堆是一个满足一定性质的二叉树。大顶堆的意思是父节点的值总是不小于子节点的值,小顶堆则正好相反。对于任何序列,建堆的时间复杂度为o(n)。堆的底层可以直接使用数组实现。
堆的操作
堆的插入
堆的删除
堆只支持删除跟节点的元素。将最后一个跟节点和最后一个元素交换,然后删除最后一个元素,然后数据下沉依次调整。
因此将堆顶元素与堆尾元素交换,然后进行调整使其满足堆的约束条件
调整思想如下:
从根节点开始调整比较根节点值与左右孩子节点的值,
1如果根节点值为最大值则满足条件
2如果右孩子存在且最大值为右孩子,则将根节点与右孩子交换
3如果左孩子存在且最大值为左孩子,则将根节点与左孩子交换
应用:堆排序
参考排序
https://www.cnblogs.com/chengxiao/p/6129630.html
简单而言就是构建一个初始堆,然后从最后一个非叶子节点开始,从右到左,从下到上不断将这个节点决定是否下沉。
应用:优先队列
可以看到java具体的实现java.util.PriorityQueue
private void siftUpComparable(int k, E x) {
Comparable<? super E> key = (Comparable<? super E>) x;
while (k > 0) {
int parent = (k - 1) >>> 1;
Object e = queue[parent];
if (key.compareTo((E) e) >= 0)
break;
queue[k] = e;
k = parent;
}
queue[k] = key;
}