堆是一種比較特殊的資料結構,它用陣列實現的二叉樹,並且總是滿足以下性質:
堆分為兩種:根結點最大的堆叫作最大堆或大根堆;根結點最小的堆叫作最小堆或小根堆。
堆屬性非常有用,其使得堆常常被當做優先佇列使用,因為可以快速地訪問到「最重要」的元素。
堆並不能取代二叉搜尋樹,它們之間有相似之處也有一些不同。兩者的主要區別如下:屬性堆
二叉搜尋樹
結點的順序
在最小堆中父結點必須比子結點小,在最大堆中父結點必須比子結點大,變化是從上到下
左子結點比父結點小,父結點比右子結點小,變化是從左到右
記憶體占用
使用陣列作為底層儲存結構,占用記憶體空間較小
使用鍊錶作為底層儲存結構,占用記憶體空間較大
平衡不需要整棵樹有序
必須是平衡的,總體上是有序的
搜尋搜尋很慢
搜尋很快
實現乙個堆,首先是涉及到如何儲存乙個堆。
根據堆總是一棵完全二叉樹的性質,以及完全二叉樹比較適合用陣列來儲存的概念,可以知道用陣列儲存堆是比較好的選擇。
從上圖可以看到,陣列中下標為 i 的結點的左子結點,就是下標為 2i 的結點,右子結點就是下標為 2i + 1 的結點,父結點就是下標為 i/2 的結點。
往堆中插入或者刪除乙個元素後,重要的是需要繼續滿足堆的兩個特性,而這個重新滿足堆特性的過程稱為堆化。
堆化實際上有兩種:從下往上、從上往下。
插入元素時涉及的是從下往上的堆化方法。
往堆中插入乙個元素其實就是往底層陣列的末尾新增元素,下面是示例圖:
從下往上堆化的過程比較簡單,實際上就是將插入的元素與父結點進行比較,出現不符合特性的情況就互換兩個結點,一直重複這個過程,直至父子結點之間滿足堆的特性。
從堆的特性可以看出,堆頂元素儲存的就是堆中資料的最大值或最小值。
當刪除堆頂元素的時候,為保持堆的特性,則會涉及到從上往下的堆化方法。
從上往下堆化不是直接從堆頂元素開始與子結點進行互換,而是先將陣列中的最後乙個元素移到被刪除結點位置(為了滿足完全二叉樹的特性),然後利用同樣的父子結點比對方法。
通常,對於大根堆會比較較大的子結點,對於小根堆會比較較小的子結點,出現不符合特性的情況就互換兩個結點,一直重複這個過程,直至父子結點之間滿足堆的特性。
這種方法堆化之後的結果,肯定滿足完全二叉樹的特性。
乙個包含 n 個節點的完全二叉樹,樹的高度不會超過 \(\log_2n\)。
堆化的過程是順著節點所在路徑比較交換的,所以堆化的時間複雜度跟樹的高度成正比,也就是 \(o(\log n)\)。
插入資料和刪除堆頂元素的主要邏輯就是堆化,所以往堆中插入乙個元素和刪除堆頂元素的時間複雜度都是 \(o(\log n)\)。
資料結構 堆
最大堆 最小堆 堆的定義是 n個元素的序列,當且僅當滿足如下關係時被成為堆 1 ki k2i 且 ki k2i 1 或 2 ki k2i 且 ki k2i 1 i 1,2,n 2 當滿足 1 時,為最小堆,當滿足 2 時,為最大堆。若將此序列對應的一維陣列堪稱是乙個完全二叉樹,則2i和2i 1個節點...
資料結構 堆
資料結構 堆的操作和實現 當應用優先順序佇列或者進行堆排序時,一般利用堆來實現。堆是乙個完全 除最底層 外都是滿的 二叉樹,並滿足如下條件 1 根結點若有子樹,則子樹一定也是堆。2 根結點一定大於 或小於 子結點。因為要求堆必須是完全二叉樹,所以可以用線性的資料結構,比如陣列,來實現堆。利用陣列實現...
資料結構 堆
堆常用來實現優先佇列,在這種佇列中,待刪除的元素為優先順序最高 最低 的那個。在任何時候,任意優先元素都是可以插入到佇列中去的,是電腦科學中一類特殊的資料結構的統稱 最大 最小 堆是一棵每乙個節點的鍵值都不小於 大於 其孩子 如果存在 的鍵值的樹。大頂堆是一棵完全二叉樹,同時也是一棵最大樹。小頂堆是...