数组模拟实现队列(Java语言描述)
2020-01-13 18:20
274 查看
队列的实例:电影院购票、排队打饭、去麦当劳买吃的,银行排队叫号等等这些场合都需要排队,生活中的各种排队现象就展示了队列的实例
队列的介绍:队列是个有序列表
队列的实现方式:
- 数组
- 链表
注意:若使用数组来模拟实现队列,就是顺序存储,若使用链表来实现队列,就是链式存储。
队列的
重要原则(或者叫做
特点):
先入先出(FIFO),也就是说谁先进入到队列谁就会先被调出去。即:先存入队列的数据要先取出,反之,后存入队列的数据要后取出
使用数组来模拟实现队列
画图分析:
rear : 表示队尾,就是队列的尾部
front:表示对首,就是队列的头部
当把数据添加到队列中时,front的值和位置不会产生变化,而rear队尾的位置和值会随着数据的增加变化而变化。由此说明,往队列中添加数据是从队列尾部rear加,变化的是rear,而不是front
当把数据从队列中取出时,rear的值和位置不会产生变化,而front队首的位置和值会随着数据的减少变化而变化。由此说明:往队列中取出数据是从队列头部front取出的,变化的是front,而不是rear
若使用数组的结构来存储队列的数据,则数组队列的声明如下图所示:
设计队列时,首先定义个
ArrayQureue类,类中有4个属性(也叫做成员变量)分别是数组
queueArr[]、
maxsize、
front和
rear
maxsize:代表队列的最大容量,就是该队列数组最大能存储多少个数据
rear:用来记录队列的队尾
front:用来记录队列的队首
queueArr[]:数组模拟实现队列,队列存的数据就是存放在数组中的。
队列的常用操作:(
重要)
- 创建队列
- 把数据添加到队列中(入队列)
- 把数据从队列从取出来(出队列)
入队列思路分析:
将入队列这个功能写成一个对应的成员方法
addQueue(int n)
实现入队列需要两个步骤:
-
首先必须判断队列是否已满
rear == maxsize - 1
,当队尾rear = maxsize - 1
时,则说明队列已经满了,就不能实现入队列了,反之,当队尾rear != maxsize - 1 || real < maxsize - 1
时,则说明队列未满,就可实现入队列操作注意:判断队列是否满,取决于
maxsize
和rear
之间的关系画图分析:
-
将队尾
rear ++
,rear的位置往后移动以下,数据从队尾加入。
出队列思路分析:
将出队列这个功能写成一个对应的成员方法
getQueue(int num)
实现出队列需要两个步骤:
-
首先判断队列是否为空
rear == front
,若队首和队尾相等了rear = front
,则证明队列是空的,就不能实现出队列的操作,若强制实现出队列,会抛出数组下标越界异常,反之,则证明队列不为空,则可实现出队列的操作。注意:判断队列是否满,取决于
front
和rear
之间的关系画图分析:
-
将队首
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]; } }
问题及优化:
- 目前数组使用一次就不能使用了,没有达到复用的效果
- 将这个数组使用算法改进成环形队列的数组,核心是采用取模% 来实现的
总结:
- front 始终指向的是队列头的前一个位置,不是直接指向队列中的第一个数据,始终不包含队列中的第一个数据,front所指向的存储空间中始终没有数据。当rear 和front相等 时,front不包含队列中的任何数据,因为队列是空的,也无法实现出队列操作。
-
rear指向队列的尾部的具体的数据,包含队列的最后一个数据。当rear 和front相等 时,rear不包含队列中的任何数据,因为队列是空的。
画图分析:
- 判断队列是否满 ,取决于
rear
和maxsize
的关系rear == maxsize - 1
- 判断队列是否为空 ,取决于
rear
和front
的关系rear == front
- 点赞
- 收藏
- 分享
- 文章举报
相关文章推荐
- 数据结构(java语言描述)-- 队列的循环数组实现
- (数据结构与算法分析 四)------数组循环队列的实现( Java语言描述)
- (数据结构与算法分析 三)------栈的实现(包括链栈和数组实现栈 Java语言描述)
- (数据结构与算法分析 七)------优先队列中的二叉堆的实现( Java语言描述)
- 队列的数组实现_JAVA描述《数据结构与算法分析》
- 数据结构与算法分析(Java 语言描述)(36)—— 使用两个队列实现一个栈
- 算法(第四版)笔记<一>-------动态队列的数组实现(Java语言)
- 使用数组实现栈和循环队列(JAVA语言)
- 数据结构与算法分析(Java 语言描述)(35)—— 使用两个栈实现一个队列
- Java语言使用数组实现队列
- 数据结构(java语言描述)-- 表的简单数组实现
- 队列的链式存储方式的实现(Java语言描述)
- 队列的链式存储方式的实现(Java语言描述)
- 【每天算法1】:用java 语言实现,输入一个数,就相应地输出的几维数组
- (数据结构与算法分析 八)------插入排序,希尔排序,归并排序的实现( Java语言描述)
- 数据结构(java语言描述)递归实现——汉诺塔问题
- 链表一元多项式计算器的实现(Java语言描述)
- 数组实现循环队列(Java)
- 算法_队列的Java通用数组实现
- JAVA 用数组实现环型队列