在認識二叉堆之前,先講一下完全二叉樹的定義:完全二叉樹指的是除了最後一層的葉子節點意外,其他層的節點都有2個兒子,而且最後一層的葉子從左往右排,例如下圖1是一棵完全二叉樹,圖2就不是。
二叉堆有2種:每個節點的值都小於等於其兒子節點的值的堆,稱為最小堆;每個節點的值都大於等於其兒子節點的值的堆,稱為最大堆。
以下以最小堆為例
設二叉堆的某個節點為p,它的左兒子是2p,右兒子是2p + 1,基於這個性質, 我們可以在o(1)的時間訪問到每乙個節點,而且我們可以直接把所有節點存在一維陣列裡,不需要鍊錶和其他的資料結構。
圖3是乙個最小堆
二叉堆的基本操作:
1. 插入節點,假設現在一共有n個節點,我們先把新的節點放在n+1的位置上,然後進行向上調整,調整的具體過程是這樣的,每一次都拿當前節點的值和它父親的值比較,如果當前節點的值已經大於等於它父親的值,那麼調整結束;如果當前節點的值小於它父親的值,那麼交換它們的值,然後繼續往上調整
這個過程稱為上濾
void heap_up(int p) //插入元素
heap[p] ^= heap[fa_p];
heap[fa_p] ^= heap[p];
heap[p] ^= heap[fa_p];
p = fa_p;
fa_p >>= 1;
}}
2.刪除根節點,可以把根節點的值設為無窮大,然後向下調整,每一次拿節點p和它兩個兒子裡值小的那個進行比較,如p的值大於等於它的那個兒子,就進行交換,否則調整結束,我們可以準確定位到值為無窮大的節點的位置x, 然後將當前二叉堆最後乙個節點的值賦給節點x,然後n--,就實現了刪除根節點的功能
這個過程稱為下濾
void heap_down()// 下濾
if (heap[p] <= heap[son_p])
heap[p] ^= heap[son_p];
heap[son_p] ^= heap[p];
heap[p] ^= heap[son_p];
p = son_p;
son_p <<= 1;
}
}
有n個節點的二叉堆,它的層數是logn,所以插入和刪除操作最壞的時間複雜度是o(logn) 關於二叉樹有感
之前不知道為甚,每次一開啟vs,苦思冥想如何建立二叉樹好,翻開clifford a.shaffer的 資料結構與演算法 發現裡面根本就沒有講如何建立,望著右上角,紅色的小叉叉居然向我招手,我毫不猶豫地對她進行響應 就這樣我這個星期一直沒有進步。直到今天,硬著頭皮,終於coded兩種結構的二叉樹。寫完...
二叉排序樹 二叉搜尋樹 二叉查詢樹
特點 結構體定義struct node 建樹 建二叉排序樹 void create node root,int t else if t root data create root lc,t else create root rc,t 前序遍歷 層序 字典序 int flag int pre 1001...
二叉搜尋樹(二叉排列樹或二叉查詢樹)
1 二叉排序樹性質 1 就是若它的左子樹不空,則左子樹上所有節點的值均小於它的根節點的值 2 若它的右子樹不空,則右子樹上所有節點的值均大於其根節點的值。3 換句話說就是 任何節點的鍵值一定大於其左子樹中的每乙個節點的鍵值,並小於其右子樹中的每乙個節點的鍵值。2 二叉排序樹查詢 要在二叉樹中找出查詢...