二叉樹是一種特殊的、常見的樹
二叉樹的特點在於每個結點最多只有兩個兒子
如果要使用更嚴格的遞迴定義,則是:
二叉樹要麼為空,要麼由根結點、左子樹、右子樹組成二叉樹是使用範圍極廣的樹,一棵多叉樹也可以轉換為二叉樹而左子樹、右子樹分別是一棵二叉樹
滿二叉樹:如果二叉樹中每個內部結點都有兩個兒子,這樣的二叉樹叫做滿二叉樹
完全二叉樹:如果一棵二叉樹除了最右邊的位置上有乙個或幾個葉節點缺少外,其他都是豐滿的,那麼它就是完全二叉樹
我們可以把滿二叉樹理解為一種特殊的,極其完美的完全二叉樹
我們只需要用乙個一維陣列就能儲存完全二叉樹
我們將完全二叉樹進行從上到下,從左到右的編號,可以得到下面這個結論:
如果已知子結點的編號是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...