JS实现堆排序

堆排序

let arr=[2,4,5,6,6,4,3,0,21,213,65];
/*
[1]
[2,1]
[4,1,2]
[6,4,2,1]
[6,4,5,1,3,2]
* */
console.log(heapSort(arr));

function heapSort(arr) {
    //1.先变成大根堆
    for (let i =0;i<arr.length;i++){//每次加一个属数字进堆
        biJiao(arr,i);//把这个数字和父节点比较,父节点位置就是(i-1)/2
       // console.log((i - 1) / 2);
    }
    //此时的数组就是大根堆,然后头部和最后一个数字交换
    let heapSize=arr.length;
    swap(arr,0,heapSize-1); //头部和最后一个数字交换
    for(;heapSize>0;) {
        xiaChen(arr, 0, --heapSize);//重新形成大根堆 [5, 4, 2, 1, 3, 6] 大根堆的长度-1(表示组后一个数字已经是最大的,不用再参与了)
        swap(arr, 0, heapSize);  //再交换,heapSize-1,直到heapSize=0[3, 4, 2, 1, 5, 6]
    }
    return arr;
}

function biJiao(arr,index) {//把这个数字和父节点比较,父节点位置就是(i-1)/2
    for (;arr[index]>arr[parseInt((index-1)/2)];){
        swap(arr,index,parseInt((index-1)/2));
        index=parseInt((index-1)/2);
    }
}
function swap(arr,i,j) {//交换函数
    let temp=arr[i];
    arr[i]=arr[j];
    arr[j]=temp;
}

//
function xiaChen(arr,index,heapSize) {//大根堆头部的数字和最后一个数字交换之后,再次形成大根堆,可以看作把头部的数字下沉
    let left=2*index+1;
    for (;left<heapSize;) {//沉到底了就算越界了
        let largest= left+1<heapSize&&arr[left+1]>arr[left]?left+1:left;//左子节点和右子节点比较
        largest=arr[largest]>arr[index]?largest:index;
        if (largest==index){
            break
        }
        swap(arr,largest,index);
        index=largest;
        left=2*index+1;
    }
}

你可能感兴趣的:(JS实现堆排序)