算法 中的 棧和隊列

什麼是棧?

棧是一種線性的數據結構,只能遵循“先入後出”的原則。“先入後出”也就是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;
    }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章