本文主要是介绍排序算法之堆排序详细解读(附带Java代码解读),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
堆排序(Heap Sort)是一种基于比较的排序算法,它利用堆数据结构来排序元素。堆是一种特殊的完全二叉树,堆排序的基本思想是将数组构建成一个最大堆(或最小堆),然后通过交换根节点和堆的最后一个元素,将最大(或最小)元素移到数组的末尾。接着,调整堆,使其重新满足堆的性质,然后重复这一过程直到排序完成。
算法思想
- 构建最大堆:将无序数组构建成一个最大堆。最大堆的特性是每个节点的值都大于或等于其子节点的值。
- 提取最大元素:将堆顶(最大元素)与堆的最后一个元素交换,然后将堆的有效大小减小 1。对交换后的堆进行调整,以保持最大堆的性质。
- 重复步骤 2:直到堆的有效大小为 1,整个数组已经排序完成。
过程示例
假设有一个待排序的数组:[4, 10, 3, 5, 1]
步骤 1: 构建最大堆
将数组构建成最大堆:
- 初始数组:[4, 10, 3, 5, 1]
- 从最后一个非叶子节点开始向上调整:
- 调整节点 10:[10, 5, 3, 4, 1]
- 调整节点 4:[10, 5, 4, 3, 1]
步骤 2: 提取最大元素
将堆顶(最大元素 10)与堆的最后一个元素交换,然后调整堆:
- 交换:[1, 5, 4, 3, 10]
- 调整堆:[5, 3, 4, 1, 10]
- 交换堆顶和最后一个元素后,堆变成:[5, 3, 4, 1],最大元素 10 已经放在正确位置
重复上述步骤:
- 交换堆顶和最后一个元素:[1, 3, 4, 5, 10]
- 调整堆:[4, 3, 1, 5, 10]
- 交换堆顶和最后一个元素:[1, 3, 4, 5, 10]
- 调整堆:[3, 1, 4, 5, 10]
- 交换堆顶和最后一个元素:[1, 3, 4, 5, 10]
- 调整堆:[1, 3, 4, 5, 10],最终数组为:[1, 3, 4, 5, 10]
算法复杂度
-
时间复杂度:
- 最坏情况: O(n log n)
- 平均情况: O(n log n)
- 最佳情况: O(n log n)
-
空间复杂度: O(1) 堆排序是原地排序算法,不需要额外的存储空间。
优点
- 原地排序:只需要常数级别的额外空间。
- 时间复杂度优良:最坏情况时间复杂度为 O(n log n),适合大数据量的排序。
缺点
- 不稳定排序:相等元素的相对顺序可能会改变。
- 实现较复杂:相较于其他排序算法(如插入排序),堆排序的实现较复杂。
Java代码解读
public class HeapSort {// 主方法:执行堆排序public static void heapSort(int[] arr) {int n = arr.length;// 构建最大堆for (int i = n / 2 - 1; i >= 0; i--) {heapify(arr, n, i);}// 提取元素并调整堆for (int i = n - 1; i > 0; i--) {// 将当前堆顶(最大值)交换到数组末尾int temp = arr[0];arr[0] = arr[i];arr[i] = temp;// 调整堆heapify(arr, i, 0);}}// 调整堆的函数private static void heapify(int[] arr, int n, int i) {int largest = i; // 初始化最大元素为根节点int left = 2 * i + 1; // 左子节点索引int right = 2 * i + 2; // 右子节点索引// 如果左子节点大于根节点if (left < n && arr[left] > arr[largest]) {largest = left;}// 如果右子节点大于根节点if (right < n && arr[right] > arr[largest]) {largest = right;}// 如果最大元素不是根节点if (largest != i) {int swap = arr[i];arr[i] = arr[largest];arr[largest] = swap;// 递归地调整被替换子节点的堆heapify(arr, n, largest);}}public static void main(String[] args) {int[] arr = {4, 10, 3, 5, 1};System.out.println("排序前的数组:");for (int num : arr) {System.out.print(num + " ");}System.out.println();heapSort(arr);System.out.println("排序后的数组:");for (int num : arr) {System.out.print(num + " ");}}
}
代码说明
-
heapSort方法:
heapSort
方法首先构建最大堆,然后逐步将最大元素移到数组末尾,并调整堆。
-
heapify方法:
heapify
方法调整堆以保持最大堆的性质。- 它检查节点的左子节点和右子节点,将最大元素移动到根节点,并递归地调整被替换子节点的堆。
-
main方法:
- 创建一个待排序的数组
arr
。 - 调用
heapSort
方法对数组进行排序。 - 输出排序前和排序后的数组。
- 创建一个待排序的数组
这篇关于排序算法之堆排序详细解读(附带Java代码解读)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!