**實現
二叉堆是基於完全二叉樹的基礎上,加以一定的條件約束的一種特殊的二叉樹。
根據約束條件的不同,二叉堆又可以分為兩個型別:
大頂堆和小頂堆。
即任何乙個父節點的值,都 大於等於 它左右孩子節點的值。
即任何乙個父節點的值,都 小於等於 它左右孩子節點的值。
二叉堆的根節點叫做 堆頂 ,它是大頂堆裡面的最大值,小頂堆裡的最小值。
大頂堆和小頂堆的操作都是差不多的,這裡用小頂堆來講。
假如我們有乙個二叉樹,如下圖:
我們從最下面乙個 非葉子節點開始 ,是3。
因為小頂堆的父節點要比子節點要小,所以3可以不動,同理0也不動。
然後我們到了9,我們把9和它兩個子節點中最小的那個換位置:
然後9繼續和子節點交換:
這裡其實做的是乙個讓非葉子節點 下沉 的操作。
然後我們接著把5下沉:
5接著下沉:
然後我們這個小頂堆就完成了。
堆的建立其實就是根據約束條件 下沉非葉子節點 的過程。
堆節點的刪除,是指將堆頂刪除,如圖:
因為二叉堆是建立在完全二叉樹的基礎上。
所以為了維護完全二叉樹,我們將最後乙個節點移動到堆頂:
然後我們根據約束規則,把9下沉就行了,最後結果是下圖:
建立和刪除都是 下沉 操作,新增不一樣,它做的是 上浮 操作。
假設我們要新增乙個0,我們先將0最為最後乙個節點,如圖所示:
上浮 操作:
將 上浮節點 和其 父節點 比較,如果上 浮節點《父節點 ,就互換。
首先是0和6互換:
然後0和3換位置,再和2換位置,得到最終結果:
堆排序非常簡單。
因為堆頂是最值,所以我們可以把堆頂和最後乙個節點換位置,然後再把最後節點從樹上摘除。
此時我們得到了乙個新的樹,我們再把這個樹重新變成二叉堆。
然後堆頂又是最值了,接著重複上述步驟,就能實現堆排序。
因為堆是基於完全二叉樹,所以我們不需要用鏈式結構來表示,我們可以直接用陣列存。
假設父節點的下表為parent,從父節點獲取子節點:
左節點下標: 2*parent+1
右節點下標: 2*parent+2
假設子節點的下標為son(左右子節點都可以):
父節點下標:(son-1)/2
所以我們可以非常簡單的表示出節點之間的關係了,下面是**:
#include
using
namespace std;
const
int maxn =
10000
;int heap[maxn]
;int size =0;
intgetleft
(int parent)
//獲取左節點
intgetright
(int parent)
//獲取右節點
intgetparent
(int son)
//獲取父節點
void
initheap
(int n)
//n是堆的大小,初始化堆元素
heap[parent]
= temp;
index--;}
}void
creatheap
(int n)
//建立堆
void
insert
(int value)
//新增元素
heap[son]
= value;
}void
pop(
)//刪除元素
heap[parent]
= temp;
}void
printheap()
//列印堆
void
heapsort()
//堆排序
}
通俗易懂!什麼是MIMO?
01 mimo是什麼 在這個萬物互聯的時代,手機作為我們和外界聯絡的視窗,似乎已經成為了我們身體的一部分。而手機是無法自己上網的,和手機進行通訊的通訊網路,已經變得跟水和電一樣。暢快上網的時候,感覺不到這些幕後英雄的重要,一旦離開就感覺跟活不下去了一樣。按流量收費的時代,曾幾何時,1m流量收費一塊,...
通俗易懂的解釋 什麼是API
看到這裡,急性子的小白同學馬上就憋不住了 這不管是英文還是中文我每個字都懂啊,只是湊一塊就不知道什麼意思了,兄弟你能不能說人話啊?別著急,讓我們先看乙個小小的比方。有一天,小明來到了一家餐廳,想要吃上乙份他最愛的北京烤鴨。而他只需要把訂單交給服務員,然後就可以等著大口吃肉,大碗喝酒了。看完這個比喻,...
通俗易懂講解什麼是波特率
接觸過物聯網的都應該常聽到過這次詞 波特率。對於工程師來說,這次肯定是很熟知的,但是對於剛開始了解物聯網的同學來說,就比較陌生了。下面就來為你揭開迷霧,講講什麼是波特率。波特率 bandrate 指的是串列埠通訊的速率,也就是串列埠通訊時每秒鐘可以傳輸多少個二進位制位。比如每秒鐘可以傳輸9600個二...