大顶堆和堆排序

function GetLeastNumbers_Solution(input, k)
{
    // 构建最大堆
    // 二叉堆使用数组表示,顶点是下标1开始,子节点分别为2*n, 2*n +1
    // 对于长度为N的数组,其最后一个非叶子节点的位置为Math.floor(n/2)
    // 最大堆要求每一个分支都是最大堆,从最后一个父节点开始构建
    let n = input.length;
    if(input.length < k) return []
    // 构建最大堆
    for(let i=~~((n-1)/2); i>=0; i--) {
        maxHeapify(input, i, n);
    }
    // 堆排序
    for(let i=n-1; i>0; i--) {
        swap(input, 0, i);
        // 最大堆顶点和尾点交换后,将顶点最大堆化,则得到第二大。依次。。。
        maxHeapify(input, 0, i)
    }
    return input.slice(0,k);
}
// 
function maxHeapify(input, i, n) {// i开始堆化的位置;n长度
    let left = 2*i + 1; 
    let right = 2*i + 2;
    // 默认父节点为最小值
    let maxIndex = i;
    if (left <n && input[maxIndex] < input[left]) {
        maxIndex = left;
    }
    if (right <n && input[maxIndex] < input[right]) {
        maxIndex = right;
    }
    if (maxIndex !== i) {
       swap(input, i, maxIndex); 
       // 对于变动后的节点,需要重新进行最大堆调整
       maxHeapify(input, maxIndex, n);
    }
}
function swap(arr, i, j) {                                      
    let temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}

 

posted @ 2020-03-19 21:53  Lyra李  阅读(288)  评论(0编辑  收藏  举报