堆排序=放入+维护堆+取出
堆
顾名思义像个山包一样的,最(大,小)的放最上放
规则
从上到下,从左到右(你也可以随意)
然后维护最上放的数值是最(大,小)的,然后就是取出最(大,小)
然后再维护
解释不清自己http://wwwbaidu.com
代码:
def heapAdjust(li, s, m):
"""
将堆调整为大顶堆
"""
t = li[s]
j = 2 * s + 1 # 节点s的左孩子
while j < m:
# 将节点s的值较大孩子赋值给j
if j < m - 1 and li[j] < li[j + 1]:
j += 1
# 若节点s的值大于左右孩子,则跳出循环
if t >= li[j]:
break
li[s] = li[j] # 将孩子节点的值赋给当前节点
s = j
j = j * 2 + 1 # 继续递归迭代
li[s] = t # 将最初节点的值赋给最后得到的节点s
def heapSort(li):
"""
堆排序,属于选择排序类,不稳定排序
时间复杂度O(n*logn)
"""
n = len(li)
# 初始化大顶堆
for i in range(n // 2 - 1, -1, -1):
heapAdjust(li, i, n)
# 从后向前遍历数组,每次将堆顶最大值放置于位置i处
for i in range(n - 1, 0, -1):
li[0], li[i] = li[i], li[0] # 交换堆顶与待排序数组末尾位置i处,因为是-1的递减将最大值放入最后就不会在碰到
heapAdjust(li, 0, i) # 调整堆使其满足大顶堆
return li
if __name__ == '__main__':
li = [90, 10, 50, 80, 30, 70, 40, 60, 20]
print('堆排序:', heapSort(li.copy()))