通俗易懂,什麼是二叉堆?

2021-10-19 17:46:28 字數 2699 閱讀 8453

**實現

二叉堆是基於完全二叉樹的基礎上,加以一定的條件約束的一種特殊的二叉樹。

根據約束條件的不同,二叉堆又可以分為兩個型別:

大頂堆小頂堆

即任何乙個父節點的值,都 大於等於 它左右孩子節點的值。

即任何乙個父節點的值,都 小於等於 它左右孩子節點的值。

二叉堆的根節點叫做 堆頂 ,它是大頂堆裡面的最大值,小頂堆裡的最小值。

大頂堆和小頂堆的操作都是差不多的,這裡用小頂堆來講。

假如我們有乙個二叉樹,如下圖:

我們從最下面乙個 非葉子節點開始 ,是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個二...