1. 程式人生 > >算法:堆排序

算法:堆排序

tint get d+ turn 大於 初始 -s html 參考


堆排序可歸納為兩個操作:

1)建堆:根據初始數組去構造初始堆(構建一個完全二叉樹,保證所有的父結點都比它的孩子結點數值大)。

2)調整堆:每次交換第一個和最後一個元素,輸出最後一個元素(最大值),然後把剩下元素重新調整為大根堆。 當輸出完最後一個元素後,這個數組已經是按照從小到大的順序排列了。調整堆的過程是:比較節點i和左右節點,選出三者最大的,如果是孩子節點,那麽交換;並繼續比較。

建大根堆:buildMaxHeap(a[])

從A.length / 2一直到根結點進行堆調整。

堆調整:adjustHeap(a[], parent, length);

  • 定義左孩子child = 2 * parent + 1;tmp保存父節點;
  • 當child < length 的時候:
    • 如果有右孩子並且右孩子大於左孩子,則選取右孩子;(選擇孩子中較大的;)
    • 如果父節點值>孩子節點 break;(父>子,調整完畢;)
    • 孩子節點的值賦給父節點;(調整父和孩子;)
    • 孩子index賦給父index;並繼續child的孩子index賦給孩子index(繼續向下調整;)
  • tmp賦給最後的父節點;(找到調整值得最終位置;)

堆排序:heapSort(a[])

  • 建最大堆;
  • for(i=n-1)循環n-1次,交換首尾;adjustHeap(a, 0, i);

輔助交換:swap(a[], i, j)

參考代碼:

public
class Solution { /** * @param A an integer array * @return void */ //堆排序 public void sortIntegers(int[] a) { if (a.length == 0) return; buildMaxHeap(a); for (int i = a.length - 1; i > 0; i--) { swap(a, i, 0); adjustHeap(a, 0, i); } }
public void buildMaxHeap(int[] a) { for (int i = a.length/2; i >= 0; i--) { adjustHeap(a, i, a.length); } } public void adjustHeap(int[] a, int parent, int length) { int tar = a[parent]; int child = parent * 2 + 1; while (child < length) { if (child + 1 < length && a[child] < a[child + 1]) child++; if (a[child] < tar) break; a[parent] = a[child]; parent = child; child = child * 2 + 1; } a[parent] = tar; } public void swap (int[] a, int i, int j) { int tmp = a[i]; a[i] = a[j]; a[j] = tmp; } }

  • adjustHeap(a, parent, length):
    • tar值保存a[parent];定義child;
    • 當chile<length:
      • 獲取左右孩子中較大的:若存在右孩子且大於左孩子則child++;
      • 比較child和tar:若已經滿足[tar]>[child]則break;
      • child值賦給parent:註意這裏是賦值而不是swap;
      • 繼續向下調整:parent變化,child變化;
    • tar值賦給最終的a[parent];
  • buildMaxHeap(a):
    • for(i=a.length/2; i>=0),adjustHeap(a,i,a.length);註意參數是length;循環範圍是[0,a.length/2];
  • heapSort(a):
    • 判斷空return;
    • 建堆buildHeap(a);
    • 循環n-1次調整堆for(i=a.length-1; i>0); 循環範圍是(0,length-1]n-1次;
      • swap(a,i,0);
      • adjustHeap(a,0,i) length的範圍是[0,n-1]也就是i;
  • swap(a[],i,j);

參考:堆排序

測試數據:LintCode--Sort Integers


算法:堆排序