雞啄米:C++程式設計入門系列之五(運算子和表示式)
棧和佇列的定義和特點
- 棧和佇列是兩種常用、重要的線性結構,從資料結構角度上來看也是線性表。
- 棧和佇列是限定插入和刪除只能在表的“端點”進行操作的線性表。
棧:是限定僅為表尾進行插入或者刪除的線性表。因此,對棧來說,表尾端有其特殊含義,成為 棧頂(top),相應的,表頭端稱為 棧底(bottom)。不含元素的空表稱為空棧。棧是一種 後進先出的線性表;
與棧相反, 佇列(queue)是一種 先進先出(first in first out,縮寫為FIFO)的線性表,它只允許在表的一端進行插入,而在另一端刪除元素。在佇列中,允許插入的一端叫做 隊尾(rear),允許刪除的一端則稱為 隊頭(front)。
棧的表示和實現
棧的插入操作,叫做進棧,也稱壓棧、入棧。
棧的刪除操作,叫作出棧,也有的叫彈棧。
棧的順序儲存結構
我們定義一個top變數來指示棧頂元素在陣列中的位置,類似於小時候學過的油遊標卡尺,它的來回移動就意味著棧頂top可以變大變小。當棧存在一個元素是,top等於0,因此通常把空棧的判斷條件定為top等於-1.
棧的結構定義
棧的順序儲存結構——進棧操作
對於棧的插入,即進棧操作(如下圖所示):
程式碼如下:
棧的順序儲存結構——出棧操作
出棧操作pop
程式碼如下:
- 兩者沒有涉及到任何迴圈語句,因此時間複雜度均為O(1)。 /henan/
棧的鏈式儲存結構
對於鏈棧來說,是不需要頭結點的。基本不存在滿棧的情況,除非已經沒有可以使用的空間,如果真的發生那麼此時計算機作業系統已經面臨當機崩潰的情況,而不是鏈棧溢位的問題。
對於空棧來說,連結串列原定義是頭指標指向空,那麼鏈棧的空其實就是top=NULL。
鏈棧的結構程式碼如下:
棧的鏈式儲存結構——進棧操作
對於鏈棧的進棧push操作,假設元素值為e的新結點是s,top為棧頂指標。
程式碼如下:
棧的鏈式儲存結構——出棧操作
對於鏈棧的pop操作,也是很簡單的三句操作。假設用變數 p 用來儲存要刪除的棧頂結點,將棧頂指標下移一位,最後釋放p即可。
程式碼表示如下:
jiyuan/
如果棧的使用過程中元素變化不可預料,有時很小,有時非常大,那麼最好是用鏈棧,反之,如果它的變化在可控範圍內,建議使用順序棧會更好一些 /question/
佇列的表示和實現
佇列是隻允許在一端進行插入操作,而在另一端進行刪除操作的線性表。
與棧不同的是,佇列元素的出列是在隊頭,即下標為0的位置,也就是意味著,佇列中的所有元素都得想前移動,以確保佇列的隊頭也就是小標為0的位置不為空,此時時間複雜度為O(n),如下圖所示:
(手繪多包涵)
為了避免當只有一個元素時,隊頭和隊尾重合使處理編的麻煩,所有引入兩個指標,
front 指標指向隊頭元素,
rear 指標指向隊尾元素的下一個位置,這樣當front等於rear時,此佇列不是還剩一個元素,而是空佇列。
假如這個佇列的總個數不超過5個,但是目前如果接著入隊的話,因陣列末尾元素已經佔用,再向後加,就會產生陣列越界的錯誤,可實際上,我們的佇列在下標為0和1的地方還是空閒的。我們把這種現象稱為“假溢位”。
因此引入迴圈佇列概念。
另外,當rear > front 時,此時佇列的長度為 rear - front 。但當 rear < front 時,佇列長度分為兩段,一段是QueueSize - front,另一段是0 + rear ,加在一起,佇列長度為 rear - front + QueueSize。因此通用的計算佇列長度公式為:
(rear - front + QueueSize)% QueueSize
佇列的鏈式儲存結構及實現
佇列的鏈式儲存結構,其實就是線性表的單連結串列,只不過它只能尾進頭出而以,我們通常簡稱它為鏈佇列。
為了方便操作,我們將頭指標指向鏈佇列的頭結點,而隊尾指標指向終端節點。
空佇列,front 和 rear 都指向頭結點。
鏈佇列的結構為: anhui/
佇列的鏈式儲存結構——入隊操作
入隊操作時,其實就是在連結串列尾部插入結點。
其程式碼如下:
zhumadian/
佇列的鏈式儲存結構——出隊操作
出隊操作時,就是頭結點的後繼結點出隊,將頭結點的後繼改為它後面的結點,若連結串列除頭結點外只剩下一個元素時,則需要將 rear 指向頭結點。
程式碼如下: heilongjiang/
總的來說,在確定佇列長度最大值的情況下,建議用迴圈佇列,如果你無法預估佇列的長度時,則用鏈佇列。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/30239065/viewspace-2732922/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- C++入門程式設計----C++運算子(8)C++程式設計
- Sql Server系列:運算子和表示式SQLServer
- C++中的運算子和表示式C++
- C語言程式設計入門之--第五章C語言基本運算和表示式-part2C語言程式設計
- 《JavaScript 闖關記》之表示式和運算子JavaScript
- JavaScript表示式和運算子(轉)JavaScript
- Python運算子和表示式Python
- Java入門系列-06-運算子Java
- 運算子與表示式
- MySQL入門系列:查詢簡介(三)之表示式和函式MySql函式
- 瞎說系列之正規表示式入門
- Java雜記2—運算子和表示式Java
- [java基礎] 之 表示式和運算子的優先順序Java
- C程式設計語言讀書筆記:型別運算子與表示式C程式程式設計筆記型別
- 前端RxJs響應式程式設計之運算子實踐前端JS程式設計
- JavaScript權威指南(4)——表示式和運算子JavaScript
- java運算子和表示式詳細介紹Java
- CMake 生成器表示式---條件表示式和邏輯運算子
- [.net 物件導向程式設計基礎] (6) 基礎中的基礎——運算子和表示式物件程式設計
- Python入門(五):Python常用操作運算子Python
- java中運算子與表示式Java
- 入門篇-其之七-Java運算子Java
- Python的運算物件、運算子、表示式和語句Python物件
- 【重溫基礎】5.表示式和運算子
- C++與正規表示式入門C++
- SQLite中的運算子表示式SQLite
- PHP入門之型別與運算子(一)PHP型別
- 開心檔之C++ 過載運算子和過載函式C++函式
- Lambda表示式入門--函數語言程式設計與函式式介面函數程式設計函式
- shell程式設計(二)運算子程式設計
- Linux系統程式設計(16)——正規表示式入門Linux程式設計
- 好程式設計師Python教程系列分享之Python語言元素之運算子程式設計師Python
- SQL Server查詢計劃系列之——邏輯運算子與物理運算子SQLServer
- C++ 過載運算子和過載函式C++函式
- C語言表示式和運算子大學霸IT達人C語言
- [.net 物件導向程式設計進階] (6) Lamda表示式(二) 表示式樹快速入門物件程式設計
- 前端入門9-JavaScript語法之運算子前端JavaScript
- swift 自定義正規表示式運算子 =~Swift