堆排序——C语言实现

server/2024/12/28 16:39:56/

1. 代码结构概述

  • 核心功能:将数组中的元素按照升序排列。
  • 主要步骤
    1. 构建最大堆:将输入数组组织成最大堆(每个节点的值都大于或等于其子节点)。
    2. 堆排序:每次将堆顶(最大值)移到数组末尾,然后调整剩下的部分为最

2. 函数解析

(1) refresh 函数

作用:从指定节点开始调整堆,使其满足最大堆的性质。

void refresh(int array[], int start, int range) {int largest = start;           // 当前节点位置while (largest * 2 + 1 < range) { // 当存在子节点int left = largest * 2 + 1;   // 左子节点int right = largest * 2 + 2;  // 右子节点int maxChild = left;          // 假设左子节点是最大的// 如果右子节点存在且值更大,则更新最大子节点if (right < range && array[right] > array[left]) {maxChild = right;}// 如果当前节点比最大子节点还大,退出调整if (array[largest] >= array[maxChild]) {break;}// 交换当前节点和最大子节点int temp = array[largest];array[largest] = array[maxChild];array[maxChild] = temp;// 更新节点位置,继续向下调整largest = maxChild;}
}

(2) Heap_sort 函数

作用:实现堆排序的完整流程。

void Heap_sort(int array[], int size) {// (1) 构建最大堆for (int i = size / 2 - 1; i >= 0; i--) { // 从最后一个非叶节点开始refresh(array, i, size);             // 调整堆结构}// (2) 排序for (int i = size - 1; i > 0; i--) {    // 从数组末尾逐步移除最大元素// 将堆顶(最大值)与当前范围的最后一个元素交换int temp = array[0];array[0] = array[i];array[i] = temp;// 调整剩余部分为最大堆refresh(array, 0, i);}
}

3. 主函数 main

作用:测试堆排序算法

 
int main(void) {int array[maxsize] = {3, 5, 7, 9, 1, 4, 2, 6, 8, 0}; // 初始化数组Heap_sort(array, maxsize);                          // 调用堆排序// 输出排序后的数组for (int i = 0; i < maxsize; i++) {printf("%d ", array[i]);}return 0;
}

4. 运行过程

假设输入数组为 {3, 5, 7, 9, 1, 4, 2, 6, 8, 0}

(1) 构建最大堆

通过从最后一个非叶节点向上调整,最终堆变成:

          9/     \8       7/ \     / \6   5   4   2/3

数组形式为:{9, 8, 7, 6, 5, 4, 2, 3, 1, 0}


(2) 排序
  1. 交换堆顶和数组最后一个元素:

    • 结果:{0, 8, 7, 6, 5, 4, 2, 3, 1, 9}
    • 调整剩余部分为堆:
              8/     \6       7/ \     / \3   5   4   2/
      0
      
      数组:{8, 6, 7, 3, 5, 4, 2, 0, 1, 9}
  2. 重复上述过程,每次将堆顶移到未排序部分的末尾,并调整剩余堆。

最终结果:{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}


5. 时间复杂度

  • 建堆O(n)
  • 排序O(n log n)(每次调整堆的复杂度为 O(log n),需要调整 n 次)。
  • 总复杂度O(n log n)

6. 空间复杂度

堆排序是原地排序算法,不需要额外的数组存储数据,空间复杂度为 O(1)


7. 总结

这段代码实现了标准的堆排序算法,具有以下特点:

  • 稳定性:堆排序是不稳定排序(相同值的元素相对顺序可能改变)。
  • 效率:适合对大规模数据进行排序。
  • 应用场景:适用于对内存有限的环境中进行高效排序。

 


http://www.ppmy.cn/server/153962.html

相关文章

【国产NI替代】基于FPGA的32通道(24bits)高精度终端采集核心板卡

32通道&#xff08;24bits&#xff09;高精度终端采集核心板卡 采用 EP4CE115F29I7 型号的 FPGA &#xff0c;是一款 高精度&#xff0c;多通道动态信号采集核心板&#xff0c;核心 板主要分为 2 块板卡&#xff0c;一块为通讯板&#xff0c;一块 为采集板&#xff0c;均有 …

分享一下使用 AI 开发个人工具的迭代过程

分享一下使用 AI 开发个人工具的迭代过程&#xff1a;1. 找 gpt/claude 要一个 super shady coder 的人设 prompt&#xff1b;2. 简单介绍项目背景和基础需求给 gemini&#xff0c;生成最初的细化需求&#xff1b;3. 根据细化需求再次分析&#xff0c;完善边界条件&#xff0c;…

第十九章 C++ 日期 时间

C 日期 & 时间 C 标准库没有提供所谓的日期类型。C 继承了 C 语言用于日期和时间操作的结构和函数。为了使用日期和时间相关的函数和结构&#xff0c;需要在 C 程序中引用 <ctime> 头文件。 有四个与时间相关的类型&#xff1a;clock_t、time_t、size_t 和 tm。类型…

使用 Rust 和 wasm-pack 开发 WebAssembly 应用

一、什么是 WebAssembly&#xff1f; WebAssembly 是一种运行在现代 Web 浏览器中的新型二进制指令格式。它是一种低级别的字节码&#xff0c;可以被多种语言编译&#xff0c;并在浏览器中高效运行。 1.1 WebAssembly 的背景与概念 高性能计算&#xff1a;WebAssembly 旨在提…

NAT 技术如何解决 IP 地址短缺问题?

NAT 技术如何解决 IP 地址短缺问题&#xff1f; 前言 这是我在这个网站整理的笔记,有错误的地方请指出&#xff0c;关注我&#xff0c;接下来还会持续更新。 作者&#xff1a;神的孩子都在歌唱 随着互联网的普及和发展&#xff0c;IP 地址的需求量迅速增加。尤其是 IPv4 地址&…

Odoo 免费开源 ERP:通过 JavaScript 创建对话框窗口的技术实践分享

作者 | 老杨 出品 | 上海开源智造软件有限公司&#xff08;OSCG&#xff09; 概述 在本文中&#xff0c;我们将深入研讨如何于 Odoo 18 中构建 JavaScript&#xff08;JS&#xff09;对话框或弹出窗口。对话框乃是展现重要讯息、确认用户操作以及警示用户留意警告或错误的行…

新浪微博大数据面试题及参考答案(数据开发和数据分析)

介绍一下你所掌握的计算机网络和操作系统相关知识 计算机网络:计算机网络是将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。我掌握了网络协议…

动手学深度学习-深度学习计算-1层和块

目录 自定义块 顺序块 在前向传播函数中执行代码 效率 小结 之前首次介绍神经网络时&#xff0c;我们关注的是具有单一输出的线性模型。 在这里&#xff0c;整个模型只有一个输出。 注意&#xff0c;单个神经网络 &#xff08;1&#xff09;接受一些输入&#xff1b; &am…