數據結構之棧和隊列

一、棧

1.1 棧的定義

  • 棧(Stack):只允許在一端進行插入或刪除操作的線性表。首先棧是一種線性表,但是限定這種線性表只能在某一端進行插入和刪除操作。
  • 棧頂(Top):線性表允許進行插入和刪除的那一端。
  • 棧底(Bottom):固定的,不允許進行插入和刪除的另一端。
  • 空棧:不含任何元素的空表。

1.2 棧的基本操作

  • InitStack(&S):初始化一個空棧 S。
  • StackEmpty(S):判斷一個棧是否為空,若棧 S 為空返回 true,否則返回 false。
  • Push(&S,x):進棧,若棧 S 未滿,將 x 加入使之成為新棧頂。
  • Pop(&S,&x):出棧,若棧 S 非空,彈出棧頂元素,并用 x 返回。
  • GetTop(S,&x):讀棧頂元素,若棧頂元素為空,用 x 返回棧頂元素。
  • ClearStack(&S):銷毀棧,并釋放棧 S 占用的存儲空間。

1.3 棧的順序存儲結構

  • 順序棧的實現:棧的順序存儲稱為順序棧,是利用一組地址連續的存儲單元存放自棧底到棧頂的數據元素,同時附設一個指針(Top)指示當前棧頂的位置。
  • 順序棧的基本運算:初始化、判棧空、進棧、出棧、讀棧頂元素。
  • 共享棧:利用棧底位置相對不變的特性,可以讓兩個順序棧共享一個一維數據空間,將兩個棧的棧底分別設置在共享空間的兩端,兩個棧頂向共享空間的中間延申。

1.4 棧的鏈式存儲結構

  • 采用鏈式存儲的棧成為鏈棧,鏈棧的優點是便于多個棧共享存儲空間和提高其效率,且不存在棧滿上溢的情況。
  • 通常采用單鏈表實現,并規定所有操作都是在單鏈表的表頭進行。
  • 采用鏈式存儲,便于結點的插入與刪除。

二、隊列

2.1 隊列的定義

  • 隊列簡稱隊,是一種操作受限的線性表,只允許在表的一端進行插入,而在表的另一端進行刪除。向隊列中插入元素稱為入隊或進隊;刪除元素稱為出隊或離隊。
  • 操作特性為先進先出,又被稱為先進先出的線性表。
  • 隊頭(Front):允許刪除的一端,又稱為隊首。
  • 隊尾(Rear):允許插入的一端。
  • 空隊列:不含任何元素的空表。

2.2 隊列的順序存儲結構

  • 隊列的順序存儲:隊列的順序實現是指分配一塊連續的存儲單元存放隊列中的元素,并附設兩個指針 front 和 rear 分別指示隊頭元素和隊尾元素的位置。
  • 初始條件(對空條件):Q.front == Q.rear == 0;
  • 進隊操作:隊不滿時,先送值到隊尾元素,再送隊尾指針加 1。
  • 出隊操作:隊不空時,先取隊頭元素值,再將隊頭指針加 1。
  • 隊空條件為:Q.rear == MaxSize ;

2.3 循環隊列

  • 把存儲隊列元素的表從邏輯上看成一個環,當隊首指針 Q.front = MaxSize-1后,再前進一個位置就自動到 0,可利用除法取余(%)來實現。
  • 初始時:Q.front = Q.rear = 0;
  • 隊首指針進 1:Q.front = (Q.front+1)%MaxSize;
  • 隊尾指針進 1:Q.rear = (Q.rear+1)%MaxSize;
  • 隊列長度:(Q.rear+MaxSize-Q.front)%MaxSize;
  • 出隊入隊時:指針都按順時針方向進 1;
  • 犧牲一個單元來區分隊空和隊滿,入隊少用一個隊列單元,即隊頭指針在隊尾指針的下一個位置作為隊滿的標志。
  • 隊滿條件為:(Q.rear+1)%MaxSize==Q.front。
  • 隊空條件為:Q.front == Q.rear。
  • 隊中元素的個數:(Q.rear-Q.front+MaxSize)%MaxSize
  • 類型中增設表示元素個數的數據成員
  • 隊空:Q.size = 0;
  • 隊滿:Q.size = MaxSize;
  • 上述兩種情況均有Q.front = Q.rear
  • 類型中增設 tag 數據成員,以區分是隊空還是隊滿。
  • tag 等于零的情況下,若因刪除導致Q.front == Q.rear 則為隊空;
  • tag 等于 1 的情況下,若因插入導致Q.front == Q.rear 則為隊滿;
  • 循環隊列的操作:初始化,判隊空,入隊,出隊

2.4 隊列的鏈式存儲結構

  • 隊列的鏈式表示稱為鏈隊列,是一個同時帶有隊頭指針和隊尾指針的單鏈表。
  • 頭指針指向頭節點,尾指針指向尾結點,即鏈表的最后一個結點。
  • 當 Q.front == NULL,且 Q.rear == NULL 時,鏈表隊列為空。
  • 出隊時,首先判斷隊是否為空,若不空,則取出隊頭元素,將其從鏈表中摘除,并讓 Q.front 指向下一個結點(若該節點為最后一個節點,則置 Q.front 和 Q.rear 都為NULL)。
  • 入隊時,建立一個新節點,將新節點插入到鏈表的尾部,并改讓 Q.rear 指向這個新插入的結點(若原隊列為空隊,則令 Q.front 也指向該節點。
  • 用單鏈表表示的鏈式隊列特別適合于數據元素變動比較大的情形,而且不存在隊列滿且產生溢出的問題。
  • 假如程序中要使用多個隊列,于多個棧的情況一樣,最好使用鏈式隊列,這樣就不會出現存儲分配不合理和溢出的問題。
  • 鏈式隊列的基本操作:初始化,判隊空,入隊,出隊

2.5 雙端隊列

  • 雙端隊列是指允許兩端都可以進行入隊和出隊操作大的隊列,其元素的邏輯結構仍是線性,將隊列的兩端分別稱為前端和后端,兩邊都可以入隊和出隊。
  • 在雙端隊列進隊時:前端進的元素排列在隊列中后端進的元素后面,后端進的元素排列在隊列中前端元素進的元素的后面。
  • 在雙端隊列出隊時:無論前端還是后端出隊,先出的元素排在后出的元素前面。
  • 輸出受限的雙端隊列:允許在一端進行插入和刪除,但在另一端只允許插入的雙端隊列稱為輸出受限的雙端隊列。
  • 輸入受限的雙端隊列:允許在一端進行插入和刪除,但在另一端只允許刪除的雙端隊列稱為輸入受限的雙端隊列。而如果限定雙端隊列從某個端點插入的元素只能從該端點刪除,則該雙端隊列就蛻變為兩個棧底相鄰接的棧了。

三、棧和隊列的應用

  • 棧在括號匹配中的應用
  • 棧在表達式求值中的應用
  • 棧在遞歸中的應用
  • 隊列在層次遍歷中的應用
  • 隊列在計算機系統中的應用

四、特殊矩陣的壓縮存儲

  • 矩陣在計算機圖形學、工程計算中占有舉足輕重的地位,在數據結構中考慮的是如何用最小的內存空間來存儲同樣的一組數據。

4.1 數組

  • 數組和線性表的關系:數組是線性表的推廣。一維數組可以看作是一個線性表,二維數組可以看作元素是線性表的線性表,以此類推。
  • 數組一旦被定義,它的維數和維界就不再改變,因此,除了結構的初始化和銷毀之外,數組就只會有存取元素和修改元素的操作。

4.2 數組的存儲結構

  • 一個數組的所有元素在內存中占用一端連續的存儲空間。
  • 對于多維數組,有兩種映射方法 :按行優先和按列優先。
  • 按行優先:先行后列,先存儲行號較小的元素,行號相等先存儲列號較小的元素。
  • 按列優先:先列后行。

4.3 矩陣的壓縮存儲

  • 壓縮存儲:指為多個值相同的元素只分配一個存儲空間,對零元素不分配存儲空間,其目的是為了節省存儲空間。
  • 特殊存儲:指具有許多相同矩陣元素或零元素,并且這些相同矩陣元素或零元素的分布有一定規律性的矩陣。常見的特殊矩陣有對稱矩陣、上(下)三角矩陣、對角矩陣等。
  • 特殊矩陣的壓縮存儲方法:找出特殊矩陣中值相同的矩陣元素的分布規律,把那些呈現規律性分布的值相同的多個矩陣元素壓縮存儲到一個存儲空間中。

4.4 稀疏矩陣

  • 矩陣元素個數 s 相對于矩陣中非零元素個數 t 來說非常多,即 s >> t 為的矩陣稱為稀疏矩陣。
  • 將非零元素及其相應的行和列構成一個三元組(行標,列標,值),然后按照某種規律存儲這些三元組。
  • 稀疏矩陣壓縮存儲后便失去了隨機存取的特性。
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,836評論 6 540
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,275評論 3 428
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,904評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,633評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,368評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,736評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,740評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,919評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,481評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,235評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,427評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,968評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,656評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,055評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,348評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,160評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,380評論 2 379

推薦閱讀更多精彩內容