思维导图:
8.4.3 堆排序
堆排序(Heap Sort)是一种高效的排序算法,它把待排序的元素集视为一个完全二叉树的顺序存储结构。这种算法通过利用完全二叉树父节点与子节点之间的内在联系,从当前无序序列中选出关键字最大(或最小)的元素。堆排序的过程不仅高效而且具有很好的时间复杂度和稳定性。
堆的定义
在深入堆排序之前,我们首先需要理解堆的概念。一个包含n个元素的序列{ki},如果满足以下条件之一,则该序列构成一个堆:
- 对于任意给定的i(1 ≤ i ≤ n/2),都有ki ≥ k2i 且 ki ≥ k2i+1(构成大根堆);
- 或者,ki ≤ k2i 且 ki ≤ k2i+1(构成小根堆)。
这里,ki表示位于i位置的节点,k2i与k2i+1分别表示其左右子节点。如果以一维数组作为这个序列的存储结构,那么对应的数据结构在逻辑上可以被视为一个完全二叉树,其中所有非终端节点的值都不大于(或不小于)其子节点的值。
堆的示例
以关键字序列{96, 83, 27, 38, 11, 09}为例,该序列满足大根堆的条件,其对应的完全二叉树如图所示。类似地,序列{12, 36, 24, 85, 47, 30, 53, 91}构成小根堆。在这两种堆中,堆顶元素(即完全二叉树的根节点)必然是序列中的最大值或最小值。
堆排序的基本思想
堆排序算法的核心思想是利用大根堆或小根堆的性质——堆顶元素是序列中的最大或最小值。通过这个特性,我们可以轻松从当前的无序序列中选出最大或最小的记录。堆排序主要包括两个步骤:建立初始堆和调整堆。
建立初始堆
将待排序的序列调整为大根堆(或小根堆)。这个过程是堆排序的准备阶段,也是实现排序过程的基础。
调整堆
- 首先,交换根节点(即序列的第一个元素)与序列最后一个元素,此时序列的最后一个位置上的元素为最大(或最小)。
- 然后,将剩下的n-1个元素重新调整为大根堆,再次交换根节点与序列最后一个元素,此时倒数第二个位置上的元素为次大(或次小)。
- 重复以上步骤,直到整个序列变为非递减(或非递增)的有序序列。
通过上述步骤,堆排序能够有效地将一个无序序列转换为有序序列。重点在于掌握建立初始堆和调整堆的方法,这两个操作是堆排序成功的关键。