1. 堆结构
大顶堆:每个结点的值都大于或等于其左右孩子结点的值,在堆排序算法中用于升序排列;
小顶堆:每个结点的值都小于或等于其左右孩子结点的值,在堆排序算法中用于降序排列
2. 堆排序
概念:利用堆的概念来排序的选择排序
平均复杂度:O(nlogn) 不稳定的算法
算法步骤:
- 创建一个堆 H[0……n-1];
- 把堆首(最大值)和堆尾互换;
- 把堆的尺寸缩小 1,并调用 shift_down(0),目的是把新的数组顶端数据调整到相应位置;
- 重复步骤 2,直到堆的尺寸为 1
3. 代码实现
import math
def buildMaxHeap(arr):
for i in range(math.floor(len(arr) / 2), -1, -1): # 从中间位置到初始位置
heapify(arr, i)
def heapify(arr, i):
left = 2 * i + 1 # 左孩子位置
right = 2 * i + 2 # 右孩子位置
largest = i # 记录当前最大值(最小值)默认根部
if left < arrLen and arr[left] > arr[largest]:
largest = left # 左孩子大于根记录位置
if right < arrLen and arr[right] > arr[largest]:
largest = right # 右孩子大于根记录位置
if largest != i:
swap(arr, i, largest) # 交换
heapify(arr, largest) # 递归
def swap(arr, i, j):
arr[i], arr[j] = arr[j], arr[i]
def heapSort(arr):
global arrLen
arrLen = len(arr)
buildMaxHeap(arr) # 构造完最大堆(最小堆)
for i in range(len(arr) - 1, 0, -1): #
swap(arr, 0, i) # 将最大值放到最后
arrLen -= 1 # 长度减一
heapify(arr, 0) # 重新构造堆
return arr
if __name__ == '__main__':
arr = [1, 5, 2, 10, 4, 9, 3, 7, 6, 0]
print(heapSort(arr))