侧边栏壁纸
博主头像
人生短短几个秋

行动起来,活在当下

  • 累计撰写 45 篇文章
  • 累计创建 20 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

堆排序

人生短短几个秋
2025-01-25 / 0 评论 / 0 点赞 / 11 阅读 / 0 字

堆排序(Heap Sort)

工作原理

堆排序是一种基于堆数据结构的比较排序算法。堆是一种特殊的完全二叉树结构,其中父节点的键总是大于或小于其子节点的键。堆排序利用最大堆(或最小堆)来逐步构建有序数组。

  1. 构建最大堆:将给定数组转换成最大堆。
  2. 移除最大元素:将堆顶元素(即最大元素)与堆的最后一个元素交换,并调整剩余的堆以保持最大堆的性质。
  3. 重复步骤2:不断移除最大元素并调整堆,直到堆为空。

Java实现

public class HeapSort {

    /**
     * 堆排序算法
     * @param arr 要排序的数组
     */
    public static void sort(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--) {
            // 移动当前根到数组末尾
            swap(arr, i, 0);

            // 调整剩余堆以保持最大堆的性质
            heapify(arr, i, 0);
        }
    }

    /**
     * 调整堆以保持最大堆的性质
     * @param arr 数组
     * @param n 堆的大小
     * @param i 当前节点的索引
     */
    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) {
            swap(arr, i, largest);
            // 递归调整受影响的子树
            heapify(arr, n, largest);
        }
    }

    /**
     * 交换数组中的两个元素
     * @param arr 数组
     * @param i 第一个元素的索引
     * @param j 第二个元素的索引
     */
    private static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    /**
     * 打印数组中的元素
     * @param arr 数组
     */
    public static void printArray(int[] arr) {
        for (int value : arr) {
            System.out.print(value + " ");
        }
        System.out.println();
    }

    /**
     * 主函数
     * @param args 命令行参数
     */
    public static void main(String[] args) {
        int[] sampleArray = {64, 34, 25, 12, 22, 11, 90};
        System.out.println("Original array:");
        printArray(sampleArray);

        sort(sampleArray);

        System.out.println("Sorted array:");
        printArray(sampleArray);
    }
}

代码解析

  1. sort() 方法:这是堆排序的核心实现。它接受一个整型数组作为参数,并对其进行排序。
  2. 构建最大堆:通过 heapify() 方法将数组转换成最大堆。
  3. 移除最大元素:将堆顶元素(即最大元素)与堆的最后一个元素交换,并调整剩余的堆以保持最大堆的性质。
  4. heapify() 方法:用于调整堆以保持最大堆的性质。
  5. swap() 方法:用于交换数组中的两个元素。
  6. printArray() 方法:用于打印数组中的元素。
  7. main() 方法:测试排序功能的方法。

注意事项

  • 时间复杂度:堆排序的时间复杂度为 O(n log n),无论是在最好、平均还是最坏情况下。
  • 稳定性:堆排序是不稳定的排序算法,因为相等的元素可能会在排序过程中改变它们原有的顺序。
  • 空间复杂度:堆排序的空间复杂度为 O(1),因为它不需要额外的存储空间。

适用场景

堆排序适用于大规模数据集的排序任务。由于其 O(n log n) 的时间复杂度,堆排序在处理大量数据时非常高效。此外,由于它是原地排序算法,所以在内存受限的情况下也非常有用。

希望这段代码及其说明能够帮助您更好地理解和实现堆排序算法。如果您有任何疑问或需要进一步的帮助,请随时告诉我。

0

评论区