
在数据结构与算法的世界里,树是一种非常重要且基础的数据结构,它模拟了自然界中树的层次结构,被广泛应用于各种领域。而堆作为树的一种特殊形式,更是在排序、优先队列等场景中发挥着关键作用。本文将深入探讨树、堆的定义以及堆排序算法。
树是由 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 = ileft = 2 * i + 1right = 2 * i + 2if left < n and arr[left] > arr[largest]:largest = leftif right < n and arr[right] > arr[largest]:largest = rightif 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)$ |
通过本文的介绍,我们了解了树、堆的定义以及堆排序算法。堆排序作为一种高效的排序算法,在实际应用中具有重要的价值。希望读者能够掌握堆排序的原理和实现,在实际编程中灵活运用。