概念
- 堆结构就是用数组实现的完全二叉树结构
- 完全二叉树中如果每棵子树的最大值都在顶部就是大根堆
- 完全二叉树中如果每棵子树的最小值都在顶部就是小根堆
- 堆结构的上移heapInsert与下沉heapify操作
- 堆结构的增大和减少
- 优先级队列结构就是堆结构
完全二叉树
![[外链图片转存失败,源站可能有防盗在这里插入!链机制,建描述]议将图片上https://传(imblog.csdig.cx/ba2a8fca3c6449caamneTM6ff494c87f8e9d.030)(https://img-我blog.csdnimg.cn/ba2a8fca3c6449caae6ff494c87f8e9d.png)]](https://i-blog.csdnimg.cn/blog_migrate/86bbee0ca31457a70775c0dce7d95bc0.png)
数组中元素的位置与堆中的位置关系
- 第i个元素的左节点位置:2*i + 1
- 第i个元素的右节点位置:2*i + 2
- 第i个元素的父节点位置:(i-1)/ 2 向下取整
代码实现大根堆
function heapInsert(arr, index) {
while (arr[index] > arr[(index - 1) >> 2]) {
swap(arr, index, (index - 1) >> 2);
index = (index - 1) >> 2;
}
}
const heapify = (arr, i, size) => {
let left = 2 * i + 1;
while (left < size) {
let index = left + 1 < size && arr[left + 1] > arr[left] ? left + 1 : left;
let largest = arr[index] > arr[i] ? index : i;
if (largest == i) break;
swap(arr, largest, i);
i = largest;
left = 2 * i + 1;
}
};
function heapSort(arr) {
for (let i = 0; i < arr.length; i++) {
heapInsert(arr, i);
}
for (let i = arr.length - 1; i >= 0; i--) {
heapify(arr, i, arr.length);
}
let heapSize = arr.length;
swap(arr, 0, --heapSize);
while (heapSize > 0) {
heapify(arr, 0, heapSize);
swap(arr, 0, --heapSize);
}
}
function swap(arr, i, j) {
let tem = arr[i];
arr[i] = arr[j];
arr[j] = tem;
}