js 实现堆排序

281 阅读1分钟
var arr = [49,38,65,97,76,13,27,49]
// 先写堆调整的筛选
function heapAdjust(arr, x, length) {
    var left = 2*x+1;
    var right = 2*x+2;
    var smallest = x;// 保存最小元素的坐标    
    var temp    
    if(left < length && arr[left] < arr[smallest]){ 
       smallest = left   
     }    
    if(right < length && arr[right] < arr[smallest]){
       smallest = right    
     }    
    if(smallest !== x) {
       temp = arr[x];
       arr[x] = arr[smallest];
       arr[smallest] = temp ;      
       heapAdjust(arr,smallest,length) 
     }
}
// 建堆
/** 无序堆 从第n/2个元素开始依次到第1个元素
* 也就是说下标看就是从(arr.length)/2-1 到 第0个元素 的节点为跟的子树进行调整堆 一直到下标为0 的元素 有序堆建立好了
* */
function heapSort(arr) {
    let length = arr.length
    for (let i = (arr.length)/2 -1 ; i >= 0; i--) {
        heapAdjust(arr,i,arr.length)    
    }    
    console.log('建堆', arr)
    var temp
    // 堆排序 以小根堆为例 堆建好之后 堆顶就是最小的元素了
    /*    
     * 1. 输出堆顶元素之后,以堆中最后一个元素(编号最大的元素)代替它 也就是把最后面的元素拿到堆顶
     * 2.然后进行堆调整 '筛选'( 将根节点值与左右孩子值比较,并与其中小者进行交换,重复上述操作直到叶子节点)
     * */    
     for (let j = arr.length-1; j >= 1; j--) {
        temp = arr[0];
        arr[0] = arr[j];
        arr[j] = temp ;     
        heapAdjust(arr,0,--length) 
      }    
    return arr;
 }
console.log('堆排序', heapSort(arr))