如果你學過數據結構,就一定會遇到“堆”,"棧","堆棧",這些對于小白來說有些頭大,下面就來科普一下何謂堆棧?
按照WIKI的定義:
堆棧(英語:stack),是計算機科學中一種特殊的串列形式的抽象數據類型,其特殊之處在于隻能允許在鍊表或數組的一端(稱為堆棧頂端指針,英語:top)進行加入數據(英語:push)和輸出數據(英語:pop)的運算。另外堆棧也可以用一維數組或鍊表的形式來完成。堆棧的另外一個相對的操作方式稱為隊列。需要記住的是,堆:順序随意,棧:後進先出(Last-In/First-Out)。
這裡的pop和push到都是什麼意思?其實這是堆棧數據結構使用兩種基本操作:推入(壓棧,push)和彈出(彈棧,pop):
推入:将數據放入堆棧的頂端(數組形式或串列形式),堆棧頂端top指針加一。
彈出:将頂端數據數據輸出(回傳),堆棧頂端數據減一。
如要了解堆棧,應将之拆開分析。
堆的概念:
堆(英語:Heap)是計算機科學中的一種特别的樹狀數據結構。通常是一個可以被看做一棵樹的數組對象。若是滿足以下特性,即可稱為堆:“給定堆中任意節點 P 和 C,若 P 是 C 的父節點,那麼 P 的值會小于等于(或大于等于) C 的值”。若父節點的值恒小于等于子節點的值,此堆稱為最小堆(英語:min heap);反之,若父節點的值恒大于等于子節點的值,此堆稱為最大堆(英語:max heap)。在堆中最頂端的那一個節點,稱作根節點(英語:root node),根節點本身沒有父節點(英語:parent node)。
棧的概念
棧(stack)又名堆棧,它是一種運算受限的線性表。其限制是僅允許在表的一端進行插入和删除運算。這一端被稱為棧頂,相對地,把另一端稱為棧底。棧就是一個桶,後放進去的先拿出來,它下面本來有的東西要等它出來之後才能出來(先進後出)
棧(Stack)是操作系統在建立某個進程時或者線程(在支持多線程的操作系統中是線程)為這個線程建立的存儲區域,該區域具有FIFO的特性,在編譯的時候可以指定需要的Stack的大小。
堆棧
其實堆棧本身就是棧,隻是換了個抽象的名字。其特性是: 最後一個放入堆棧中的物體總是被最先拿出來,這個特性通常稱為後進先出(LIFO)隊列。堆棧中定義了一些操作。 兩個最重要就是上述提到的PUSH和POP。PUSH操作在堆棧的頂部加入一個元素,POP操作相反,在堆棧頂部移去一個元素,并将堆棧的大小減一。
工作原理
對于工作方式你可能還是一頭霧水,以自助餐托盤為例解釋一下,你就會更加明了:
作為堆棧如何工作的一個例子,可以把它看成一個彈簧加載托盤分發器,這種類型經常在自助餐廳中發現。每個托盤上都刻有數字。托盤依次從頂部裝入,每個托盤都放置在已經裝入的托盤上,彈簧進行壓縮,以便在必要時為更多托盤留出空間。例如,在圖中,托盤編号為42、23、2、9,先裝載42個托盤,後裝載9個托盤。
最後一個托盤是9号。因此,“第一個出來”的盤子也是9号。當顧客從托盤堆的頂部取出托盤時,第一個托盤是9号,第二個托盤是2号。然後更多的托盤被添加。這些托盤将不得不在我們裝載第一個托盤之前從堆棧上下來。在托盤堆的任意順序的push和pop出之後,托盤42仍然在底部。隻有在42号托盤從堆棧頂部彈出後,堆棧才會再次清空。
而堆棧通常被放置在機器的最上面的地址區域。它們通常從最高的内存位置增長到較低的内存位置,允許在程序内存末端和堆棧“頂部”之間的内存使用中獲得最大的靈活性。在我們的讨論中,堆棧在内存中是“向上”增長還是“向下”增長基本上是不相關的。堆棧的“top”元素是最後被推入并将首先被彈出的元素。堆棧的“底部”元素在删除時将使堆棧為空。
二者區别
堆是在程序運行時,而不是在程序編譯時,申請某個大小的内存空間。即動态分配内存,對其訪問和對一般内存的訪問沒有區别。它由程序員分配和回收。
棧就是一個桶,後放進去的先拿出來,它下面本來有的東西要等它出來之後才能出來。(後進先出)由系統自動分配和回收。
堆棧緩存方式
棧使用的是一級緩存, 他們通常都是被調用時處于存儲空間中,調用完畢立即釋放。
堆則是存放在二級緩存中,生命周期由虛拟機的垃圾回收算法來決定(并不是一旦成為孤兒對象就能被回收)。所以調用這些對象的速度要相對來得低一些。棧的優勢是,存取速度比堆要快,僅次于直接位于CPU中的寄存器。
棧:在Windows下,棧是向低地址擴展的數據結構,是一塊連續的内存的區域。意思是棧頂的地址和棧的最大容量是系統預先規定好的,在 WINDOWS下,棧的大小是2M(也有的說是1M,總之是一個編譯時就确定的常數),如果申請的空間超過棧的剩餘空間時,将提示overflow。因此,能從棧獲得的空間較小。
堆:堆是向高地址擴展的數據結構,是不連續的内存區域。這是由于系統是用鍊表來存儲的空閑内存地址的,自然是不連續的,而鍊表的遍曆方向是由低地址向高地址。堆的大小受限于計算機系統中有效的虛拟内存。由此可見,堆獲得的空間比較靈活,也比較大。
作為“堆”的數據空間,必須是靈活的,因為成千上萬的程序員在寫什麼程序是未知的。但可知道的一點,就是他們是跑在确定的某個OS裡面的。因此,也不過就是給系統管理的數據空間起了個名字,叫棧;給程序員使用的空間,起了個名,叫堆。
,