def heap_sort(arr):
max_index = len(arr) - 1
# 构建大顶堆,0位置上为最大值
heap_swift(arr, 0, max_index)
# end_index 为每次得到最大值后,最大值应该放的位置
for end_index in range(1, max_index + 1).__reversed__():
# 将得到的当前0位置上最大值,交换到它应该放的位置
swap_elem(arr, 0, end_index)
# 在剩下的元素里面比较得出最大值
swift_node(arr, 0, end_index - 1)
def heap_swift(arr, start_index, end_index):
last_non_leaf_index = (len(arr) - 1) // 2
for i in range(start_index, last_non_leaf_index + 1).__reversed__():
# 自底向上遍历非叶子节点,调整各自和孩子的位置
swift_node(arr, i, end_index)
def swift_node(arr, node_index, end_index):
left_child_index = 2 * node_index + 1
while left_child_index <= end_index:
right_child_index = left_child_index + 1
max_child_index = left_child_index # 最大孩子节点索引
if right_child_index <= end_index and arr[left_child_index] < arr[right_child_index]:
max_child_index = right_child_index
if arr[max_child_index] > arr[node_index]: # 最大child节点值比自己大,需要调整
swap_elem(arr, max_child_index, node_index)
node_index = max_child_index
left_child_index = 2 * node_index + 1
else:
# 节点无需和自己child节点比较了,可以终止循环
break