參考文章
堆常用來實現優先佇列。
用陣列儲存資料,而不是鍊錶。
在佇列中,作業系統排程程式反覆提取佇列中第乙個作業並執行,因為實際情況中某些時間較短的任務將等待很長時間才能結束,或者某些不短小,但具有重要性的作業,同樣應當具有優先權。堆即為解決此類問題設計的一種資料結構。
堆的實現通過構造二叉堆(binary heap),實為二叉樹的一種(完全二叉樹)
完全二叉樹:若設二叉樹的深度為h,除第 h 層外,其它各層 (1~h-1) 的結點數都達到最大個數,第 h 層所有的結點都連續集中在最左邊,這就是完全二叉樹
最大(最小)堆是一棵每乙個節點的鍵值都不小於(大於)其孩子(如果存在)的鍵值的樹。大頂堆是一棵完全二叉樹,同時也是一棵最大樹。小頂堆是一棵完全完全二叉樹,同時也是一棵最小樹。
將根節點最大的堆叫做最大堆或大根堆,根節點最小的堆叫做最小堆或小根堆。
如下圖所示,圖一為最大堆,圖二為最小堆:
以小根堆為例:
堆可以用陣列儲存資料,如有陣列:
則可以構成堆:
可以發現:任意節點的左右孩子對應陣列下標的一半為其父節點對應的下標(5/24/22)。
注意:這裡下標從1開始計算而不是從0開始,因為從0開始的話根節點的下標和子節點下標間就沒有了倍數關係(5/2 != 6/2)
從當前結點開始,和它的父親節點比較,若是比父親節點來的小,就交換,然後將當前詢問的節點下標更新為原父親節點下標;否則退出。
經過上浮操作之後,下標3處節點的元素值如下圖所示
讓當前結點的左右兒子(如果有的話)作比較,哪個比較小就和它交換,並更新詢問節點的下標為被交換的兒子節點下標,否則退出。
每次插入的時候呢,都往最後乙個插入,然後使它上浮。
讓根節點元素和尾節點進行交換,然後讓現在的根元素下沉就可以了。
根節點陣列下標必定是 0,返回堆陣列中下標為 0 的元素即可。
見演算法 - 排序系列文章第六篇,同時用**實現上述對堆的操作。
資料結構 完全二叉樹
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!完全二叉樹是一種效率很高的資料結構,堆就是一種完全二叉樹,所以效率極高。像十分常用的排序演算法 dijkstra演算法 prim演算法等都要用堆才能優化 幾乎每次都要考到的二叉排序樹的效率也要借助平衡性來提高,而平衡性基於完全二叉樹。完全二叉樹定義...
資料結構 無序的完全二叉樹轉為堆
無序的完全二叉樹轉為堆。這裡以轉為最大堆為例 首先要知道sift down下沉操作,才能理解怎麼轉為最大堆,最大堆的下沉 下沉某個節點,即把該節點與它的兩個子節點,共3個節點中值最大的結點選出來作為這三個節點中的父節點。並且,下沉後,被下沉的結點及其子節點還要進行下沉操作,直到不需要下沉為止,這是為...
資料結構 二叉堆
二叉堆一般用來實現優先佇列 優先佇列是一種至少允許以下兩種操作的資料結構 insert 以及 deletemin 同查詢樹一樣,二叉堆具有結構性與堆序性,對二叉堆的基本操作可能會破壞這些性質,所以二叉堆的操作要直到其基本性質滿足才能結束。一 結構性 二叉堆在結構上為完全二叉樹,其具有完全二叉樹的結構...