堆排序
- 不稳定排序,时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)
堆排序的特点是利用了数据结构中的堆。
堆是一种完全二叉树,将根节点大的堆叫做大根堆,根节点小的堆叫做小根堆。这里我用大根堆来进行演示,如下图所式,就是一个大根堆。
步骤:
- 首先取出根结点7
- 将4移动到7原来的位置,重新构造堆
- 然后再取出根结点的数字,再重新构造堆,依次进行,直到堆变空为止,排序完成。
实现代码
def heapify(tree,n,i):
# 对堆的第i个结点,进行重构堆
c1 = 2*i + 1 # 第i个结点的子结点1
c2 = 2*i + 2 # 第i个结点的子结点2
max_index = i # 假设根结点i的值是最大的
while c1 < n and tree[max_index] < tree[c1]: # 如果子结点的值 大于 根结点的值,则将子结点的下标 置成最大下标
max_index = c1
while c2 < n and tree[max_index] < tree[c2]:
max_index = c2
if i != max_index:
tree[max_index],tree[i] = tree[i],tree[max_index]
heapify(tree,n,max_index)
def build_heap(tree,n):
# 对一个列表 按照 大根堆 进行排列
last_node = n-1 # 最后一个结点
p = int((last_node-1)/2) # last_node的父结点
for i in range(p,-1,-1):
heapify(tree,n,i) # 从下往上,依次对结点,按照堆的顺序排列
def heap_sort(tree,n):
build_heap(tree,n)
for i in range(n-1,-1,-1):
tree[i],tree[0] = tree[0],tree[i] # 将 根结点 取出
heapify(tree,i,0) # 对 根结点 重构堆
if __name__ == "__main__":
arr = [15,8,32,42,25,41]
heap_sort(arr,len(arr))
print("排序之后:",arr)