堆排序
原理
堆的向下调整图形化:
代码实现:
def sift(li, low, high):
i = low # 根节点
temp = li[i]
j = 2*i + 1 # 左孩子节点
while j <= high:
if j + 1 < high and li[j + 1] > li[j]: # 防止右孩子节点溢出,如果右孩子节点大于左孩子节点,则右孩子节点接替父节点
j = j + 1 # j指向右孩子节点
if temp < li[j]: # 如果当前i指向的要小于j指向的孩子节点,则孩子节点上位
li[i] = li[j]
# 往下看一层
i = j
j = 2*i + 1
else:
li[i] = temp # 此时树结构中temp不存在,需要把temp放回来 (在树的上面放)
break
else:
li[i] = temp # 此时树结构中temp不存在,需要把temp放回来 (在树的最底层放)
def heap_sort(li):
n = len(li)
# 生成堆
for i in range((n-2)//2, -1, -1):
# 子树向下调整
sift(li, i, n-1)
# 排序
for i in range(n-1, -1, -1):
li[0], li[i] = li[i], li[0] # 节约内存,堆顶与最后一个元素互换
sift(li, 0, i-1) # 此时最后一个元素应该是i-1,因为第i个是暂存堆顶的元素
Li = [5, 2, 4, 6, 1, 3]
heap_sort(Li)
print(Li)
参考:
https://www.bilibili.com/video/BV1uA411N7c5?p=25