思想:该循环队列是用数组实现的,而在数组的长度上是采用浪费一个数组空间(就是说让this.elem[this.elem[].length-1]位置空着)。因为如果不浪费空间的话(让this.elem[this.elem[].length-1]位置不空着),需在出入队时,判断队列是否为空和是否为满,需要多增加判断。
比如:在我的设计中,当this.rear == this.front,即可判断循环队列为空,而而如果不浪费这个空间的话this.rear == this.front有可能是循环队列为空,也有可能是为满,需要进一步进行判断,既要考虑数组下标,还要考虑别的情况,去证明数组为空或满,所以,这里是牺牲空间来减少代码复杂;
public class MyCircularQueue {
public int[] elem;
public int front;
public int rear;
// 初始化循环队列空间大小
public MyCircularQueue(int k){
// 因为设定是K长度的数组,而我们浪费了一个空间,所以需要加1
this.elem = new int[k+1];
}
// 入队
public boolean enQueue(int val){
if(isFull()){
return false;
}
// 这里多余了,因为队头默认是0,而绑定(或改变)队头位置是在出队方法中做标记
/*if(isEmpty()){
this.elem[this.front] = val;
this.rear = (this.rear+1)%this.elem.length;
return true;
}*/
this.elem[this.rear] = val;
this.rear = (this.rear+1)%this.elem.length;
return true;
}
// 判断是否为满
public boolean isFull(){
if((this.rear+1)%this.elem.length == this.front) return true;
return false;
}
// 判断是否为空
public boolean isEmpty(){
if(this.front == this.rear) return true;
return false;
}
// 出队
public boolean deQueue(){
if(isEmpty()) return false;
this.front = (this.front + 1)%this.elem.length;
return true;
}
// 队头元素
public int front(){
if(isEmpty()) return -1;
return this.elem[this.front];
}
// 队尾元素
public int rear(){
if(isEmpty())return -1;
int index = this.rear == 0? this.elem.length-1 : this.rear -1;
return this.elem[index];
}
}
在整个过程中,需要判断特殊情况,当rear 或front的下一个或前一个下表是否为0下标的情况。
this.front = (this.front + 1)%this.elem.length;
这种处理可以越过上面说的情况。