在数据结构与算法的世界里,树是一种非常重要且基础的数据结构,它模拟了自然界中树的层次结构,被广泛应用于各种领域。而堆作为树的一种特殊形式,更是在排序、优先队列等场景中发挥着关键作用。本文将深入探讨树、堆的定义以及堆排序算法。
树是由 n(n >= 0)个节点组成的有限集合。当 n = 0 时,称为空树;当 n > 0 时,有一个特定的节点称为根节点,其余节点可以分为 m(m >= 0)个互不相交的有限集合,每个集合本身又是一棵树,称为根节点的子树。
堆是一种特殊的完全二叉树。完全二叉树是指除了最后一层外,每一层上的节点数均达到最大值;在最后一层上只缺少右边的若干节点。堆分为最大堆和最小堆。
由于堆是完全二叉树,所以通常使用数组来存储堆。对于数组中索引为 i 的节点,其左子节点的索引为 2 i + 1,右子节点的索引为 2 i + 2,其父节点的索引为 (i - 1) / 2(这里的除法是整数除法)。
堆排序利用了堆的特性,通过构建最大堆(或最小堆),将堆顶元素(最大值或最小值)与堆的最后一个元素交换,然后调整剩余元素重新构成堆,重复这个过程直到整个数组有序。
def heapify(arr, n, i):
largest = i
left = 2 * i + 1
right = 2 * i + 2
if left < n and arr[left] > arr[largest]:
largest = left
if right < n and arr[right] > arr[largest]:
largest = right
if largest!= i:
arr[i], arr[largest] = arr[largest], arr[i]
heapify(arr, n, largest)
def heap_sort(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[0], arr[i] = arr[i], arr[0]
heapify(arr, i, 0)
return arr
# 测试
arr = [12, 11, 13, 5, 6, 7]
sorted_arr = heap_sort(arr)
print("排序后的数组:", sorted_arr)
概念 | 描述 |
---|---|
树 | 由节点组成的有限集合,有根节点和子树 |
堆 | 特殊的完全二叉树,分为最大堆和最小堆 |
最大堆 | 节点值大于或等于子节点值,根节点为最大值 |
最小堆 | 节点值小于或等于子节点值,根节点为最小值 |
堆排序 | 利用堆的特性进行排序,时间复杂度 $O(n log n)$,空间复杂度 $O(1)$ |
通过本文的介绍,我们了解了树、堆的定义以及堆排序算法。堆排序作为一种高效的排序算法,在实际应用中具有重要的价值。希望读者能够掌握堆排序的原理和实现,在实际编程中灵活运用。