好久没写博客了。今天在做力扣丑数这道题的时候用到了python内置的小顶堆。所以来总结一下关于堆的内容~
1. 堆的概念
堆是一颗完全二叉树
小顶堆:任意一个节点的左右孩子的值都大于此节点的值。即堆顶上维护了一个堆中最小的数。
大顶堆:任意一个节点的左右孩子的值都小于此节点的值。即对顶上维护了一个堆中最大的数。
2.堆的创建
以小堆为例:向上调整算法(向下调整类似,满足堆的概念即可)
时间复杂度为O(n)
- 先设定倒数第一个叶子结点为当前结点cur,找出他的父节点parent
- 比较cur和parent的值,如果cur比parent小,将他俩交换
- 如果cur比parent大,不需要交换
- 处理完一个节点后,从当前的parent出发,循环之前的过程
3. 堆的插入
将数据插入到数组最后,再向上进行调整
时间复杂度为O(logN)
4. 堆的删除
删除堆是删除堆顶数据
将堆顶的数据和最后一个数据交换,然后删除数组的最后一个数据,再进行向下调整算法。
时间复杂度O(logN)
5. 堆的排序
- 将待排序序列构造成一个大顶堆
- 此时,整个序列的最大值就是堆顶的根节点
- 将其与末尾元素进行交换,末尾就为最大值
- 将剩余n-1个元素重新构造成一个堆,反复这个过程。
- 堆排的时间复杂度为O(nlogn)
堆排的详细内容可以参考:
https://blog.csdn.net/mango_12345/article/details/115734730?spm=1001.2014.3001.5501
6.堆的应用
堆的应用有topK问题。详细可以参考:
https://blog.csdn.net/mango_12345/article/details/115771696?spm=1001.2014.3001.5501
丑数问题
数据流中的中位数
7.python中的内置堆函数
python中有内置的小顶堆模块。heapq
构建一个小顶堆
import heapq
heap = [2,3,4,5,1,6,7]
heapq.heapify(heap)
# 输出 heap = [1, 2, 4, 5, 3, 6, 7]
删除堆顶元素
弹出并返回最小元素,保持堆的性质不变
c = heapq.heappop(heap)
# c=1
# 此时heap变为heap = [2, 3, 4, 5, 7, 6]
向堆中插入元素,保持堆的性质不变
heapq.heappush(heap,3)
# heap = [1, 2, 4, 3, 3, 6, 7, 5]
堆中最小的3个数
c = heapq.nsmallest(3,heap)
# c = [1, 2, 3]
堆中最大的3个数
c = heapq.nlargest(3,heap)
# c = [7, 6, 5]