Stack棧類與、Queue隊列與線性表的區別和聯系


棧和隊列都屬於特殊的線性表

 

一、定義

 

 

1、線性表(linear list):

 

是數據結構的一種,一個線性表是n個具有相同特性的數據元素的有限序列。數據元素是一個抽象的符號,其具體含義在不同的情況下一般不同。

 

2、棧(Stack):

棧是限定僅能在表尾進行插入或刪除操作的線性表。對棧來說,表尾稱為棧頂、表頭稱為棧底,不含元素的空表稱為空棧。

由於棧的上述特性,最先入棧的元素最后才能被刪除,最晚入棧的元素最先被刪除,所以棧又稱為后進先出的線性表。

 

應用例子:進制轉換、括號匹配檢驗、行編輯程序、迷宮求解、表達式求值、遞歸實現

 

3、隊列(Queue):

和棧相反,隊列是一種先進先出的線性表,它只允許在表的一端進行插入,而在另一端刪除元素,允許插入的一端叫隊尾,允許刪除的一端叫隊頭。

應用例子:操作系統中的作業排隊。

雙端隊列,是限定插入和刪除操作在表的兩端進行的線性表,盡管雙端隊列看起來比棧和隊列靈活,但實際上在應用程序中遠不及棧和隊列有用。

 

 

二、實現方式和順序表示

 

 

1、線性表:

 

用一組地址連續的儲存單元依次存儲線性表的數據元素。以元素在計算機內“物理位置相鄰”來表示線性表中數據元素之間的邏輯關系。只要確定了數據元素的起始位置,就可隨機地訪問數據元素。但是這種表示方法不便於插入和刪除元素,每插入或刪除一個元素,都要移動插入或刪除位置之后的數據元素在連續儲存單元中的位置,而且除了重新分配內存,否則在程序運行過程中不能動態地增加儲存單元的數量。

 

 

2、棧:

 

和線性表相似,棧也有兩種儲存方式,順序棧和鏈式棧。

順序棧的實現在於使用了數組這個基本數據結構,數組中的元素在內存中的存儲位置是連續的,且編譯器要求我們在編譯期就要確定數組的大小,這樣對內存的使用效率並不高,一來無法避免因數組空間用光而引起的溢出問題,二在系統將內存分配給數組后,則這些內存對於其他任務就不可用;

而鏈棧使用了鏈表來實現棧,鏈表中的元素存儲在不連續的地址,由於是動態申請內存,所以我們可以以非常小的內存空間開始,另外當某個項不使用時也可將內存返還給系統。

 

3、隊列

1).順序隊列

 

建立順序隊列結構必須為其靜態分配或動態申請一片連續的存儲空間,並設置兩個指針進行管理。一個是隊頭指針front,它指向隊頭元素;另一個是隊尾指針rear,它指向下一個入隊元素的存儲位置,如圖所示

 

每次在隊尾插入一個元素是,rear增1;每次在隊頭刪除一個元素時,front增1。隨着插入和刪除操作的進行,隊列元素的個數不斷變化,隊列所占的存儲空間也在為隊列結構所分配的連續空間中移動。當front=rear時,隊列中沒有任何元素,稱為空隊列。當rear增加到指向分配的連續空間之外時,隊列無法再插入新元素,但這時往往還有大量可用空間未被占用,這些空間是已經出隊的隊列元素曾經占用過得存儲單元。

順序隊列中的溢出現象:

(1) "下溢"現象:當隊列為空時,做出隊運算產生的溢出現象。“下溢”是正常現象,常用作程序控制轉移的條件。

(2)"真上溢"現象:當隊列滿時,做進棧運算產生空間溢出的現象。“真上溢”是一種出錯狀態,應設法避免。

(3)"假上溢"現象:由於入隊和出隊操作中,頭尾指針只增加不減小,致使被刪元素的空間永遠無法重新利用。當隊列中實際的元素個數遠遠小於向量空間的規模時,也可能由於尾指針已超越向量空間的上界而不能做入隊操作。該現象稱為"假上溢"現象。

2).循環隊列

在實際使用隊列時,為了使隊列空間能重復使用,往往對隊列的使用方法稍加改進:無論插入或刪除,一旦rear指針增1或front指針增1 時超出了所分配的隊列空間,就讓它指向這片連續空間的起始位置。自己真從MaxSize-1增1變到0,可用取余運算rear%MaxSize和front%MaxSize來實現。這實際上是把隊列空間想象成一個環形空間,環形空間中的存儲單元循環使用,用這種方法管理的隊列也就稱為循環隊列。除了一些簡單應用之外,真正實用的隊列是循環隊列

在循環隊列中,當隊列為空時,有front=rear,而當所有隊列空間全占滿時,也有front=rear。為了區別這兩種情況,規定循環隊列最多只能有MaxSize-1個隊列元素,當循環隊列中只剩下一個空存儲單元時,隊列就已經滿了。因此,隊列判空的條件時front=rear,而隊列判滿的條件時front=(rear+1)%MaxSize。隊空和隊滿的情況如圖:

 

 

 

三、其他概念

 

1、棧(Stack)

 

Stack繼承Vector類,它通過五個操作對類 Vector 進行了擴展。 棧提供了通常的 push 和 pop 操作,以及取堆棧頂點的 peek 方法、測試堆棧是否為空的 empty 方法、在堆棧中查找項並確定到堆棧頂距離的 search 方法。

empty()判斷堆棧是否為空。

peek() 查看堆棧頂部的對象,但不從堆棧中移除它。

pop() 移除堆棧頂部的對象,並作為此函數的值返回該對象。

push(E item)  把項壓入堆棧頂部。

search(Object o) 返回對象在堆棧中的位置,以 1 為基數。

 

2、接口 Queue隊列:

    Queue接口與List、Set同一級別,都是繼承了Collection接口。LinkedList實現了Queue接 口。Queue接口窄化了對LinkedList的方法的訪問權限(即在方法中的參數類型如果是Queue時,就完全只能訪問Queue接口所定義的方法 了,而不能直接訪問 LinkedList的非Queue的方法),以使得只有恰當的方法才可以使用。BlockingQueue 繼承了Queue接口。

      隊列通常(但並非一定)以 FIFO(先進先出)的方式排序各個元素。不過優先級隊列和 LIFO 隊列(或堆棧)例外,前者根據提供的比較器或元素的自然順序對元素進行排序,后者按 LIFO(后進先出)的方式對元素進行排序。無論使用哪種排序方式,隊列的頭 都是調用 remove() 或 poll() 所移除的元素。在 FIFO 隊列中,所有的新元素都插入隊列的末尾。其他種類的隊列可能使用不同的元素放置規則。每個 Queue 實現必須指定其順序屬性。

Queue使用時要盡量避免Collection的add()和remove()方法,而是要使用offer()來加入元素,使用poll()來獲取並移出元素。它們的優點是通過返回值可以判斷成功與否,add()和remove()方法在失敗的時候會拋出異常。 如果要使用前端而不移出該元素,使用element()或者peek()方法。

add(E e) 將指定的元素插入此隊列(如果立即可行且不會違反容量限制),在成功時返回 true,如果當前沒有可用的

element() 獲取,但是不移除此隊列的頭。

offer(E e) 將指定的元素插入此隊列(如果立即可行且不會違反容量限制),當使用有容量限制的隊列時,此方法通常要優於 add(E),后者可能無法插入元素,而只是拋出一個異常。

peek()  獲取但不移除此隊列的頭;如果此隊列為空,則返回 null。

poll() 獲取並移除此隊列的頭,如果此隊列為空,則返回 null。

remove()   獲取並移除此隊列的頭。

 

 

 

四、總結

 

1.隊列先進先出,棧先進后出。

2.對插入和刪除操作的"限定"。 棧是限定只能在表的一端進行插入和刪除操作的線性表。隊列是限定只能在表的一端進行插入和在另一端進行刪除操作的線性表。  從"數據結構"的角度看,它們都是線性結構,即數據元素之間的關系相同。但它們是完全不同的數據類型。除了它們各自的基本操作集不同外,主要區別是對插入和刪除操作的"限定"。 棧和隊列是在程序設計中被廣泛使用的兩種線性數據結構,它們的特點在於基本操作的特殊性,棧必須按"后進先出"的規則進行操作,而隊列必須按"先進先出"的規則進行操作。和線性表相比,它們的插入和刪除操作受更多的約束和限定,故又稱為限定性的線性表結構。

3.遍歷數據速度不同。棧只能從頭部取數據 也就最先放入的需要遍歷整個棧最后才能取出來,而且在遍歷數據的時候還得為數據開辟臨時空間,保持數據在遍歷前的一致性隊列怎不同,他基於地址指針進行遍歷,而且可以從頭或尾部開始遍歷,但不能同時遍歷,無需開辟臨時空間,因為在遍歷的過程中不影像數據結構,速度要快的多

 

棧(Stack)是限定只能在表的一端進行插入和刪除操作的線性表。
隊列(Queue)是限定只能在表的一端進行插入和在另一端進行刪除操作的線性表。


從"數據結構"的角度看,它們都是線性結構,即數據元素之間的關系相同。但它們是完全不同的數據類型。除了它們各自的基本操作集不同外,主要區別是對插入和刪除操作的"限定"。

棧和隊列是在程序設計中被廣泛使用的兩種線性數據結構,它們的特點在於基本操作的特殊性,棧必須按"后進先出"的規則進行操作,而隊列必須按"先進先出"的規則進行操作。和線性表相比,它們的插入和刪除操作受更多的約束和限定,故又稱為限定性的線性表結構。

可將線性表和棧及隊列的插入和刪除操作對比如下:

 

線性表允許在表內任一位置進行插入和刪除
棧只允許在表尾一端進行插入和刪除

隊列只允許在表尾一端進行插入,在表頭一端進行刪除

--------------------- 本文來自 https://blog.csdn.net/qq_35888875/article/details/78667423


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM