目录
1.背景
根据上一篇文章,我们得出了一个结论,在使用普通队列时,无法重复使用队列。想要队列重复使用,那么需要使用到环形队列。
2.环形队列分析
将front定义为队列头,指向队列中第一个元素的位置,并初始化为0.
将rear定义为队列尾,指向元素中最后一个元素的后一个位置,并初始化为0.
这种方式实现的话会空出一个位置。
判断是否为空:只需要判断front的位置是否与rear的位置相等即可。
判断是否为满:判断(rear+1)%maxSize是否与front相等。rear+1是因为数组中始终有一个空位,取模是为了让数组能够重复使用。
添加元素:在rear指针的位置添加,并将rear向后移动一位,当然也需要取模,否则可能出现索引越界。
取出元素:在front的位置添加,并将front向后移动一位,也需要取模。
队列中元素的个数:(rear指针位置-front指针位置+maxSize)再对maxSize取模。
3.代码演示
package com.study.queue;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.Scanner;
public class ArrayCircleQueueDemo {
public static void main(String[] args) {
//用户输入
Scanner scanner = new Scanner(System.in);
int maxSize = 0;
Boolean isFirstQueue = true;
int haveQueue = 0;
ArrayCircleQueue queue = null;
Boolean loop = true;
Scanner sc1 = null;
Scanner sc2 = null;
while (loop){
while (haveQueue==0){
if (isFirstQueue) {System.out.println("请定义队列的长度:");}
try {
sc1 = new Scanner(System.in);
maxSize = sc1.nextInt();
haveQueue = 1;
} catch (Exception e) {
System.out.println("请输入正确的数字:");
}
isFirstQueue = false;
}
while (haveQueue == 1) {
queue = new ArrayCircleQueue(maxSize);
haveQueue = 2;
}
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):查看头数据");
char c = scanner.next().charAt(0);
switch (c){
case 's':
queue.showQueue();
break;
case 'e':
loop = false;
System.out.println("程序结束喽,下班~");
break;
case 'a':
Boolean flga = true;
int num = 0;
while (flga){
try {
System.out.println("请输入要插入的数据:");
sc2 = new Scanner(System.in);
num = sc2.nextInt();
queue.addQueue(num);
flga = false;
} catch (Exception e) {
if (e instanceof InputMismatchException){
System.out.print("输入数字格式有误,");
} else {
System.out.println(e.getMessage());
flga = false;
}
}
}
break;
case 'g':
try {
int queue1 = queue.getQueue();
System.out.printf("取出数据是:%d\r\n",queue1);
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 'h':
try {
int i = queue.headQueue();
System.out.printf("头数据是:%d\r\n",i);
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
default:
System.out.println("别瞎搞,好好输入,揍你奥!");
break;
}
}
}
}
class ArrayCircleQueue{
private int maxSize;
private int front;
private int rear;
private int[] arrayCircleQueue;
//创建数组
public ArrayCircleQueue(int maxSize){
this.maxSize = maxSize+1;
front = 0;
rear = 0;
arrayCircleQueue = new int[maxSize+1];
}
//判断非空
public Boolean isFull(){
return (rear+1) % maxSize == front;
}
//添加一个值
public void addQueue(int i){
if (isFull()){
throw new RuntimeException("队列满了,别加了~");
}
arrayCircleQueue[rear] = i;
rear = (rear+1)%maxSize;
}
public Boolean isEmpty(){
return front == rear;
}
//获取一个值
public int getQueue(){
if (isEmpty()){
throw new RuntimeException("队列空的,你取啥?");
}
int i = arrayCircleQueue[front];
arrayCircleQueue[front] = -1;
front = (front+1)%maxSize;
return i;
}
//查看头数据
public int headQueue(){
if (isEmpty()){
throw new RuntimeException("队列空的,哪有头?");
}
return arrayCircleQueue[front];
}
//显示队列中的所有数据
public void showQueue(){
System.out.print("队列中的数据:");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
if (isEmpty()) System.out.println("队列空,你还查?");
for(int i = front;i<front+(rear-front+maxSize)%maxSize;i++){
System.err.print(arrayCircleQueue[i%maxSize]+" ");
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
System.out.println();
}
}
以上是关于环形队列的简单小案例,如有不严谨的地方,麻烦各位大佬评论或私信支教,还请不吝赐教,谢谢!