八大排序之堆排序

2021-08-18 20:12:35 字數 2473 閱讀 9102

堆排序法(直接選擇排序的改進):將排序碼k1,k2,k3,...,kn表示成一棵完全二叉樹,然後從第n/2個排序碼開媽篩選,使由該結點組成的子二叉樹符合堆的定義,然後從第n/2-1個排序碼重複剛才操作,直到第乙個排序碼止,這時候,該二叉樹符合堆的定義,初始堆已經建立。

接著,可以按如下方法進行堆排序:將堆中第乙個結點(二叉樹根結點)和最後乙個結點的資料進行交換(k1與kn),再將k1--kn-1重新建堆,然後k1和kn-1交換,再將k1--kn-2重新建堆,然後k1和kn-2交換,如此重複下去,每次重新建堆的元素個數不斷減1,直到重新建堆的元素個數僅剩乙個為止。這時堆排序已經完成,則排序碼k1,k2,k3,...kn已排成乙個有序序列。

若排序是從小到大排列,則可以建立大根堆實現堆排序,若排序是從大到小排列,則可以用建立小根堆實現堆排序。

時稱之為堆。由堆的定義可以看出,堆頂元素(即第乙個元素)必為最小項(小頂堆,或最大項,則對應為大頂堆)。若以一維陣列儲存乙個堆,則堆對應一棵完全二叉樹,且所有非葉結點的值均不大於(或不小於)其子女的值,根結點(堆頂元素)的值是最小(或最大)的。如:

(a)大頂堆序列:(96, 83,27,38,11,09)

(b)小頂堆序列:(12,36,24,85,47,30,53,91)

初始時把要排序的n個數的序列看作是一棵順序儲存的二叉樹(一維陣列儲存二叉樹),調整它們的儲存序,使之成為乙個堆,將堆頂元素輸出,得到n個元素中最小(或最大)的元素,這時堆的根節點的數最小(或者最大)。然後對前面(n-1)個元素重新調整使之成為堆,輸出堆頂元素,得到n個元素中次小(或次大)的元素。依此類推,直到只有兩個節點的堆,並對它們作交換,最後得到有n個節點的有序序列。稱這個過程為堆排序

因此,實現堆排序需解決兩個問題:

1.如何將n個待排序的數建成堆;

2.輸出堆頂元素後,怎樣調整剩餘n-1個元素,使其成為乙個新堆。

首先建堆方法:對初始序列建堆的過程,就是乙個反覆進行篩選的過程。

1)n個結點的完全二叉樹,則最後乙個結點是第n/2個結點的子樹。

2)篩選從第n/2個結點為根的子樹開始,該子樹成為堆。

3)之後向前依次對各結點為根的子樹進行篩選,使之成為堆,直到根結點。

如圖建堆初始過程:無序序列:(49,38,65,97,76,13,27,49)

然後討論第二個問題:輸出堆頂元素後,對剩餘n-1元素重新建成堆的調整過程。調整小頂堆的方法:

1)設有m個元素的堆,輸出堆頂元素後,剩下m-1個元素。將堆底元素送入堆頂((最後乙個元素與堆頂進行交換),堆被破壞,其原因僅是根結點不滿足堆的性質。

2)將根結點與左、右子樹中較小元素的進行交換。

(小頂堆是小元素在上面,所以與較小的元素交換,大頂堆是較大的元素在上面,所以與較大的元素交換

)。3)若與左子樹交換,如果左子樹堆被破壞,即左子樹的根結點不滿足堆的性質,則重複方法(2).

4)若與右子樹交換,如果右子樹堆被破壞,即右子樹的根結點不滿足堆的性質。則重複方法 (2).

5)繼續對不滿足堆性質的子樹進行上述交換操作,直到葉子結點,堆被建成。

稱這個自根結點到葉子結點的調整過程為篩選。如圖:

堆排序實現:

package com.eight.paixu;

public class heapsort ;

heapsort obj = new heapsort();

system.out.print("初始陣列: ");

obj.print(a);

for (int i = 0;i = 0;i--)

} //若雙親節點值小於於子節點中較大的,則交換2者得值(建立大頂堆,大的元素要上來)

if (data[parent] < data[bigger]) else

} }

} public void print(int a)

system.out.println();

} public void swap(intdata,int i,int j)

data[i] = data[i] + data[j];

data[j] = data[i] - data[j];

data[i] = data[i] - data[j];

} }

八大排序之堆排序

public class heapsort heapsort num,num.length for int i 0 i 0 i heapadjust array,i,length 從最後乙個元素開始對序列進行調整,不斷的縮小調整的範圍直到第乙個元素 for i length 1 i 0 i priv...

八大排序之堆排序

public static void heapsort int arr for int i 0 i arr.length i int size arr.length 堆中用size表示長度 swap arr,0,size while size 0 用 3 0 1 5 2 畫圖,過程清晰。陣列最後插入...

八大排序 堆排序

堆排序 利用大頂堆 小頂堆 堆頂記錄的是最大關鍵字 最小關鍵字 這一特性,使得每次從無序中選擇最大記錄 最小記錄 變得簡單。其基本思想為 大頂堆 1 將初始待排序關鍵字序列 r1,r2 rn 構建成大頂堆,此堆為初始的無須區 2 將堆頂元素r 1 與最後乙個元素r n 交換,此時得到新的無序區 r1...