概念補充:
二叉樹:是n個結點的有限集合,該集合或為空(空二叉樹),或者由乙個根節點和兩顆互不相交的、分別稱為根節點的左子樹和
右子樹的二叉樹組成
完全二叉樹:
以上是完全二叉樹,具有n個節點的二叉樹按層序遍歷,如果i的節點與同樣深度的滿二叉樹編號為i的節點位置
完全相同,則這個二叉樹為完全二叉樹
性質5:如果乙個有n個節點的完全二叉樹,的節點按層序編號,,對任意節點(1<=i<=n)
如果i=1,節點i是二叉樹的根,無雙親,如果i>1,則其雙親節點是i/2
如果2i>n,該節點無左子樹,否則其左節點是2i
如果2i+1>n,該節點無右子樹,否則其右節點是2i+1
堆是具有以下特殊性質的完全二叉樹:
每個節點的值都大於等於左右孩子節點,大頂堆
每個節點的值都小於等於左右孩子節點,小頂堆
按層序遍歷的方式,給節點從1開始編號,節點間滿足下列關係
ki>=
k2i 或者k
i<=k2i
ki>=k
2i+1ki
<=k
2i+1(1<=i<=n/2)
堆排序演算法:將待排序序列構造成大頂堆,此時整個序列最大值為根節點,將其與堆陣列中的末尾元素交換,
此時末尾元素就是最大值,然後將剩餘的n-1個節點的序列構造成大頂堆,如此反覆。
堆排序**:
void heapsort(arr *l)
for ( i=l->length;i>1;i-- )
}//l序列l->data[s...n]之間除了r->data[s]之外均滿足堆的定義
//本函式調整l->data[s]的關鍵字,使之滿足大頂堆
void heapadjust(arr *l,int s, int n )
if ( temp >= l->data[i] )
l->data[s]=l->data[i];
s=i;
}l->data[s]=temp;}
以為待排序序列講解
s=length/2=9/2=4,n=9,既節點30的調整,
變數j以2*s開始,又是以j*=2遞變,是根據二叉樹的性質5,當前節點為s,其左孩子是2*是,右孩子是2*s+1,
他們的孩子也是以2的位數序數增加。
temp=data[4]=30
i=2*s=8,i左右孩子對比,找出大的孩子, data[j]
j=820,j=8
30<60,s=j,data[s=4]=data[j=8],既將左孩子放到雙親節點處
以上為乙個節點的調整
接下來同樣的方法對i=3,90節點做調整,i=2,10節點作調整,
i=1,50節點做調整
j=2*s=2左右孩子對比10<90,j++
j=2*s=6左右孩子對比,40<80,j++
j>n=9,退出for迴圈
通過對不是葉子節點的節點做調整,將該陣列做成乙個大頂堆的完全二叉樹陣列。
將根節點90與最後乙個接點交換,並重新調整
下一次length=8,調整將9排除陣列樹外,既最大值在陣列的最右邊
for(i=length/2;i>0;i--)
我們所謂的將待排序的序列構建成乙個大頂堆,其實就是從下往上,從右到左,將每個非
終端節點當做根節點,將其子樹調整成大頂堆。
最小的非終端節點,n/2
堆排序時間複雜度分析:
構建堆的過程,時間複雜度為o(n)
正式排序時,時間複雜度為o(nlogn)
總體來說,堆的時間複雜度為o(nlogn)
堆排序對原始記錄的排序狀態並不敏感,因此它的最好,與最壞平均時間複雜度均為o(nlogn)
因為初始構建堆所需的比較次數較多,因此堆排序不適合排序序列個數較少的情況
小白高階之堆排序
堆排序與歸併排序一樣,但不同於插入排序的是堆排序的時間複雜度為o nlgn 而與插入排序相同,但不同於歸併排序的是堆排序同樣具有空間原址性 任何時候都只需要常數個額外的元素空間儲存臨時資料。堆分為最大堆和最小堆。最大堆性質是指除了跟以外的所有結點i都滿足 a parent i a i 最小堆性質是指...
排序之堆排序
堆排序是一種基於比較排序的另一種排序演算法,它採用了一種近似完全二叉樹的二叉堆資料結構。演算法實現相容了插入排序的空間原址性 即只需要有限個額外的儲存空間 和歸併排序的優良時間複雜度。偽 如下 heapsort a build max heap a for i a.length downto 2 e...
排序之堆排序
這裡沒有對0號元素進行排序 堆排 public class heap public static void exec comparable array,int i,int j 下沉 private static void sink comparable array,int k,int n publi...