堆(heap)是实现有限队列的首选,在上一篇文章中有讲解。
这篇文章将堆的变种
二项堆 斐波那契堆
二叉堆的主要操作时
insert() O(logn) 在尾部插入元素并siftUp调整堆
extractMin() O(logn)删除堆顶元素并将最后一个放在堆顶 用siftDown调整
peek() O(1)
delete() O(logn)
heapify() O(n)
要实现堆的操作要涉及两个函数siftDown siftUp.
建堆的思路:
1.不停的insert(insert调用siftUp)
2.将一个数组变成一个堆 从底向上每个位置siftDown调整
关于具体的代码实现 正在写
堆的应用
1.堆排序
常用的 稳定的 高效的排序算法 堆排序 时间复杂度(nlogn) 空间(o1)
思想
n个元素的无序数组nums ,构建一个heap ,依次执行n次extractMin得到最小元素,执行n次得到的就是排列好的顺序
但是由于相同的两个键位于两颗子树中,两个元素的顺序会在堆调整时发生改变 所以是不稳定排序
降序 小跟堆
升序 大根堆
2.优先队列
优先队列的应用场景:
Dijkstras 单源最短路径
Huffman 构建最优的前缀树
Prims 最小生成树
Bestfirst serach
3.海量数据 top-k问题
思想 维护一个大小为k的二叉堆然后不断比较堆顶元素 判断是否替换堆顶元素
时间复杂度n*logk k和n差距很大 此方法有效