基礎算法學習之(三):堆排序

奇妙的記憶點:

  • 不穩定javascript

  • 內排序java

基本思想:

分爲兩步,建堆與維持堆的性質,首先咱們要先理解堆是什麼東西.
堆其實就是一個徹底二叉樹,咱們可使用順序表存儲一個二叉樹,以下圖所示來存儲:數組

其中分爲最大堆最小堆,而最大堆就是上頭大,下頭小;最小堆則反之.
明白了堆的定義咱們就能夠開始學習堆排序了,堆排序其實也是分爲有序區與無序區,其中無序區就是咱們建好的最大堆,根節點就是堆中最大的數,咱們逐個讓最大元素進有序區並對堆結構進行調整,維持根節點最大的性質,直到堆中元素清空爲止,就是堆排序的過程.
函數

堆排序關鍵代碼

//工具函數
function swapItem(pre,next,arr){
  var temp = arr[next];
  arr[next] = arr[pre];
  arr[pre] = temp;
}
function getLeft(i){
  return 2*i+1;
}
function getRight(i){
  return 2*i+2;
}

//維持堆的性質
function heapAdjust(arr,i,len){//數組,數組下標,堆元素長度(無序區長度)
  var large,l = getLeft(i),r = getRight(i);
  if(l < len&&arr[l] > arr[i]){
    large = l;
  }else{
    large = i;
  }
  if(r < len&&arr[r] > arr[large]){
    large = r;
  }
    //上述代碼就是取節點也子節點三個元素之間的最大值
  if(large !== i){
    swapItem(large,i,arr);
    heapAdjust(arr,large,len);//防止堆性質被破壞,因此遞歸調用來維持堆性質
  }
}

//建堆
function heapBuild(arr,len){
  for(var i = Math.floor(len / 2) - 1;i>=0;i--){
    heapAdjust(arr,i,len);
  }
  //console.log(arr);
}

//堆排序本體以下
function heapSort(arr){
  var heapSize = arr.length;//堆(無序區)大小
  heapBuild(arr,heapSize);//建堆
  for(var i=heapSize-1;i>=1;i--){
    swapItem(0,i,arr);//堆頂部元素與堆底部元素交換(無序區->有序區)
    //console.log(arr);
    heapAdjust(arr,0,--heapSize);//維持堆性質(無序區)
  }
}
//測試代碼
var arr=[91,60,96,13,35,65,46,65,10,30,20,31,77,81,22];
heapSort(arr);
console.log(arr);

記憶點:

  • 最佳狀況:T(n) = O(nlogn)工具

  • 最差狀況:T(n) = O(nlogn)學習

  • 平均狀況:T(n) = O(nlogn)測試

相關文章
相關標籤/搜索