大話數據結構—棧與隊列

一、棧的定義

棧是(stack)是限定盡在表尾進行插入和刪除操作的線性表。
棧又稱為后進先出(Last In First Out)的線性表,簡稱LIFO結構。

二、進棧出棧變化形式

注意: 并不是最新進棧的元素只能最后處棧。如,我們現在有三個元素一次進棧,次序會有以下5種:
1. 1、2、2進,再3、2、1出,出棧次序為321;
2. 1進,1出,2進,2出,3進,3出,出棧次序為123;
3. 1進,2進,2出,1出,3進,3出,出棧次序為213;
4. 1進,1出,2進,3進,3出,2出,出棧次序為132;
5. 1進,2進,2出,3進,3出,1出,出棧次序為231。

三、棧的順序存儲結構及實現

(一)棧的順序存儲結構
棧是線性表的特例,棧的順序存儲結構也是線性表存儲結構的簡化。線性表是用數組實現的,用下標為0的那一端作為棧底使棧變化最小。
我們定義一個top變量來指示棧頂元素在數組中的位置。若存儲棧的 長度為StackSize,則棧頂位置top必須小于StackSize。當棧存在一個元素時,top=0.因此,通常把空棧的判定條件定位top=-1.

進棧:push;出棧:pop。(就像子彈的壓和彈)。
沒有涉及循環,兩者的時間復雜度均為1.

兩棧共享空間:兩個類型相同的棧,則可以共享存儲空間。讓一個棧的棧底為數組的始端,即下標為0處,另一個棧為數組的末端,即下標為數組長度n-1處。這樣,兩個棧如果增加元素,就是兩端點向中間延伸。兩個棧見面之時,也就是兩個棧指針相差1,即top1+1==top2為棧滿。

(二)棧的鏈式存儲結構
棧的鏈式存儲結構,簡稱為鏈棧。
鏈棧的棧頂和單鏈表的頭指針重合,不需要頭結點。
對于鏈棧來說,不存在棧滿的情況,除非內存已經沒有可以使用的空間。如果真的發生,就是操作系統已經面臨死機崩潰的情況,而不是這個鏈棧是否真的溢出。
對于空棧來說,鏈表原定義是頭指針指向空,那么鏈棧的空其實就是top=NULL的時候。

對比順序棧和鏈棧,它們在時間復雜度上是一樣的,均為O(1)。對于空間性能,順序棧要事先確定一個固定的長度,可能會存在內存空間浪費的問題,但它的優勢是存取時定位很方便,而鏈棧則要求每個元素都有指針域,這同時也增加了一定的內存開銷,但對于棧的長度無限制。所以它們的區別和線性表中討論的一樣,如果棧的使用過程中元素變化不可預料,有時候很小,有時候很大,那么最好是用鏈棧,如果它們的變化在可控范圍內,建議使用順序棧會更好一些。

四、棧的作用

有的人可能會問,用數組或鏈表直接實現功能不就行了嗎?為什么還要引入棧這個數據結構呢?
其實這和我們明明有兩只腳可以走路,干嘛還要乘汽車、火車、飛機一樣。理論上,陸地上的任何地方,你都是可以用雙腳走到的,可那需要多長時間和精力呢?我們更關注的是到達而不是如何去的問題。
棧的引入簡化了程序設計的問題,劃分了不同關注層次,使得思考范圍縮小,更加聚焦于我們要解決的核心問題。反之,像數組等,因為要分散精力去考慮數組下標的增減問題,反而掩蓋了問題的本質。
所以,現在的許多高級語言,比如Java,C#等都有對棧結構的封裝,你可以不關注它的實現細節,就可以直接使用Stack的push和pop方法,非常方便。

五、棧的應用

(一) 遞歸
斐波那契數列
(二)四則運算表達式求值
后綴(逆波蘭)表示法:從左到右遍歷表達式的每個數字和符號,遇到是數字就進棧,遇到是符號,就將處于棧頂兩個數字出棧,進行運算,運算結果進棧,一直到最終獲得結果。
中綴表示法:從左到右遍歷中綴表達式的每個數字和符號,若是數字就輸出,即成為中綴表達式的一部分;若是符號,則判斷其與棧頂符號的優先級,是右括號有優先級不高于棧頂符號(乘除有限加減)則棧頂元素依次出棧并輸出,并將當前符號進棧,直到最終輸出后綴表達式為止。

隊列

一、隊列定義

隊列(queue)是只允許在一端進行插入操作,而在另一端進行刪除操作的線性表。
隊列是一種先進先出(First In First Out)的線性表,簡稱FIFO。允許插入的一端稱為隊尾,允許刪除的一端稱為隊頭。

二、隊列的抽象數據類型

同樣是線性表,隊列也有類似線性表的各種操作,不同的就是插入數據只能在隊尾進行,刪除數據只能在隊頭進行。

三、循環隊列

隊列也有線性表的兩種存儲方式:順序存儲和鏈式存儲。
入隊操作是在隊尾增加一個元素,時間復雜度為O(1)。但是,出隊時,如果規定隊列中的元素都放在前n個位置,則第一個元素出隊后,后面的元素都要向前移動,以保證對頭不為空,也就是下標為0的位置不為空,此時時間復雜度為O(n)。
但是,我們可以想,如果沒有隊列的元素都必須放在前n個位置的規定,出隊的性能就會大大增加。于是,我們因為兩個指針,front指向對頭元素,rear指針指向隊尾的下一個元素,當front==rear,隊列為空。這樣,當出隊時,只需移動front指針即可。但是,這樣也會有一個問題,一個隊列不可能只有出隊,當繼續進行入隊操作致使隊尾已經填滿,rear指針指向隊列外時,繼續入隊就可能產生數組越界的錯誤。但是,由于前面已經進行過出隊操作,所以這個隊列前面會有空位置,這種現象稱為“假溢出”。這里舉個例子,現實生活中,當你上了一輛公交車,發現前面有兩個空位置,但后排的座位都已經滿了。這是,你不會告訴自己,后面沒座了,立馬下車,等待下一輛。我們都不會這么笨,而都會坐在前面的位置。
這時,就引入了循環隊列的概念。循環隊列就是首尾相接的順序存儲結構。
那么,問題又來了,前面提到當front==rear時,隊列為空,但在循環隊列中,這個結論顯然不成立。所以,如何判斷隊列是空還是滿呢?以下給出兩種方法:
1. 設置一個標志變量flag,當front==rear,且flag=0時隊列為空,當front==rear,且flag=1時隊列滿。
2. 當隊列空時,條件就是front=rear,當隊列滿時,我們修改條件,保留一個元素空間。也就是說,隊列滿時,數組中還有一個空閑單元。
我們來重點討論第二種方法,由于rear可能比front大,也可能比front小,所以它們只相差一個位置時就是滿的情況,但也可能是相差整整一圈。所以,若隊列的最大尺寸是QueueSize,那么隊滿的條件是(rear+1)%QueueSize==front(取模%的目的就是為了整合front和rear大小為一個問題)
通用的計算隊列長度的公式為(rear-front+QueueSize)%QueueSize
循環隊列的相關條件和公式:
1. 隊空條件:rear==front
2. 隊滿條件:(rear+1) %QueueSIze==front,其中QueueSize為循環隊列的最大長度
3. 計算隊列長度:(rear-front+QueueSize)%QueueSize
4. 入隊:(rear+1)%QueueSize
5. 出隊:(front+1)%QueueSize
到這里,大家可以發現,但是順序存儲,若不是循環隊列,算法的時間性能是不高的,但循環隊列有面臨著數組可能會溢出的問題,所以我們還需要研究一樣不需要擔心隊列長度的鏈式存儲結構。

四、隊列的鏈式存儲結構及實現

隊列的鏈式存儲結構,其實就是線性表的單鏈表,只不過它只能尾盡頭出而已,稱為鏈隊列。將隊頭指針指向鏈隊列的頭結點,隊尾指針指向終端結點。
空隊列是,front和rear都指向頭結點。
入隊操作:就是在鏈尾插入結點。
出隊操作,就是頭結點的后繼結點出隊,將頭結點的后繼改為它后面的結點,若鏈表除頭結點外只剩一個元素時,則需將rear指向頭結點。

對比循環隊列和鏈隊列,時間上,其實它們基本操作都是常數時間,即都為O(1)的。不過循環隊列是事先申請好空間,使用期間不釋放,而對于鏈隊列,每次申請和釋放結點也會存在一些時間開銷,如果入隊出隊頻繁,則兩者還是存在細微差異。對于空間上來說,循環隊列不存在這個問題,盡管它需要一個指針域,會產生一些空間上的開銷,但也可以接受。所以在空間上,鏈隊列更加靈活。
總的來說,在可以確定隊列長度最大值的情況下,建議使用循環隊列,如果無法預估隊列長度,則用鏈隊列。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/386041.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/386041.shtml
英文地址,請注明出處:http://en.pswp.cn/news/386041.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【工作感悟】java編程規范pdf下載

前言 要相信,你現在所有的努力和付出都會在將來的某一天回報給你! 首先阿里巴巴作為國內互聯網行業的領頭羊,培養了一代又一代的IT技術人才,很多想進阿里這些互聯網大廠的程序員看中的不僅僅是高薪豐厚的福利待遇,同樣…

大話數據結構——串

串(string)是由零個或多個字符組成的有限序列,又名字符串。 字符串有很多函數,replace、ToUpper、ToLower(轉小寫)、Trim(去掉兩邊空格)、IndexOf(從左到右查找子串的位…

【工作感悟】全網最經典26道Spring面試題總結

開頭 學習如逆水行舟,尤其是IT行業有著日新月異的節奏。 而且現在這個浮躁而又拜金的社會,我相信很多人做技術并非出于熱愛,只是被互聯網的高薪吸引,畢竟技術崗位非常枯燥,不僅要面對奇奇怪怪的需求,還要…

大話數據結構——樹

一、樹的定義 樹(Tree)是n(n>0)個結點的有限集。 n0又稱為空樹。在任意一課非空的樹中:(1)有且僅有一個特定的稱為跟(Root)的結點;(2&#xf…

大話數據結構——圖

圖(Graph)是由定點的又窮非空集合和頂點之間邊的集合組成,通常表示為:G(V,E),其中,G表示一個圖,V是圖G中頂點的集合,E是圖G中邊的集合。 一、各種圖的定義 …

【工作感悟】達內java大數據課程

前言 其實前幾篇文章已經寫了好多有關于Spring源碼的文章,事實上,很多同學雖然一直在跟著閱讀、學習這些Spring的源碼教程,但是一直都很迷茫,這些Spring的源碼學習,似乎只是為了面試吹逼用,我大概問過一些…

大話數據結構——查找

查找(Searching)是根據給定的某個值,在查找表中確定一個其關鍵字等于給定值的數據元素(或記錄)。 一、順序表查找 順序查找又叫線性查找,是最基本的查找技術,它的查找過程是:從表中…

【工作經驗分享】java圖片轉文字

前言 又到一年金九銀十之際。 Java作為目前用戶最多,使用范圍最廣的軟件開發技術之一。 Java的技術體系主要由支撐Java程序運行的虛擬機,提供各開發領域接口支持的Java,Java編程語言及許多第三方Jvav框架構成。 其中,以Java的虛擬器為今天的著…

數據挖掘工程師的面試問題與答題思路

一個Java程序可以認為是一系列對象的集合,而這些對象通過調用彼此的方法來協同工作。下面簡要介紹下類、對象、方法和實例變量的概念。 對象:對象是類的一個實例,有狀態和行為。例如,一條狗是一個對象,它的狀態有&…

【干貨】java課程實戰培訓

開頭 消息隊列 RocketMQ 是阿里巴巴集團基于高可用分布式集群技術,自主研發的云正式商用的專業消息中間件,既可為分布式應用系統提供異步解耦和削峰填谷的能力,同時也具備互聯網應用所需的海量消息堆積、高吞吐、可靠重試等特性,…

Java的幾個特點

Java語言是簡單的: Java語言的語法與C語言和C語言很接近,使得大多數程序員很容易學習和使用。另一方面,Java丟棄了C中很少使用的、很難理解的、令人迷惑的那些特性,如操作符重載、多繼承、自動的強制類型轉換。特別地&#xff0c…

【干貨】mysql建表語句注釋

前言 難道程序員的職業生命線是青春飯?答案是的。 35歲考慮轉行,然后35歲又成了一個新人,而外國可以做到60歲,啥也不說了,可能是覺得中年大叔油膩,不及小鮮肉便宜,唉,可嘆市場更新…

軟件測試知識整理

在一個測試計劃匯總能包含哪些內容? 答:在一個測試計劃中可以包含需要測試的產品的特點和主要功能模塊,列出需要測試的功能點,并標明側重點;測試的策略和記錄(測試工具的確認,測試用例等文檔模…

【干貨】mysql查詢重復數據sql

前言 本系列的目的是明明白白、徹徹底底的搞定日期/時間處理的幾乎所有case。上篇文章鋪設所有涉及到的概念解釋,例如GMT、UTC、夏令時、時間戳等等,若你還沒看過,不僅強烈建議而是強制建議你前往用花5分鐘看一下,因為日期時間處…

【微信小程序】java最簡單觀察者模式

開頭 對于一個Java程序員而言,能否熟練掌握并發編程是判斷他優秀與否的重要標準之一。因為并發編程是Java語言中最為晦澀的知識點,它涉及操作系統、內存、CPU、編程語言等多方面的基礎能力,更為考驗一個程序員的內功。 那到底應該怎么學習并…

操作系統知識點整理

作業 用戶在一次解題或一個事務處理過程中要求計算機系統所做工作的集合。它包括用戶程序、所需要的數據及控制命令等。作業是由一系列有序的步驟組成的。 進程 一個程序在一個數據集合上的一次運行過程。所以一個程序在不同數據集合上運行,乃至一個程序在同樣數…

【性能優化實戰】java驗證碼識別訓練

前言 今天剛好有空,跟大家聊聊如何學好算法進大廠。 前兩天一個讀者和我說,他堅持刷算法題2個月,薪資翻番去了他夢寐以求的大廠,期間面字節跳動還遇到了原題…其實據我所知目前國內的大廠和一些獨角獸,已經越來越效仿…

計算機網絡知識整理

OSI七層 物理層、數據鏈路層、網絡層、傳輸層、會話層、表示層、應用層。 物理層涉及信道上傳輸的比特流。 數據鏈路層的主要任務是加強物理層傳輸原始比特流的功能,是指對應的網路層顯現為一條無錯線路。發送包把數據封裝在數據幀,按順序傳送出去并處…

吸水間最低動水位標高_體驗長安逸動EV460:再也不用為電動車續駛里程焦慮了...

文| 車突突車圖騰出品,未經許可,謝絕轉載● ● ●人們都在期待碧水藍天,而且越來越多的消費者也開始踐行環保理念,在買車時關注起了純電動汽車。不過遺憾的是,純電動汽車目前還沒能成為主流。一方面,是因為…

java開發工具包jdk包括哪些

害怕干不過SpringBoot?莫慌,我送你套神級pdf文檔 隨著 Spring Boot 使用越來越廣泛,Spring Boot 已經成為 Java 程序員面試的知識點,很多同學對 Spring Boot 理解不是那么深刻,經常就會被幾個連環追問就給干趴下了&am…