堆特性
- 完全二叉树
- 任意一个父节点的值都大于子节点
构建堆
- 堆化:对指定节点进行堆化,使得当前节点大于其子节点【注意:进行过堆化后要对子节点也进行堆化,保证整棵树满足堆特性】
- 堆:自下而上,从最后一个节点开始,依次对每个节点作堆化。
堆排序
- 堆的特性,使得整棵树的最大值在堆顶。交换堆顶和堆尾的值后,砍去堆尾(即树长度 - 1)后对整棵树进行堆化,再次使得整棵树的最大值在堆顶。重复操作,实现树按照从小到大的顺序从堆顶到堆尾。
- 代码
/**
* @param {number[]} nums
* @param {number} k
* @return {number}
*/
var findKthLargest = function(nums, k) {
heapSort(nums, nums.length);
return nums[nums.length - k];
};
const swap = (arr, i, j) => {
const temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
const heapify = (tree, n, i) => {
if (i >= n) {
return;
}
const leftChildNode = 2 * i + 1;
const rightChildNode = 2 * i + 2;
let max = i;
if (leftChildNode < n && tree[leftChildNode] > tree[max]) {
max = leftChildNode;
}
if (rightChildNode < n && tree[rightChildNode] > tree[max]) {
max = rightChildNode;
}
if (max !== i) {
swap(tree, max, i);
heapify(tree, n, max);
}
}
const buildHeap = (tree, n) => {
const lastNode = n - 1;
const parentNode = Math.floor((lastNode - 1) / 2);
for(let i = parentNode; i >= 0; i--) {
heapify(tree, n, i);
}
}
const heapSort = (tree, n) => {
buildHeap(tree, n);
for(let i = n - 1; i > 0; i--) {
swap(tree, 0, i);
heapify(tree, i, 0);
}
}
- 缺陷: 对整棵树进行了排序,造成浪费。