高階排序之堆排序

2021-06-28 13:42:07 字數 2699 閱讀 3369

概念補充:

二叉樹:是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...