堆排序是指利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,即将堆逻辑上存成完全二叉树的形式,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。

         在堆的数据结构中,堆中的最大值总是位于根节点(在优先队列中使用堆的话堆中的最小值位于根节点)。堆中定义以下几种操作:

最大堆调整(Max Heapify):将堆的末端子节点作调整,使得子节点永远小于父节点

创建最大堆(Build Max Heap):将堆中的所有数据重新排序

堆排序(HeapSort):移除位在第一个数据的根节点,并做最大堆调整的递归运算 

var len;
   function buildMaxHeap(arr) {   //建堆
       len = arr.length;
       // [n/2-1]表示的是最后一个有子节点 (本来是n/2(堆从1数起),但是这里arr索引是从0开始,所以-1)
       for (var i = Math.floor(len/2)-1; i>=0; i--) {
           maxHeapify(arr, i);
       }
       //对每一个节点(非叶节点),做堆调整
   }
   function maxHeapify(arr, i) {     //堆调整
       var left = 2*i+1,
           right = 2*i+2,
           largest = i;   //i为该子树的根节点

       if (left < len && arr[left] > arr[largest]) {
           largest = left;
       }

       if (right < len && arr[right] > arr[largest]) {
           largest = right;
       }

       if (largest != i) {  //即上面的if中有一个生效了
           swap(arr, i, largest);  //交换最大的为父节点
           maxHeapify(arr, largest);  //交换后,原值arr[i](往下降了)(索引保存为largest),
           //作为根时,子节点可能比它大,因此要继续调整
       }
   }
   function swap(arr, i, j) {
       var temp = arr[i];
       arr[i] = arr[j];
       arr[j] = temp;
   }
   function heapSort(arr) {
       buildMaxHeap(arr);
       for (var i = arr.length-1; i > 0; i--) {
           swap(arr, 0, i);
           len--;
           maxHeapify(arr, 0);
       }
       return arr;
   }