循环队列可以有效的利用资源。如果使用普通数组实现队列时,如果不进行移动,随着数据的不断读写弹出插入,会出现假满队列的情况。例如不断向队列中添加元素,然后在弹出元素。这是弹出元素所空闲出来的空间并没有得到重复利用,这是就会出现数组尾部已经满了,但是头部还有空闲空间没有得到利用。
入队时尾指针向前追赶头指针,出队时头指针向前追赶尾指针
/**
* Created by JKerving on 2016/4/20.
* use an array to implement a circle queue
*/
public class CircleQueue {
private int[] q = null;
//首索引
private int head = 0;
//尾索引
private int tail = 0;
private int len = 0;
public CircleQueue(int len){
this.len = len;
q = new int[len];
}
//insert into circle queue
private int insert(int x){
//判断循环队列是否已满
if (isFull()){
System.out.println("circle queue is Full");
return -1;
}else {
q[tail] = x;
//逻辑上实现首尾相连,循环队列
tail = (tail + 1) % len;
//返回最近插入的元素
return x;
}
}
//pop from circle queue
private int pop(){
if (isNull()){
System.out.println("circle queue is Null");
return -1;
}else {
int n = q[head];
//头结点不断追赶尾结点
head = (head + 1)%len;
//返回最近弹出的元素
return n;
}
}
//get head for circle queue
private int head(){
return q[head];
}
//get tail for circle queue
private int tail(){
return q[(tail + len - 1)%len];
}
//check isFull
private boolean isFull(){
//有个规定,要给队尾留出一个空间来
//如果不留出一个空间,举个例子,创建大小为12的数组,索引值为0~11.不断向其中添加元素
//当添加到tail=11之后,就把tail置为(tail+1)%12 = 0
//那么这时候无论判断队列isFull还是isNull都将返回true
//所以为了防止这种情况的发生,当向tail=10添加元素之后,
//把tail置为(tail+1)%12,然后在判断(tail+1)%12==head,这时判断isFull还是isNull就不会发生相冲突的情况
if ((tail + 1) % len == head){
return true;
}else {
return false;
}
}
//check is null
private boolean isNull(){
//首尾相等的话则为空
if (head == tail){
return true;
}else {
return false;
}
}
}