目录
队列:先进先出,可以使用数组或链表来实现
1.数组模拟队列
1)首先现编写一个类(会使用到的参数变量)
class ArrayQueue {
private int maxSize; //表示数组的最大容量
private int front; //队列头(指针)
private int rear; //队列尾
private int[] arr; //该数组用于存放数据,模拟队列
//创建队列构造器
public ArrayQueue(int arrMaxSize) {
maxSize = arrMaxSize;
arr = new int[maxSize];
front = -1; //指向队列头部的前一个位置
rear = -1; //指向队列尾部的具体数据
}
2)判断队列是否为满的时候可以看队列尾是否等于队列最后一个元素的索引值(既队列长度-1)
public boolean isFull() {
return rear == maxSize - 1;
}
3)判断队列是否为空既可以使用队列头的位置和队列尾的位置是否相同来判断,若两位置相同,则队列为空,其中无元素
public boolean isEmpty() {
return rear == front;
}
4)添加数据至队列中(前提是队列不满),每添加一个数据,则队列尾后移一个位置,既自加
public void addQueue(int n) {
//1.判断队列是否为满
if (isFull()) {
System.out.println("队列已满!不能继续加入数据");
return;
}
rear++; //让尾部位置后移
arr[rear] = n;
}
5)获取队列中的数据(既使数据出队列),根据队列先进先出的特点,每出队列一个元素,则队列头向后移动一位,既队列头自加
public int getQueue() {
//判断队列是否为空
if (isEmpty()) {
//通过抛出异常来处理
throw new RuntimeException("该队列为空!");
}
front++; //让队列头部后移
return arr[front];
}
6)获取队列中全部数据,此时的队列可看作一个数组,遍历即可
public void showQueue(){
if(isEmpty()){
System.out.println("队列为空!");
}
for (int i = 0; i < arr.length; i++) {
System.out.println("arr[" + i + "]" + " = " + arr[i]);
}
}
7)获取队列头数据(前提是队列不为空)
public int headQueue(){
//判断队列为空
if(isEmpty()){
System.out.println("队列为空!");
}
return arr[front + 1];
}
2.数组模拟环形队列
思路:
a.front做一个调整:front指向队列的第一个元素,既arr[front]就是队列的第一个元素.front的初始值 = 0;
b.rear的做一个调整:rear只指向队列的最后一个元素的后一个位置(因为希望空出一个空间作为约定),rear的初始值 = 0;
c.当队列满时,条件既为 (rear + 1)% maxSize = front
d.当队列为空的条件为:rear == front
e.队列中有效的数据个数(rear + maxSize - front) % maxSize(此前认为有效数字即为rear-front,未考虑到当头不为0且队列满既队列尾为0时的情况)
对数组表示普通队列进行一定的修改,即可完成数组对环形队列的模拟
//使用数组模拟队列——编写一个ArrayQueue类
class CircleArray {
private int maxSize; //表示数组的最大容量
private int front; //队列头(指针)
private int rear; //队列尾
private int[] arr; //该数组用于存放数据,模拟队列
//创建队列构造器
public CircleArray(int arrMaxSize) {
maxSize = arrMaxSize;
arr = new int[maxSize];
front = 0; //指向队列头部的前一个位置
rear = 0; //指向队列尾部的具体数据
}
//判断队列是否满
public boolean isFull() {
return (rear + 1) % maxSize == front;
}
//判断队列是否为空
public boolean isEmpty() {
return rear == front;
}
//添加数据到队列
public void addQueue(int n) {
//1.判断队列是否为满
if (isFull()) {
System.out.println("队列已满!不能继续加入数据");
return;
}
arr[rear] = n; //该位置填充数据,队尾向后移动一次
rear = (rear + 1) % maxSize;
// 如在未加入数据之前rear = 5(此时队列最后一个元素位置为arr[4]),maxSize = 6(队列最后一个元素的位置为(arr[5])),
// 因为时环形队列,所以此时队列填充数据后,队列尾向后移动至队列头位置
}
//获取队列数据(出队列)
public int getQueue() {
//判断队列是否为空
if (isEmpty()) {
//通过抛出异常来处理
throw new RuntimeException("该队列为空!");
}
//此处需要分析 front是指向第一个元素
//1.先把front对应的值保存至临时变量
int value = arr[front];
//2.将front后移
front = (front + 1 ) % maxSize;
//3.将临时保存的变量返回
return value;
}
//显示队列所有数据
public void showQueue() {
if (isEmpty()) {
System.out.println("队列为空!");
}
//思路:从front开始遍历,遍历多少个元素?(因为时环形,所以遍历时可能会对元素进行重复遍历)
for (int i = front; i < front + (rear+maxSize-front)%maxSize; i++) {
System.out.println("arr[" + i%maxSize + "] =" + arr[i%maxSize]);
}
}
//显示队列头数据(并不是取出数据)
public int headQueue() {
//判断队列为空
if (isEmpty()) {
System.out.println("队列为空!");
}
return arr[front];
}
//查看队列中的有效数字有几个
public int size(){
return (rear+maxSize-front)%maxSize;
}
TIP:
可以使用菜单来对队列进行操作
public static void main(String[] args) {
CircleArray circleArray = new CircleArray(4); //其队列的有效数据个数为3,因为其中一个空间为预留空间
char key = ' ';
Scanner scanner = new Scanner(System.in);
boolean loop = true;
//输出菜单
while (loop){
System.out.println("s(show):显示队列");
System.out.println("e(exit):退出程序");
System.out.println("a(add):添加数据到队列");
System.out.println("g(get):取出数据");
System.out.println("h(head):查看队列头数据");
System.out.print("选择:");
key = scanner.next().charAt(0);
switch (key){
case 's': //显示队列
circleArray.showQueue();
break;
case 'a': //添加数据
System.out.print("请输入一个数据:");
int value = scanner.nextInt();
circleArray.addQueue(value);
break;
case 'g': //取出数据
//因为getQueue()中可能会抛出异常,所以保险起见使用try/catch来接收该异常
try {
int queue = circleArray.getQueue();
System.out.println("取出的数据为" + queue);
}catch (Exception e){
System.out.println(e.getMessage());;
}
break;
case 'h': //查看队列头数据
int head = circleArray.headQueue();
System.out.println("队列的头数据为" + head);
break;
case 'e': //退出
scanner.close();
break;
case 'v':
int num = circleArray.size();
System.out.println("队列中有效数字个数为:" + num);
break;
default:
break;
}
}
}
}