【排序 - 堆排序】

堆排序(Heap Sort)是一种高效的排序算法,利用了堆这种数据结构的特性。堆排序的时间复杂度为 O(n log n),并且是一个原地排序算法,不需要额外的存储空间。

堆的基本概念

堆是一种特殊的树形数据结构,分为最大堆和最小堆两种类型:

  • 最大堆:父节点的值大于或等于任何一个子节点的值。
  • 最小堆:父节点的值小于或等于任何一个子节点的值。

堆排序利用了最大堆的性质来进行升序排序,具体过程如下:
在这里插入图片描述

堆排序算法步骤

  1. 构建最大堆

    • 将待排序的数组看作是一个完全二叉树,通过调整部分节点的值,使得整个树满足最大堆的性质。
  2. 堆化数组

    • 从数组的中间位置开始,逐步向前调整,使得每个父节点都大于等于其子节点,从而得到一个最大堆。
  3. 排序

    • 将堆顶元素(最大值)与堆的最后一个元素交换位置,然后重新调整堆,除去最后一个元素,再次形成最大堆。重复这个过程,直到整个数组排序完成。

C语言实现

下面是用C语言实现堆排序的代码示例:

#include <stdio.h>

// 交换数组中两个元素的值
void swap(int* a, int* b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

// 调整堆,使得以root为根节点的子树满足最大堆的性质
void heapify(int arr[], int n, int root) {
    int largest = root;  // 初始化根节点为最大值
    int left = 2 * root + 1;  // 左子节点
    int right = 2 * root + 2; // 右子节点

    // 如果左子节点大于根节点,则更新最大值的索引
    if (left < n && arr[left] > arr[largest])
        largest = left;

    // 如果右子节点大于当前的最大值,则更新最大值的索引
    if (right < n && arr[right] > arr[largest])
        largest = right;

    // 如果最大值不是根节点,则交换并递归调整堆
    if (largest != root) {
        swap(&arr[root], &arr[largest]);
        heapify(arr, n, largest);
    }
}

// 堆排序函数
void heap_sort(int arr[], int n) {
    // 构建最大堆(从最后一个非叶子节点开始向前调整)
    for (int i = n / 2 - 1; i >= 0; i--)
        heapify(arr, n, i);

    // 从堆顶开始将元素逐个移出堆
    for (int i = n - 1; i > 0; i--) {
        // 将堆顶元素(最大值)与当前堆的最后一个元素交换位置
        swap(&arr[0], &arr[i]);

        // 重新调整堆,排除最后一个元素
        heapify(arr, i, 0);
    }
}

int main() {
    int arr[] = {12, 11, 13, 5, 6, 7};
    int n = sizeof(arr) / sizeof(arr[0]);

    printf("排序前:");
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");

    heap_sort(arr, n);

    printf("排序后:");
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");

    return 0;
}

代码解释

  • swap 函数用于交换数组中两个元素的值。
  • heapify 函数用于调整堆,使得以指定根节点为起点的子树满足最大堆的性质。
  • heap_sort 函数首先构建最大堆,然后逐步将堆顶元素(最大值)与堆的末尾元素交换,再重新调整堆,最终完成排序。

时间复杂度

堆排序的时间复杂度为 O(n log n),空间复杂度为 O(1),是一个原地排序算法,适合处理大规模数据的排序问题。

总结

堆排序利用堆这种数据结构的特性,通过构建最大堆和不断调整堆的过程来实现排序。它的时间复杂度稳定在 O(n log n),并且适用于大数据量的排序需求。通过本文,我们深入了解了堆排序的原理和实现方式,并通过C语言代码展示了如何实现堆排序算法。对于理解高效排序算法和算法设计有着重要的帮助。

相关推荐

  1. 排序!!

    2024-07-11 16:34:05       25 阅读
  2. 排序排序

    2024-07-11 16:34:05       55 阅读
  3. 排序算法-排序

    2024-07-11 16:34:05       34 阅读
  4. [排序算法]排序

    2024-07-11 16:34:05       95 阅读
  5. 选择排序排序

    2024-07-11 16:34:05       53 阅读
  6. 排序算法】之排序

    2024-07-11 16:34:05       62 阅读
  7. 九、算法-排序-排序

    2024-07-11 16:34:05       32 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-11 16:34:05       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-11 16:34:05       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-11 16:34:05       58 阅读
  4. Python语言-面向对象

    2024-07-11 16:34:05       69 阅读

热门阅读

  1. 电商商城网站防护选购指南,高防CDN使用攻略

    2024-07-11 16:34:05       25 阅读
  2. [题解]P1113 杂务||拓扑排序板子题,但是dp求解

    2024-07-11 16:34:05       22 阅读
  3. PgMP考试报名攻略,不会的看这里!

    2024-07-11 16:34:05       24 阅读
  4. 高效利用iCloud指南

    2024-07-11 16:34:05       21 阅读
  5. 力扣面试经典150题

    2024-07-11 16:34:05       25 阅读
  6. MacOS 上安装和管理 Node.js

    2024-07-11 16:34:05       21 阅读
  7. C++ tcp中的可变长度结构体的序列化和反序列化

    2024-07-11 16:34:05       17 阅读
  8. RootViewController

    2024-07-11 16:34:05       21 阅读