7 2 二叉樹與堆

2022-09-07 00:15:20 字數 1922 閱讀 8520

二叉樹是一種特殊的、常見的樹

二叉樹的特點在於每個結點最多只有兩個兒子

如果要使用更嚴格的遞迴定義,則是:

二叉樹要麼為空,要麼由根結點、左子樹、右子樹組成

而左子樹、右子樹分別是一棵二叉樹

二叉樹是使用範圍極廣的樹,一棵多叉樹也可以轉換為二叉樹

滿二叉樹:如果二叉樹中每個內部結點都有兩個兒子,這樣的二叉樹叫做滿二叉樹

完全二叉樹:如果一棵二叉樹除了最右邊的位置上有乙個或幾個葉節點缺少外,其他都是豐滿的,那麼它就是完全二叉樹

我們可以把滿二叉樹理解為一種特殊的,極其完美的完全二叉樹

我們只需要用乙個一維陣列就能儲存完全二叉樹

我們將完全二叉樹進行從上到下,從左到右的編號,可以得到下面這個結論:

如果已知子結點的編號是x,那麼它父結點的編號就是x/2

符合所有父結點都比子結點要小的樹,就是最小堆

符合所有父結點都比子結點要大的樹,就是最大堆

那麼想要向堆中加入乙個資料,需要怎麼做呢?

比如說我們想要把23加入到乙個最小堆

1.我們把23放入堆頂,檢查是否合適

2.如果不合適,我們就將這個數和它的兩個兒子比較,並且選擇較小者交換位置

3.繼續向下交換,檢查。重複1-2直到符合條件

當新增加乙個數被放置到堆頂時,如果此時不符合最小堆的特性,則需要將這個數向下調整,直到找到合適的位置為止

void siftdown(int i)

//如果發現最小的結點編號不是自己,那麼就說明子結點中,有比父結點更小的

if(t!=i)

else

}return ;

}

如果只是想新增乙個值,而不要刪除掉最小值,那麼該怎麼做呢?

直接將新元素插入到末尾,再根據情況判斷元素是否需要上移,直到滿足堆的特性為止

與快速排序一樣,,堆排序的時間複雜度是o(nlogn)

進行堆排序,需要我們建立對應的堆,每次刪除頂部元素並將頂部元素輸出或者放到乙個陣列中,直到堆空

最後輸出的或者存放在新陣列中的數,就是已經排序好的

下面以從小到大排序為例

//先整個刪除最小元素的

int deletemin()

完整的**組成如下:

#include int h[101];//用來存放堆的陣列

int n ; //用來儲存堆中元素的個數,實質上就是堆的大小

//先整個交換函式

void swap(int x ,int y)

//向下調整的函式,上文已經寫過了

void siftdown(int i)

//如果發現最小的結點編號不是自己,那麼就說明子結點中,有比父結點更小的

if(t!=i)

else

}return ;

}//建立堆的函式

void creat()

return ;

}//刪除最大的元素

int deletmax()

int main(){

int i , num ;

//讀入要排序的數字個數

scanf("%d",&num);

//讀入數字

for(i=1;i像這種,支援插入元素和尋找最值元素的資料結構被稱為優先佇列

堆就是一種優先佇列的實現

樹 二叉樹 堆

樹 樹是乙個無向無環圖,n個節點正好有n 1條邊,再任意加上一條邊就可以構成迴路。乙個結點的上乙個結點是這個結點父結點,這個節點是子結點,並且父結點和子結點是相對的。特別的,如果乙個結點沒有父結點,那這個結點是根節點 乙個結點沒有子結點,它是葉節點。二叉樹 如果乙個樹除了葉結點之外的其他每個結點都不...

二叉堆(完全二叉樹)

最小堆的實現 最小堆是一顆完全二叉樹 這裡用陣列實現完全二叉樹 index 0 1 2 3 4 5 6 value 空 a b c d 任意index,其父親為index 2,左兒子為2 index,右兒子為2 index 1 時間複雜度 o logn include includeusing na...

樹 二叉樹 滿二叉樹 完全二叉樹 堆 概念彙總

樹 乙個擁有n 個節點和n 1 條邊的乙個有向無環圖。二叉樹 每個節點最多有兩個子樹的樹結構。滿二叉樹 除最後一層無任何子節點外,每一層上的所有結點都有兩個子結點的二叉樹。完全二叉樹 由滿二叉樹而引出 二叉樹的深度為h,除第 h 層外,其它各層 1 h 1 的結點數都達到最大個數 滿二叉 樹 第 h...