当前位置: 首页 > article >正文

堆排序算法

目录

  • 1.基本原理
  • 2.例子
  • 3.代码实现

本文主要介绍堆排序的原理、例子以及代码实现。

1.基本原理

堆排序(Heap Sort)是一种基于比较的排序算法,它的工作原理是首先将待排序的序列构造成一个大顶堆或小顶堆,然后交换堆顶元素和最后一个元素,然后将剩余元素重新调整为大顶堆或小顶堆,再交换堆顶元素和最后一个元素,如此反复,直到所有元素都排好序。

堆排序的步骤如下:

  1. 构造大顶堆(或小顶堆),对于每一个非叶子节点,保证其值大于(或小于)其子节点的值。
  2. 将堆顶元素与最后一个元素交换,然后将剩余元素重新调整为大顶堆(或小顶堆)。
  3. 重复步骤2,直到所有元素都排好序。

堆排序的时间复杂度为O(nlogn),空间复杂度为O(1)。

2.例子

假设我们有一个待排序的数组 [4, 10, 3, 5, 1],我们想要对其进行升序排序,可以使用堆排序,具体步骤如下:

  1. 首先,我们将数组构造成一个大顶堆。大顶堆是一种满足父节点的值大于或等于其子节点值的二叉树。构造大顶堆后,数组变为 [10, 5, 3, 4, 1]。
  2. 然后,我们将堆顶元素(即当前最大的元素10)与最后一个元素1交换位置,然后将剩余的元素(即除去最后一个元素的其他元素)重新调整为大顶堆。交换并调整后,数组变为 [5, 4, 3, 1] 和 [10]。
  3. 我们再次将堆顶元素5与最后一个元素1交换位置,然后将剩余的元素重新调整为大顶堆。交换并调整后,数组变为 [4, 1, 3]、[5, 10]。
  4. 重复上述步骤,直到所有元素都排好序,最终得到的数组为 [1, 3, 4, 5, 10]。

以上就是一个堆排序的具体例子。

3.代码实现

以下是堆排序的C语言实现:

#include <stdio.h>

void swap(int *a, int *b) {
    int t = *a;
    *a = *b;
    *b = t;
}

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], &arr[largest]);
        heapify(arr, n, largest);
    }
}

void heapSort(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);
    }
}

void printArray(int arr[], int n) {
    for (int i=0; i<n; ++i)
        printf("%d ", arr[i]);
    printf("\n");
}

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

    heapSort(arr, n);

    printf("Sorted array is \n");
    printArray(arr, n);
}

在这段代码中,heapify 函数用于构造大顶堆,heapSort 函数用于进行堆排序,swap 函数用于交换两个元素的值,printArray 函数用于打印数组。


http://www.kler.cn/a/154950.html

相关文章:

  • 23种设计模式的Flutter实现第一篇创建型模式(一)
  • 【数学二】线性代数-二次型
  • k8s 1.28.2 集群部署 docker registry 接入 MinIO 存储
  • SQL 注入详解:原理、危害与防范措施
  • 【Excel】ToRow超级查找函数
  • Tomcat 和 Netty 的区别及应用场景分析
  • 选股的重要性、考虑的因素
  • MySQL-视图
  • 【学习笔记】GAN实战(基础)
  • 动态规划学习——回文串
  • day4 找到两个链表的交点
  • 用友U8 ERP和面粉行业专版系统接口集成方案
  • 国产AI边缘计算盒子,双核心A55丨2.5Tops算力
  • 怎么用SSH远程连接Ubuntu服务器
  • 【Unity动画】状态机添加参数控制动画切换(Animator Controller)
  • C# WPF上位机开发(计算器界面设计)
  • Oracle连接和使用
  • Java高级技术-反射
  • 02_线程通信与线程池
  • H265、VP9、AV1视频编码器性能对比
  • 22.Oracle中的临时表空间
  • 短线买入卖出有哪些交易技巧?
  • Sailfish OS 移动操作系统
  • C/C++内存管理(含C++中new和delete的使用)
  • 优化机器学习:解析数据归一化的重要性与应用
  • Git 合并冲突解决步骤