堆排序(Heap Sort)是一种基于比较的排序算法,它利用堆这种数据结构对一组数据进行排序。堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子节点的键值或索引总是小于(或者大于)它的父节点。
堆排序算法可以分为两个大的步骤:
- 建立堆:将无序的输入数据构造成一个最大堆或最小堆。
- 重复提取堆顶元素:将堆顶元素(最大或最小值)与堆的最后一个元素交换,然后破坏堆结构,通过调整使其重新满足堆的性质,重复这个过程直到堆中只剩下一个元素。
Python算法实现
下面是一个Python实现的堆排序算法:
def heapify(arr, n, i):largest = ileft = 2 * i + 1right = 2 * i + 2# 如果左子节点大于根节点if left < n and arr[i] < arr[left]:largest = left# 如果右子节点比最大的还大if right < n and arr[largest] < arr[right]:largest = right# 如果最大的不是根节点if largest != i:arr[i], arr[largest] = arr[largest], arr[i] # 交换heapify(arr, n, largest)
def heapSort(arr):n = len(arr)# 构建最大堆for i in range(n // 2 - 1, -1, -1):heapify(arr, n, i)# 一个个从堆顶取出元素for i in range(n - 1, 0, -1):arr[i], arr[0] = arr[0], arr[i] # 交换heapify(arr, i, 0)
# 示例
arr = [12, 11, 13, 5, 6, 7]
heapSort(arr)
n = len(arr)
print("排序后的数组:")
for i in range(n):print("%d" % arr[i], end=' ')
应用场景
堆排序算法的时间复杂度为平均O(n log n),在最坏的情况下也是O(n log n),这是一个相当高效的排序算法。堆排序是不稳定的排序算法,因为它会改变相同元素之间的相对顺序。
堆排序适用于:
- 需要对大量数据进行排序的场景。
- 数据量不大,但是数据分布范围广,或者数据具有特定分布规律,例如数据已经部分有序。
- 当内存空间不是特别受限时,因为堆排序需要将数据存储在数组中,并且会进行多次的数组遍历和调整。
堆排序不适合: - 内存使用非常受限的场景,因为堆排序需要一个额外的数组来存储堆结构。
- 数据量非常小,因为堆排序的 overhead 相对较高,对于很少的数据来说,其他更简单的排序算法可能更有效。
- 对稳定性有特殊要求的场景,如果相同元素的相对顺序重要,则应该考虑其他稳定的排序算法,如冒泡排序或插入排序。