二叉堆是一種特殊的堆,二叉堆是完全二元樹(二叉樹)或者是近似完全二元樹(二叉樹)。二叉堆有兩種:最大堆和最小堆。二叉堆用陣列儲存,從下標1開始,並且因為二叉堆為完全二叉樹,所以除根節點外的任意節點i 的父節點為 i / 2,除終端節點外任意節點i 的 左孩子為 i / 2,右孩子為 i / 2 + 1(存在右孩子時)。接下來的一系列二叉堆操作皆以最大堆為基礎例如插入新結點,資料為20,首先插入到陣列末尾(這個末尾也代表序號 ⑤ 的左孩子)如下:最大堆:父結點的鍵值總是 >=(大於或等於) 任何乙個子節點的鍵值。
最小堆:父結點的鍵值總是 <=(小於或等於) 任何乙個子節點的鍵值。
我們可以清楚的看到新結點的加入,其資料比他的,使得原最大堆已經不符合最大堆的條件
所以插入之後:
1.首先將他的資料與其父節點資料進行比較
2.假如大於的話,則進行資料交換,直到滿足最大二叉堆條件如下圖:
**實現:
void
insert_
(int tail)
// tail 指插入到尾部的新結點
son = father;
father = son /2;
//完全二叉樹,父節點為孩子結點下標除以2
}return
;}
因為二叉堆為完全二叉樹,而完全二叉樹的深度為 log n,所以插入操作時間複雜度為o(log n)。
訪問操作一般與刪除操作是一起的
訪問則直接訪問下標刪除就直接將該結點後面所有結點的前移將其覆蓋
**實現:
int
visit_delet
(int adress,
int end)
// adress 表示訪問結點的下標,end 表示末尾結點下標
訪問的時間複雜度為o(1),刪除的時間複雜度為o(n)。
無論是插入還是訪問刪除,基礎都是要最初的二叉堆是符合條件的,所有堆排序在操作前是非常有必要的。
① 建立最大堆
② 將堆頂元素與末尾元素交換位置(將堆頂取出),將剩下的元素重新建立最大堆
③ 重複 ②,直到排序完成
**實現:
void
swap
(int
*x,int
*y)void
percdown
(int a,
int num,
int root)
a[father]
= x;
}void
head_sort
(int a,
int n)
}
時間複雜度 o(n logn)
適用於如:
① 10000個數中 找最小的 100個數
② 醫院排隊,急症優先順序高,儘管可能比普通病人來得晚,但它依然能最快的到就診。
總結 二叉堆 7 20
堆一般有兩個重要的操作,put 往堆中加入乙個元素 和get 從堆中取出並刪除乙個元素 put一般用來建堆和維護堆,get則是得到最小值。堆在noip競賽中應用廣泛,常用與快速查詢最大 最小值 優化各種演算法 如 最短路演算法 dp演算法 是一種效率高,應用廣泛的資料結構。顯然,堆只能以乙個關鍵字作...
二叉堆 Heap 的學習
定義 在一棵完全二叉樹中,滿足a parent i a i 小根堆為例 性質1 parent i i 2 left i i 2 right i i 2 1 性質2 高度為 h的堆,元素對多 個,最少 個 性質3 含 n個元素的堆的高度為floor lg n 性質 4 當用陣列表示儲存了 n個元素的堆...
(二叉)堆操作
堆操作 實驗目的 一 建堆 將陣列a 1.n 變成乙個最大堆。二 堆排序 將乙個堆中的元素按遞減排序輸出。三 用插入方法建堆 堆大小從1到n每次插入乙個元素到堆中,直到n個元素入堆。實驗原理 二叉 堆是乙個陣列,它可以被看成乙個近似的完全二叉樹。樹上的每乙個結點對應陣列中的乙個元素。除了最底層外,該...