在算法设计当中,我们经常会用到从一个序列重找到最大值和最小值的操作。比如前面算法系列提到的最短路径和最小生成树,如果我们采用这种暴力的顺序查找的方式,他的时间复杂度是 O ( n ) O(n) O(n)。
但是如果我们使用优先队列来查找最值得话,时间复杂度会降到 O ( n l o g n ) O(nlogn) O(nlogn)的时间。
- 堆可以看做是一棵完全二叉树的顺序存储结构,如果这棵树的父节点都大于他的左右孩子,称为最大堆。反之则称为最小堆。
- 完全二叉树的深度是 l o g 2 n log_{2}^n log2n,其中 n n n是元素总量。
python初始化最大堆
# coding=utf-8
# 初始化最大堆
def InitStack(input_stack):
n = len(input_stack)
print("数组长度:{}".format(n))
# 1.从n/2部分开始调整堆顶点
adjust_start = int(n / 2)
# 防止列表长度为偶数时,最后一个父节点没有右孩子
if n % adjust_start == 0:
input_stack.append(-1e12)
# 2.从后向前查找,检查当前顶点是否大于左右孩子
for i in reversed(range(adjust_start)):
while 2 * i+1 <= n:
max_child_index = 2 * i+1 if input_stack[2 * i+1] > input_stack[2 * i + 2] else 2 * i + 2
# 2.1 大于则不调整
if input_stack[i] >= input_stack[max_child_index]:
break
# 2.2 小于则与左右孩子的较大值交换(持续比较一直到大于左右孩子为止)
# 当前节点开始下沉
else:
input_stack[max_child_index], input_stack[i] = input_stack[i], input_stack[max_child_index]
i = max_child_index
# print(i)
input_stack.pop(n)
print("最大堆:{}".format(input_stack))
if __name__ == "__main__":
input_stack = [12, 16, 2, 30, 28, 22, 20, 6, 10, 18]
InitStack(input_stack)
还是没忍住推荐下这块APP,真的好用!看动态图比文字更好理解,附几张实景图,这是测试模式,点击一下就能算法运行一步,很人性化有木有!!!
算法动态图解:链接:https://pan.baidu.com/s/1mX3s7VjLTKLr7MZhAQO-6Q
提取码:cv5y