對于鏈表實現(xiàn)方式芦疏,隊列的入隊冕杠、出隊操作和棧是大同小異的。但對于數(shù)組實現(xiàn)方式來說酸茴,因為數(shù)組的長度固定分预,隊列的入隊和出隊操作有了一些有趣的變化。
隊列為隊尾入隊薪捍,對頭出隊笼痹,但如果不斷出隊,對頭的左邊就會失去作用酪穿,如下圖:
image.png
在數(shù)組不做擴容的前提下凳干,如何讓新元素入隊并確定新的隊尾位置呢?我們可以利用已出隊元素留下的空間被济,讓隊尾指針重新指回數(shù)組的首位救赐。
image.png
這樣一來,整個隊列的元素就“循環(huán)”起來了溉潭。在物理存儲上净响,隊尾的位置也可以在隊頭之前少欺。當再有元素入隊時喳瓣,將其放入數(shù)組的首位,隊尾指針繼續(xù)后移即可赞别。
image.png
一直到(隊尾下標+1)%數(shù)組長度 = 隊頭下標時畏陕,代表此隊列真的已經(jīng)滿了。需要注意的是仿滔,隊尾指針指向的位置永遠空出1位惠毁,所以隊列最大容量比數(shù)組長度小1犹芹。
image.png
循環(huán)隊列不但充分利用了數(shù)組的空間,還避免了數(shù)組元素整體移動的麻煩鞠绰,還真是有點意思呢腰埂!至于入隊和出隊的時間復(fù)雜度,都同樣是O(1)
具體代碼實現(xiàn):
private int[] array;
private int front;
private int rear;
public MyQueue(int capacity){
this.array = new int[capacity];
}
/**
* 入隊
* @param element 入隊的元素
*/
public void enQueue(int element) throws Exception {
if((rear+1)%array.length == front){
throw new Exception(" 隊列已滿蜈膨!");
}
array[rear] = element;
rear =(rear+1)%array.length;
}
/**
* 出隊
*/
public int deQueue() throws Exception {
if(rear == front){
throw new Exception(" 隊列已空屿笼!");
}
int deQueueElement = array[front];
front =(front+1)%array.length;
return deQueueElement;
}
/**
* 輸出隊列
*/
public void output(){
for(int i=front; i!=rear; i=(i+1)%array.length){
System.out.println(array[i]);
}
}
public static void main(String[] args) throws Exception {
MyQueue myQueue = new MyQueue(6);
myQueue.enQueue(3);
myQueue.enQueue(5);
myQueue.enQueue(6);
myQueue.enQueue(8);
myQueue.enQueue(1);
myQueue.deQueue();
myQueue.deQueue();
myQueue.deQueue();
myQueue.enQueue(2);
myQueue.enQueue(4);
myQueue.enQueue(9);
myQueue.output();
}