什麼是棧?
棧是一種線性的數據結構,只能遵循“先入後出”的原則。“先入後出”也就是First In Last Out,簡稱FILO,也就是最先進入棧的原則需要最後出棧的元素,這個最早進入棧的元素存放位置叫棧底,最後進入的元素存放的位置叫做棧頂。
棧的基本操作
入棧
現有這樣一個棧,需要將一個新元素入棧。
將新的元素入棧。
新的元素取代原來的棧頂,成爲新的棧頂。
出棧
現在有一個這樣的棧,我要讓他執行一次出棧操作。
將需要出棧的元素移除,前面的元素就變成了棧頂。
什麼是隊列?
隊列不同於棧的先入後出,隊列中的元素只能按照先入先出(First In First Out,FIFO)的方式,隊列的出口端叫隊頭,隊列的入口端叫隊尾。
爲了入隊操作方便,把隊尾位置規定爲最後入隊元素的下一個位置,就像這樣:
隊列的基本操作
入隊
現有這樣一個隊列需要入隊。
將需要插入的元素插入隊尾。
最後再重新調整隊尾指針的位置,需要指向最後一個元素的下一個元素。
出隊
根據先入先出的原則,出隊需要讓隊頭的元素先出。
出隊完成後,隊頭便成了隊頭的下一個元素。
循環隊列
如果隊列不停的入隊和出隊操作,這個數組固定的空間就會越用越小,像這樣:
隊列的容量將會越來越小,這時候再插入一個元素。
從上面來看,插入了一個新元素,隊尾指針又重新指向了該數組的第一個元素。
現在再插入一個元素:
這時候,新元素又插入了隊尾指針的位置,隊尾指針又指向了下一個元素,這樣一來,整個數組就循環起來了,這就叫做循環隊列。
循環隊列的判滿公式
( 隊尾下標 + 1 ) % 數組長度 = 隊頭下標
當 隊尾下標+1 剛好等於 數組長度 時,結果應是0。
例如:隊尾下標=15,數組長度=30,隊頭下標=16。
則:(15 + 1) % 30 = 16
因爲,之前說過,隊尾的下標是最後一個元素的下一個,實際在隊尾的元素其實下標爲14,但,隊尾指針指向的位置永遠空出一位,所以循環隊列元素已滿。
循環隊列的入隊
/**
* 入隊
* @param element 入隊的元素
* @param front 隊頭下標
* @param rear 隊尾下標
*/
public void enQueue(int element) throws Exception{
if((rear+1)%array.length == front) { //判滿公式
throw new Exception("隊列已滿!!");
}
array[rear] = element; //把新值插入隊尾下標,也就是隊列的下一個元素
rear = (rear+1)%array.length; //重新定義隊尾下標(+1就是下標向後移一位)
}
循環隊列的出隊
/**
* 出隊
* @return
*/
public int deQueue() throws Exception{
if(rear == front) {
throw new Exception("隊列已空!!");
}
int deQueueElement = array[front]; //隊頭下標的元素就是要出隊的元素
front = (front+1)%array.length; //重新定義隊頭下標(隊頭下標向後移一位)
return deQueueElement;
}