循環隊列
隊列:只允許在一端進行插入,另一端進行刪除的線性表
循環隊列:隊列首尾相接的順序存儲結構稱作循環隊列。
隊列順序存儲的不足:順序存儲我們一般使用數組,那麼假設一個隊列有n個元素,首先需要建立一個大於n的數組,把所有元素存入數組的前n個地址,每次刪除完之後前面也就是隊頭所在的位置會空出來,無法繼續利用,就需要所有元素向前移動,但這樣時間複雜度爲O(n).除此之外,如果數組長度爲n,隊頭和隊尾在n-1處,前面有n-2個空的地址,但是我們需要入隊時會提示我們數組越界,這種現象叫做“假溢出”
要解決假溢出的方法就是後面滿了就從頭開始,也就是首位相連形成一個環,就是循環隊列。
判隊空就是 front == rear
隊列大小的計算是(rear-front+MAXSIZE)%MAXSIZE,當rear>front時,隊列長度是rear-front,當rear<front時,隊列長度是,MAXSIZE-front和rear的和,就是rear-front+MAXSIZE,因此,通用的計算隊列的長度公式爲:(rear-front+MAXSIZE)%MAXSIZE。
循環隊列的代碼
簡單的入隊和出隊操作
public class CircularQueue<T> {
private static final int MAXSIZE = 5; //
private T[] element;
private int front; //隊首下標即隊首指針
private int rear; //隊尾下標即隊尾指針
public CircularQueue(){
this(MAXSIZE);
}
public CircularQueue(int size){
element = (T[])new Object[size];
front = 0;
rear = 0;
}
//判隊空
public boolean isEmpty(){
return front == rear;
}
//判隊滿
public boolean isFull(){
return rear+1 == front;
}
//隊列大小
public int size(){
return (rear-front+MAXSIZE)%MAXSIZE;
}
//入隊
public void offer(T value){
if (isFull()){
throw new ArrayIndexOutOfBoundsException();
}else{
element[rear] = value;
rear = (rear+1)%MAXSIZE; //到達最後一個以後轉到數組頭部
}
}
//出隊
public T poll(){
if (isEmpty()){
throw new NullPointerException();
}else{
T data = element[front];
element[front] = null; //防止內存泄漏
front = (front+1)%MAXSIZE;
return data;
}
}
//獲取隊首元素
public T peek(){
if (isEmpty()){
throw new NullPointerException();
}else{
return element[front];
}
}
//打印隊列元素
public void show(){
int temp = front;
while (temp != rear){
System.out.println(element[temp]);
temp++;
}
}
}