堆的特点
堆其实是一种完全二叉树,从上到下从左到右,大顶堆的父节点大于其左右子节点,小顶堆的父节点小于其左右子节点
步骤
(1):首先是进行Heapify,建立堆
(2):从下到上,从右到左的进行heapify构建有序的堆
(3):进行排序,将堆顶父节点和底层最右边的子节点互换,然后不断重复以上步骤
1:Heapify
def heapify(tree, n, i):
# n为树的长度, i为起始的父节点
if (i >= n): # 当i超过树的长度时跳出循环
return
c1 = 2*i + 1 # 左儿子
c2 = 2*i + 2 # 右儿子
max = i # 当前的父节点
if (c1 < n and tree[c1] > tree[max]): # 当是>时,大顶堆; 当是<时,小顶堆
max = c1
if (c2 < n and tree[c2] > tree[max]):
max = c2
if (max != i): # 当max和i不一样的时候才进行调换
tree[i], tree[max]=tree[max], tree[i]
heapify(tree, n, max)
2:build_heap
def build_heap(tree):
n = len(tree)
last_node = (n - 1)//2 # 最后的一个父节点
for i in range(last_node, -1, -1): # 从下到上,从右到左
heapify(tree, n, i)
3:heap_sort
def heap_sort(tree):
build_heap(tree) # 对于无序的数组先建立好大顶堆
for i in range(len(tree)-1, -1, -1): # 注意这里是len(tree)-1
tree[0], tree[i] = tree[i], tree[0]
heapify(tree, i, 0) # 注意,这里直接就是使用i当成树的长度
参考链接:
视频:av4719699320多分钟,讲解的很细,看完就都会了
堆排序的Python实现(附详细过程图和讲解),这个用链表来代替list
为什么堆排序是不稳定的
比如:3 27 36 27,
如果堆顶3先输出,则,第三层的27(最后一个27)跑到堆顶,然后堆稳定,继续输出堆顶,是刚才那个27,这样说明后面的27先于第二个位置的27输出,不稳定。