https://github.com/vnues/data-structure-algorithm/blob/master/215.%20%E6%95%B0%E7%BB%84%E4%B8%AD%E7%9A%84%E7%AC%ACK%E4%B8%AA%E6%9C%80%E5%A4%A7%E5%85%83%E7%B4%A0.js
const num = [3,2,1,5,6,4] const  k = 2console.log(findKthLargest(num,6))// 可以使用堆排序来解决这个问题——建立一个大顶堆,做k−1 次删除操作后,堆顶元素就是我们要找的答案// ! 因为大顶堆的 最大数的肯定是在顶 如果我们再删除k-1次数 然后再调整大顶堆// 建堆的好处就是可以操作K次就拿到结果 而不是全部排序后再去拿到结果// 尤其要搞懂「建堆」、「调整」和「删除」的过程function findKthLargest(nums,  k) {    let heapSize = nums.length;    buildMaxHeap(nums, heapSize); // 构建大顶堆    // ! 删除k-1操作 就是相当于下沉 nums.length - k + 1次    // 比如k是nums.length 第k大  数组6个元素排序 5个排好就行 所以i>=0    for (let i = nums.length - 1; i >= nums.length - k + 1; --i) {        swap(nums, 0, i); // 进行下沉 也就是交换 大顶堆 大的放后面        --heapSize;         maxHeapify(nums, 0, heapSize);    }    // !要找的目标值不进行下沉就行 在堆顶获取到    console.log(nums)    return nums[0]; // nums ===> [ 5, 3, 4, 1, 2, 6 ]} // ! 自下而上构建大顶堆 ===>从最后一个非叶子节点构建再到根节点 // 非叶子节点function buildMaxHeap(a,  heapSize) {    // heapSize / 2 表示有多少个非叶子节点    for (let i = Math.floor(heapSize / 2)-1; i >= 0; --i) {        maxHeapify(a, i, heapSize);    } }// ! 自上而下的「调整」function maxHeapify(a,  i,  heapSize) {     // 左子节点和右子节点     let l = i * 2 + 1, r = i * 2 + 2, largest = i;    if (l < heapSize && a[l] > a[largest]) {        largest = l;    }     if (r < heapSize && a[r] > a[largest]) {        largest = r;    }    if (largest != i) {        swap(a, i, largest);        maxHeapify(a, largest, heapSize);    }}function swap(a,  i,  j) {    let temp = a[i];    a[i] = a[j];    a[j] = temp;}// 堆排序的步骤// 1.构造初始堆 给定无序序列结构 如下:注意这里的操作用数组// 2.此时从最后一个非叶子节点开始调整,从左到右,从上到下进行调整 ===> let i = Math.floor(heapSize / 2)-1// 3.将堆顶元素与末尾元素进行交换 ===>进行下沉操作