参考:
https://blog.csdn.net/weixin_42109012/article/details/91668543
https://blog.csdn.net/sunxianghuang/article/details/51872360
堆
堆分为大根堆和小根堆,是完全二叉树。大根堆的要求是每个节点的值都不大于其父节点的值,即A[PARENT[i]]>=A[i]。在数组的非降序排序中,需要使用的就是大根堆,因为根据大根堆的要求而知,最大的值一定在堆顶。最小堆通常在构造优先队列时使用。
堆排序
基本思想:
首先通过自底向上的调整堆来建立大根树,然后依次将最大值a[0]与末尾元素交换并调整交换后的堆(大小减1)
代码:
def down(s, node, end): # s是列表,node是父节点,end是列表长度
"""从上面到下面判断是否符合大顶堆,不符合就交换"""
root = node # 父节点
child = 2 * root + 1 # 子节点
while child < end:
if s[child] < s[child + 1] and (child + 1) < end: # 找出较大的子节点
child += 1
if s[child] > s[root]: # 如果子节点大于父节点,交换
s[child], s[root] = s[root], s[child]
root = child
child = child * 2 + 1
def BuildHeap(s, size):
"""从倒数第二排的非叶子节点开始创建大顶堆"""
for i in range(size // 2 - 1, -1, -1):
down(s, i, size)
def HeapSort(s, size):
BuildHeap(s, size)
for i in range(size - 1, 0, -1):
s[0], s[i] = s[i], s[0]
down(s, 0, i)
s1 = [49, 38, 65, 97, 76, 13, 27, 49, 10]
print(f'排序前:{s1}')
size1 = len(s1)
HeapSort(s1, size1)
print(f'排序后:{s1}')
结果
算法复杂度