27-咸鱼学Java-Java中的循环队列
原创
©著作权归作者所有:来自51CTO博客作者MC43700000046E4的原创作品,请联系作者获取转载授权,否则将追究法律责任
队列介绍
队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。—–百度
而循环队列的结构如图所示
其本质类似于将一个数组弯折,首尾相连,这样的话。可是这样的话因为需要判断数组是否满,是否空,所以需要手动浪费掉一个空间,最标志位这样的话,在队尾和对头直接一直有一块数据空余,就方便于进行判断,又因为数组的下标变化是连续的不会从7突变为0,所以如图的循环顺序队中,每一个指引移动的时候都必须+1然后模8,即rear=(rear+1)%8;即rear = (rear+1)%allsize,allsize为队列的总共数据长度。这样就可以把整个数组变成一个环,然后就可以循环起来。
代码
/**
* 循环队列
* 特点 先进先出 浪费一个格子标志位
* @author 14831
*
*/
public class LoopQueue {
/**
* 数据
*/
int[] elem;
/**
* 队头
*/
int front;
/**
* 队尾
*/
int rear;
/**
* 当前队列中有效数据个数
*/
int usedSize = 0;
/**
* 队列的最大长度
*/
int allSize = 0;
public LoopQueue(int size) {
this.elem = new int[size+1];
this.front = 0;
this.rear = 0;
this.allSize = size+1;
}
public LoopQueue() {
this(10);
}
/**
* 入队
* @param val
*/
public void push(int val)
{
//如果队满直接返回
if(isFull())
{
return;
}
//插入数据
elem[rear] = val;
//更新队尾
rear = (rear+1)%allSize;
usedSize++;
}
/**
* 出队
* @return
*/
public int pop()
{ //如果队为空 返回-1
if(isEmpty())
{
return -1;
}
//获得当前数据
int x = elem[front];
//清空数据
elem[front] = -1;
//更新队头
front = (front+1)%allSize;
usedSize--;
return x;
}
/**
* 获得队头位置的元素
* @return
*/
public int getTop()
{
return isEmpty()?-1:elem[front];
}
/**
* 打印队列
*/
public void show ()
{
for (int i = 0; i < usedSize; i++) {
System.out.print(elem[(front+i)%allSize]+" ");
}
}
/**
* 判断队列是否为空
* @return
*/
public boolean isEmpty() {
return front==rear;
}
/**
* 判断队是否满
* @return
*/
public boolean isFull()
{
return (rear+1)%allSize == front;
}
}
测试
public static void main(String[] args) {
LoopQueue a = new LoopQueue();
int loopLength = 11;
for (int i = 0; i < loopLength; i++) {
a.push(i);
}
a.show();
System.out.println();
for (int i = 0; i < loopLength; i++) {
System.out.print(a.pop()+" ");
}
}
结果
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9 -1