一、循环队列概念介绍:
这里的循环队列是用数组来实现的,但是当用数组来实现队列时,会出现一种叫做“假溢出”的现象。
当用普通数组进行模拟时,随着数据不断入队rear指针的不断增加很快的rear指针便会达到数组的边缘。而不断的出队会让front指针不断增加。因为队列中的数据容量是通过rear-front指针来计算的,所以说当rear和front指针都快要到达数组的边缘时其实队列中的数据量是很少的,而rear和front指针不能“后退”,只能不断“前移”。这就导致了数组中的空间被大量浪费。怎么解决这种问题?要是rear和front指针能“后退”就可以了。人们就用了取余操作的特性来使得数组可以循环利用。实际存储中数据还是存放在数据的某处,只是人们用取余操作使得数组看起来变的可以循环使用。
二、队列相关操作
1.数据入队:首先判断队列是否为满,满则无法入队。如果没满才可以入队。入队操作:rear=(rear+1)%MAXSIZE,front不动。(MAXSIZE为队列最大容量)
2.数据出队:首先判断队列是否为空,没有元素就无法出队。如果不为空则可以出队。front=(front+1)%MAXSIZE,rear不动。
3.判断队列为空:rear==front;
4.判断队列满:(rear+1)%MAXSIZE==front, 如上图所示,实际上队列的最大容量必须舍弃一个才可以将队列满和队列空的情况区分开来。队列满的时候只是rear指向MAXSIZE-1的位置。
5.计算队列容量:(rear-front+MAXSIZE)%MAXSIZE
6.遍历队列:将front指针(在数组中是下标,但是以后用链表实现时就是指针,统一称呼)用临时的指针标记(头指针不能动),用临时指针遍历,一直遍历到rear即可
public static void main(String []args)
{
//test
CircleQueue queue=new CircleQueue(4);
Scanner sc = new Scanner(System.in);
System.out.print("1.入队 2.出队\n");
System.out.print("3.取头元素 4.计算容量+遍历\n");
System.out.print("5.退出\n");
while(true)
{
System.out.print("输入选项\n");
int option=sc.nextInt();
switch(option) {
case 1:
System.out.print("数值入队列\n");
int x=sc.nextInt();
queue.EnQueue(x);
break;
case 2:
queue.DeQueue();
break;
case 3:
queue.gethead();
break;
case 4:
System.out.print("队列元素为"+queue.Capility()+"\n");
System.out.print("可以遍历队列:\n");
queue.traver();
break;
}
System.out.print("1.入队 2.出队\n");
System.out.print("3.取头元素 4.计算容量+遍历\n");
System.out.print("5.退出\n");
if(option==5)
{
break;
}
}
}
class CircleQueue{
public int front;
public int rear;
public int []array;
public int MaxSize;
//初始化
public CircleQueue(int MaxSize)
{
front=rear=0;
array=new int[MaxSize+1];
this.MaxSize=MaxSize+1;
}
//判断满
public boolean IsFull()
{
if((rear+1)%MaxSize==front)
return true;
else
return false;
}
//判断空
public boolean IsEmpty()
{
if(rear==front)
return true;
else
return false;
}
//判断容量
public int Capility()
{
return ((rear-front+MaxSize)%MaxSize);
}
//入队
public void EnQueue(int value)
{
if(IsFull())
System.out.print("队列满,无法入队!\n");
else
{
array[rear]=value;
rear=(rear+1)%MaxSize;
System.out.print("已经入队\n");
}
}
//出队
public void DeQueue()
{
if(IsEmpty())
System.out.print("队列空,无法出元素\n");
else
{
front=(front+1)%MaxSize;
System.out.print("已出队\n");
}
}
//求头元素
public void gethead()
{
if(IsEmpty())
{
System.out.print("队列空,没有元素\n");
}
else
{
System.out.print("头元素为"+array[front]+"\n");
}
}
//遍历队列
public void traver()
{
int i=front;
while(i!=rear)
{
System.out.printf("%5d",array[i]);
i=(i+1)%MaxSize;
}
System.out.println();
}
}
图片来自百度,视频教程B站java数据结构