堆排序
堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。
- 时间复杂度O(N*logN)
- 空间复杂度O(1)
- 不稳定排序:比如一个数组222,我们建立大根堆时,堆顶元素会换到最后的位置上去,导致第一个2排序后跑到了最后面,破坏了数据的稳定性。
算法的原理
首先是把数组建中的N个数建成一个大小为N的大根堆,堆顶元素数树的最大值,将堆顶元素与堆的最后一个元素进行位置互换,然后把最大值脱离出堆结构,放在数组的最后位置,作为数组的有序部分;然后对n-1的堆进行位置调整,把最大值放在堆顶;再重复堆顶数据与堆的最后一位进行位置交换,存入有效部分,当堆的大小为1的时候,数据就变得有序了。
Python实现
# 堆排序
def heapify(arr, n, i):
# 根节点序号
largest = i
# 计算子根节点序号
l = 2 * i + 1 # left = 2*i + 1
r = 2 * i + 2 # right = 2*i + 2
# 判断左子树是否存在
if l < n and arr[i] < arr[l]:
largest = l
# 判断右子树是否存在
if r < n and arr[largest] < arr[r]:
largest = r
# 最大的节点序号 不等于 根节点的序号时,
if largest != i:
arr[i], arr[largest] = arr[largest], arr[i] # 交换
heapify(arr, n, largest)
def heapSort(arr):
n = len(arr)
# Build a maxheap.
# 按叉树层遍历的 生产二叉树
# 构建大堆
for i in range(n, -1, -1):
heapify(arr, n, i)
print(arr, i)
# 一个个交换元素
for i in range(n - 1, 0, -1):
arr[i], arr[0] = arr[0], arr[i] # 交换
heapify(arr, i, 0)
return arr
if __name__ == "__main__":
print(heapSort([45, 32, 8, 33, 12, 22, 19, 97]))