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.将堆顶元素与末尾元素进行交换 ===>进行下沉操作