1. 程式人生 > >資料結構與演算法(七)堆

資料結構與演算法(七)堆

優先順序佇列:按照事先約定的優先順序,可以始終高效查詢並訪問優先順序最高資料項的資料結構。

可以將堆繼承於向量的資料結構,優先順序佇列ADT的size(),insert(),getMax(),delMax()四個介面。

堆的成員:詞條也是向量的元素,有大小N確定。

應用介面:可反覆使用delMax介面實現排序演算法。

如何確保insert(),getMax(),delMax()的時間複雜度均可達到o(logn);

無論是向量還是列表均無法實現該要求,無需保證全體詞條之間的全序關係。

有限偏序集的極值必然存在,故因此藉助堆結構來實現,也就是樹結構特例。

完全二叉堆的其中一種:完全二叉樹,條件二:根節點均不大於或不小於子節點。

大頂堆:優先順序最高的詞條在堆頂為大頂堆。優先順序最低的詞條在堆頂,為小頂堆。

基於向量結構實現堆結構。完全二叉樹可用向量實現。節點之間的關係由位置RANK確定。

1.詞條插入堆中:將詞條新增到向量末尾,再對堆執行上濾操作。

2.獲取優先順序最高或最低的詞條:返回向量的首單元。

3.刪除優先順序最高的的詞條:堆頂詞條=末尾詞條,捨棄末尾詞條,對新堆頂實現下濾。

堆的上濾操作:判斷該元素是否有父親;
            若有,看是否逆序,若逆序,則調換
            直到不再逆序或達到堆頂。

由於完全二叉堆中元素均按照層次遍歷儲存在向量結構中,所以各節點在物理上連續,可利用RANK判斷父子關係。
只要i>0,則有父節點=i/2-1;
i*2+1滿足[0,N)之間,則合法,且左孩子為i*2+1

i*2+2滿足[0,N)之間,則合法,且右孩子為i*2+2

堆的下濾操作: 判斷i是否有兩個孩子,有,則與最大的那個交換,
             若只有一個左孩子,則與左孩子看最大的那個交換。
       
建堆:給定一組詞條,如何高效地將他們建成堆。
方法一:insert()插入法,O(NLOGN);
方法二:將所有詞條插入向量中,自頂向下對每個詞條進行上濾操作。O(LOGN).深度
方法三:Floyd演算法,自下而上,依次對每一個內部節點進行下濾。O(N)。高度
方法三優於方法二的原因是:在完全二叉樹樹中,深度小的點,遠遠少於高度小的節點。

堆排序:反覆呼叫delmax()方法,實際執行時間往往高於O(nlogn)時間。

也就證明堆結構優於向量結構。

左式堆:除了標準的插入和刪除操作,堆結構的另一個常見操縱為合併。由列表構成。

方法一:反覆取出堆的最大詞條並插入另外一個堆中。