1. 程式人生 > >js實現堆排序

js實現堆排序

小頂堆 ldm heapsize 結點 記錄 堆排序原理 維護 繼續 初始

二叉樹:數據結構的一種。二叉樹的每個結點至多只有二棵子樹(不存在度大於2的結點),二叉樹的子樹有左右之分,次序不能顛倒。一棵深度為k,且有2^k-1個節點稱之為滿二叉樹;深度為k,有n個節點的二叉樹,當且僅當其每一個節點都與深度為k的滿二叉樹中,序號為1至n的節點對應時,稱之為完全二叉樹。

堆實質上是完全二叉樹,必須滿足:樹中任一非葉子結點的關鍵字均不大於(或不小於)其左右孩子(若存在)結點的關鍵字。

堆分為:大根堆和小根堆,升序排序采用大根堆,降序排序采用小根堆。

堆排序原理:

利用大頂堆(小頂堆)堆頂記錄的是最大關鍵字(最小關鍵字)這一特性,使得每次從無序中選擇最大記錄(最小記錄)變得簡單。

1.將初始無需數組構建大頂堆(小頂堆)

2.將堆頂元素R(1)與堆末元素R(n)交換,得到無序區R(1)~R(n-1)與有序區R(n),且滿足R(1~n-1)<=R(n)

3.將無序區R(1)~R(n-1)繼續調整,然後再次將R(1)與無序區最後一個元素交換,得到新的無序區(R1,R2....Rn-2)和新的有序區(Rn-1,Rn)。不斷重復此過程直到有序區的元素個數為n-1,則整個排序過程完成。

js代碼實現:

/*

維護最大堆性質

@param arr 數組

@param index 元素下標

@param heapSize 堆大小

*/

function maxHeap(arr, index, heapSize){

  var tem = index; //記錄入參元素下標

  var leftChildIndex = 2 *i ndex + 1; //元素的左子樹的元素下標

  var rightChildeIndex = 2 * index + 2;//元素的右子樹的元素下標

  if( leftChildIndex < heapSize && arr[leftChildIndex] > arr[index]){

    index = leftChildIndex;

  }

  if( rightChildeIndex < heapSize && arr[rightChildeIndex] > arr[index]){

    index = rightChildeIndex;

  }

  if(index != tem){

    var t = arr[tem];

    arr[tem] = arr[index];

    arr[index] = t;

    maxHeap(arr, index, heapSize);

  }

}

/*

構建最大堆

@param arr 數組

*/

function buildMaxHeap(arr){

  var lastFather = Math.floor(arr.length / 2) - 1;//堆的最後一個父節點

  for(var i = lastFather; i > 0; i --){

    maxHeap(arr, i, arr.length);

  }

}

/*

堆排序

@param arr 待排序數組

*/

function heapSort(arr){

  var len = arr.length;

  var tem;

  buildMaxHeap(arr);

  for(var i = len - 1; i > 0; i --){

    tem = arr[i];

    arr[i] = arr[0];

    arr[0] = tem;

    maxHeap(arr, 0 , --len);

  }

  return arr;

}

js實現堆排序