返回
堆排序:一种高效的原地排序算法
Android
2023-10-09 06:07:41
堆排序原理
堆排序的基本思想是将待排序序列转化为一个大顶堆 (堆中每个节点的值都大于或等于其子节点的值),然后依次弹出堆顶元素,并将其插入到已排序序列的末尾。这个过程不断重复,直到堆中只剩下一个元素。
堆化 是堆排序的核心步骤,它将一个无序序列转化为一个大顶堆。具体操作如下:
- 将待排序序列的最后一个元素与根节点交换位置。
- 调整根节点,使其满足大顶堆性质(父节点的值大于等于子节点的值)。
- 重复步骤2和步骤3,直到调整完毕。
与选择排序的比较
堆排序与选择排序都属于原地排序算法,它们的元素交换次数相同,但它们在效率上有显着差异。堆排序的平均时间复杂度为O(n log n),而选择排序的时间复杂度为O(n^2)。
堆排序优于选择排序的原因在于:
- 堆排序对数据进行了部分排序,而选择排序每次只能找出序列中的一个最小(或最大)元素。
- 堆排序在堆化过程中利用了堆的特性,可以高效地找到要交换的元素。
代码实现
def heap_sort(arr):
"""堆排序算法"""
# 1. 构建大顶堆
for i in range(len(arr) // 2 - 1, -1, -1):
heapify(arr, i, len(arr))
# 2. 依次弹出堆顶元素
for i in range(len(arr) - 1, 0, -1):
# 交换堆顶元素和最后一个元素
arr[0], arr[i] = arr[i], arr[0]
# 重新堆化
heapify(arr, 0, i)
def heapify(arr, i, n):
"""维护堆性质"""
# 左子节点的索引
left = 2 * i + 1
# 右子节点的索引
right = 2 * i + 2
# 寻找最大值索引
max_index = i
if left < n and arr[left] > arr[max_index]:
max_index = left
if right < n and arr[right] > arr[max_index]:
max_index = right
# 若最大值索引不是根节点,则交换并继续堆化
if max_index != i:
arr[i], arr[max_index] = arr[max_index], arr[i]
heapify(arr, max_index, n)
总结
堆排序是一种高效的原地排序算法,它利用堆的特性进行排序。它在效率上优于选择排序,并且在实际应用中得到了广泛的应用。