您的位置:首页 > 编程语言 > Java开发

数组模拟实现队列(Java语言描述)

2020-01-13 18:20 274 查看

队列的实例:电影院购票、排队打饭、去麦当劳买吃的,银行排队叫号等等这些场合都需要排队,生活中的各种排队现象就展示了队列的实例

队列的介绍:队列是个有序列表

队列的实现方式:

  1. 数组
  2. 链表

注意:若使用数组来模拟实现队列,就是顺序存储,若使用链表来实现队列,就是链式存储。

队列的

重要原则
(或者叫做
特点
):
先入先出(FIFO)
,也就是说谁先进入到队列谁就会先被调出去。即:先存入队列的数据要先取出,反之,后存入队列的数据要后取出

使用数组来模拟实现队列

画图分析:

rear : 表示队尾,就是队列的尾部

front:表示对首,就是队列的头部

当把数据添加到队列中时,front的值和位置不会产生变化,而rear队尾的位置和值会随着数据的增加变化而变化。由此说明,往队列中添加数据是从队列尾部rear加,变化的是rear,而不是front

当把数据从队列中取出时,rear的值和位置不会产生变化,而front队首的位置和值会随着数据的减少变化而变化。由此说明:往队列中取出数据是从队列头部front取出的,变化的是front,而不是rear

若使用数组的结构来存储队列的数据,则数组队列的声明如下图所示:

设计队列时,首先定义个

ArrayQureue
类,类中有4个属性(也叫做成员变量)分别是数组
queueArr[]
maxsize
front
rear

maxsize
:代表队列的最大容量,就是该队列数组最大能存储多少个数据

rear
:用来记录队列的队尾

front
:用来记录队列的队首

queueArr[]
:数组模拟实现队列,队列存的数据就是存放在数组中的。

队列的常用操作:(

重要

  1. 创建队列
  2. 把数据添加到队列中(入队列)
  3. 把数据从队列从取出来(出队列)

入队列思路分析:

将入队列这个功能写成一个对应的成员方法

addQueue(int n)

实现入队列需要两个步骤:

  1. 首先必须判断队列是否已满

    rear == maxsize - 1
    ,当队尾
    rear = maxsize - 1
    时,则说明队列已经满了,就不能实现入队列了,反之,当队尾
    rear != maxsize - 1 || real < maxsize - 1
    时,则说明队列未满,就可实现入队列操作

    注意:判断队列是否满,取决于

    maxsize
    rear
    之间的关系

    画图分析:

  2. 将队尾

    rear ++
    ,rear的位置往后移动以下,数据从队尾加入。

出队列思路分析:

将出队列这个功能写成一个对应的成员方法

getQueue(int num)

实现出队列需要两个步骤:

  1. 首先判断队列是否为空

    rear == front
    ,若队首和队尾相等了
    rear = front
    ,则证明队列是空的,就不能实现出队列的操作,若强制实现出队列,会抛出数组下标越界异常,反之,则证明队列不为空,则可实现出队列的操作。

    注意:判断队列是否满,取决于

    front
    rear
    之间的关系

    画图分析:

  2. 将队首

    front ++
    ,front的位置往后移动以下,数据从队首取出。

    画图分析:

    front = - 1
    时, 队列中的第一个数据是
    queueArr[0]
    ,front指向的是队列头的前一个位置,
    front
    不包含这个
    queueArr[0]
    数据,当front ++ ;这时front = 0,然后实现
    return queueArr[front];
    出队列操作,则证明
    queueArr[0]
    出队列了,同理,队列中不再包含
    queueArr[0]
    这个数据,那么队列中的第一个数据所在的位置由原来的
    queueArr[0]
    变为了现在的
    queueArr[1]
    。画图分析:

代码实现:

import java.util.Scanner;
public class ArrayDemoTest{
public static void main(String[] agrs){
// 实例化 ArrayQueue对象
ArrayQueue arrayQueue = new ArrayQueue(3);
char c = ' ';
Scanner input = new Scanner(System.in);
boolean flag = true;
while(flag){
System.out.println("s (showQueue()) : 显示队列中的所有数据");
System.out.println("a(addQueue()):  实现入队列操作,把数据添加到队列中");
System.out.println("g(getQueue()):  实现出队列操作,把数据从队列中取出来");
System.out.println("h (headQueue()) : 查看队列中的第一个数据");
System.out.println("e (exit) : 退出程序");
System.out.println("请选择(s、a、g、h、e):");
c = input.next().charAt(0);
switch(c) {
case 'e':
input.close();
flag = false;
break;
case 's':
arrayQueue.showQueue();
break;
case 'a':
System.out.println("请输入一个数:");
int num = input.nextInt();
arrayQueue.addQueue(num);
break;
case 'g':
try{
System.out.println("取出的数据是" + arrayQueue.getQueue());
}catch(Exception e){
System.out.println(e.getMessage());
}
break;
case 'h':
try{
System.out.println("队列的第一个数据是" + arrayQueue.headQueue());
}catch(Exception e){
System.out.println(e.getMessage());
}
break;
default:
System.out.println("您输入的信息错误");
break;
}
}
System.out.println("程序正常退出");
}
}
// 定义个ArrayQureue类
class ArrayQueue{
// 编写属性(共4个)
// maxsize : 表示队列的最大容量
private int maxsize;
// rear : 表示队列的尾部,即:队尾
private int rear;
// front :表示 队列的头部 即:队首
private int front;
// queueArr[] : 数组模拟实现队列,队列存的数据就是存放在数组中的
private int queueArr[];

// 编写队列的构造方法,实现将局部变量maxsize的值赋值给成员变量maxsize并对rear、front和queueArr[] 进行初始化
// 带参构造
public ArrayQueue(int maxsize){
// 将局部变量maxsize的值赋值给成员变量maxsize
this.maxsize = maxsize;
// 对rear、front和queueArr[] 进行初始化
rear = -1;
front = -1;
queueArr = new int[maxsize];
}
// 无参构造
public ArrayQueue(){

}
// 编写成员方法isFull(),用来判断队列是否满
public boolean isFull(){
// true : 满  false : 未满
return rear == maxsize - 1;
}
// 编写成员方法isEmpty(),用来判断队列是否为空
public boolean isEmpty(){
// true : 空 false : 不为空
return rear == front;
}
// 编写无返回值带参的成员方法,实现入队列addQueue(int num),类似于setXxx(形参列表)方法
public void addQueue(int num){
if(isFull()){
// 抛异常做处理,给提示文字
System.out.println("队列已满,不能实现入队列操作");
return;
}
queueArr[++rear] = num;
}
// 编写有返回值无参的成员方法,实现出队列getQueue(),类似于getXxx()方法
public int getQueue(){
if(isEmpty()){
throw new RuntimeException("空队列,不能实现出队列操作");
}
return queueArr[++front];
}
// 编写成员方法,使用增强for循环 | 普通for循环遍历队列中的所有数据.
public void showQueue(){
if(isEmpty()){
System.out.println("空队列,没有数据可以遍历");
return;
}
/*for(int temp : queueArr){
System.out.print(temp + " ");
}*/
for(int i = 0;i < queueArr.length ; i++){
System.out.println("queueArr[" + i + "] = " + queueArr[i]);
}

}
// 编写成员方法,显示队列的第一个数据,注意:不是出队列
public int headQueue(){
if(isEmpty()){
throw new RuntimeException("空队列,队列中没有数据");
}
return queueArr[front + 1];
}
}

问题及优化:

  1. 目前数组使用一次就不能使用了,没有达到复用的效果
  2. 将这个数组使用算法改进成环形队列的数组,核心是采用取模% 来实现的

总结:

  1. front 始终指向的是队列头的前一个位置,不是直接指向队列中的第一个数据,始终不包含队列中的第一个数据,front所指向的存储空间中始终没有数据。当rear 和front相等 时,front不包含队列中的任何数据,因为队列是空的,也无法实现出队列操作。

  1. rear指向队列的尾部的具体的数据,包含队列的最后一个数据。当rear 和front相等 时,rear不包含队列中的任何数据,因为队列是空的。

    画图分析:

  1. 判断队列是否满 ,取决于
    rear
    maxsize
    的关系
    rear == maxsize - 1
  2. 判断队列是否为空 ,取决于
    rear
    front
    的关系
    rear == front
  • 点赞
  • 收藏
  • 分享
  • 文章举报
My-Sun-Shine 发布了27 篇原创文章 · 获赞 12 · 访问量 1506 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: