【排序 - 堆排序】

堆排序(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语言代码展示了如何实现堆排序算法。对于理解高效排序算法和算法设计有着重要的帮助。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3226772.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

用Racket做一个拼图游戏——4 实现工具

4 实现工具 思路理清楚了&#xff0c;接下来就一个一个功能实现。在阐述实现功能的编程过程中&#xff0c;会延伸讲解编程思路、相关的Racket函数及相关知识点&#xff0c;力图达到在实践中的学习目的。 在编程实现过程中&#xff0c;首先实现图片操作功能&#xff0c;再通过…

告别混乱,可道云企业网盘个人标签,让文件管理更轻松

在信息爆炸的时代&#xff0c;你是不是常常觉得自己的大脑就像一台过载的处理器&#xff0c;各种文件、资料、想法在脑海中“打架”&#xff0c;让你焦头烂额&#xff1f; 别担心&#xff0c;可道云企业网盘个人标签功能来拯救你的“大脑内存”了&#xff01; 我们需要告别无…

Python 轻松生成多种条形码、二维码 (Code 128、EAN-13、QR code等)

条形码和二维码是现代信息交换和数据存储的重要工具&#xff0c;它们将信息以图形的形式编码&#xff0c;便于机器识别和数据处理&#xff0c;被广泛应用于物流、零售、医疗、教育等各领域。 本文将介绍如何使用Python快速生成各种常见的条形码如Code 128、EAN-13&#xff0c;…

3DMAX卡死也要安装的10大插件

在探索3DMAX的无限创意边界时&#xff0c;有些插件如同星辰般璀璨&#xff0c;即便面对插件偶尔的“倔强”卡顿&#xff0c;设计师们依然对其爱不释手&#xff0c;誓要将其纳入麾下。以下便是那份令人心动的“卡死也要安装”的10大插件清单&#xff0c;每个都蕴含着设计师对美的…

【GIS开发小课堂】WebGIS开发必学开源框架Openlayers,附赠视频教程、电子书、笔记源码

WebGIS开发之Openlayers 当前&#xff0c;WebGIS开发热门程度越来越高&#xff0c;市场招聘供需比处于较为紧张的状态。 常见的WebGIS开源框架有&#xff1a;OpenLayers、Leaflet、MapBox、MapFish、GeoServer、GeoEXT、MapInfo等。公司最希望求职者具备至少一种框架开发技能…

什么样的开放式耳机好用?,五大超强卷王单品推荐!

对于热衷尝试不同耳机类型的小伙伴们而言&#xff0c;经过对佩戴舒适度、音质清晰度及电池续航能力的全面考量&#xff0c;开放式蓝牙耳机因其卓越的平衡性脱颖而出&#xff0c;成为多数人的心头好。其轻巧设计不仅保证了长时间佩戴的舒适感&#xff0c;还兼顾了音质与续航的双…

【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第一篇 嵌入式Linux入门篇-第十九章 Linux 工具之make 工具和 makefile 文件

i.MX8MM处理器采用了先进的14LPCFinFET工艺&#xff0c;提供更快的速度和更高的电源效率;四核Cortex-A53&#xff0c;单核Cortex-M4&#xff0c;多达五个内核 &#xff0c;主频高达1.8GHz&#xff0c;2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…

【亲测有效】Linux/Ubuntu远程服务器使用plt.show()没有反应,vscode ssh 远程ubuntu,plt.show不显示图片问题

【亲测有效】Linux/Ubuntu远程服务器使用plt.show没有反应&#xff0c;vscode ssh 远程ubuntu&#xff0c;plt.show不显示图片问题 plt.show()在linux或者ubuntu系统中不会有显示&#xff0c;这是因为系统没有图形界面。解决方法&#xff1a;保存成png图片然后在程序运行后查看…

使用 MinIO 赢得 RAG 权利

人们常说&#xff0c;在人工智能时代&#xff0c;数据是你的护城河。为此&#xff0c;构建生产级 RAG 应用程序需要合适的数据基础架构来存储、版本控制、处理、评估和查询构成专有语料库的数据块。由于 MinIO 采用数据优先的 AI 方法&#xff0c;因此对于此类项目&#xff0c;…

PostMan添加path参数请求

如下图&#xff1a; /findInventoryByQrCode/:qrCode用 : 会出现Path Variables 栏

科普文:看懂Linux日志分析

日志文件是Linux系统中极为重要的一部分&#xff0c;它们记录了系统和应用程序的各种活动信息。通过日志文件&#xff0c;系统管理员可以监控系统的运行状态、发现潜在的问题&#xff0c;并进行故障排除。 一. 常见的日志文件 在介绍具体的日志分析命令之前&#xff0c;首先了…

Mybatis的优缺点及适用场景?

目录 一、什么是Mybatis&#xff1f; 二、Mybatis框架的特点 三、Mybatis框架的优点&#xff1f; 四、MyBatis 框架的缺点&#xff1f; 五、MyBatis 框架适用场合&#xff1f; 六、代码示例 1. 配置文件 mybatis-config.xml 2. 映射文件 UserMapper.xml 3. Java 代码…

前端面试39(关于git)

针对前端开发者的Git面试题可以覆盖Git的基础概念、常用命令、工作流程、团队协作、以及解决冲突等方面。以下是一些具体的Git面试 Git基础知识 什么是Git&#xff1f; Git是一个分布式版本控制系统&#xff0c;用于跟踪计算机文件的更改&#xff0c;并协调多个人共同在一个项…

c++ 多边形 xyz 数据 获取 中心点方法,线的中心点取中心值搞定 已解决

有需求需要对。多边形 获取中心点方法&#xff0c;绝大多数都是 puthon和java版本。立体几何学中的知识。 封装函数 point ##########::getCenterOfGravity(std::vector<point> polygon) {if (polygon.size() < 2)return point();auto Area [](point p0, point p1, p…

C#知识|账号管理系统:UI层-添加账号窗体设计思路及流程。

哈喽,你好啊,我是雷工! 前边练习过详情页窗体的设计思路及流程: 《C#知识|上位机UI设计-详情窗体设计思路及流程(实例)》 本节练习添加账号窗体的UI设计,以下为学习笔记。 01 效果展示 02 添加窗体 在UI层添加Windows窗体,设置名称为:FrmAddAcount.cs 设置窗体属…

检测管道有没有水的传感器-管道液位传感器

如今&#xff0c;随着生活方式的多样化和科技的进步&#xff0c;检测管道液位的需求变得愈发重要。特别是在诸如扫地机器人、洗地机、饮水机等设备中&#xff0c;确保管道中是否存在水是关键的功能之一。针对这一需求&#xff0c;市场上涌现出多种先进的管道液位传感器&#xf…

移动应用:商城购物类,是最常见的,想出彩或许就差灵犀一指

在移动应用中&#xff0c;商城购物类的非常常见&#xff0c;模式也非常成熟&#xff0c;想要设计的出彩也是有难度的&#xff0c;这次分享一些不同的。

项目收获总结--Redis的知识收获

一、概述 最近几天公司项目开发上线完成&#xff0c;做个收获总结吧~ 今天记录Redis的收获和提升。 二、Redis异步队列 Redis做异步队列一般使用 list 结构作为队列&#xff0c;rpush 生产消息&#xff0c;lpop 消费消息。当 lpop 没有消息的时候&#xff0c;要适当sleep再…

迁移至 AI-Ready 基础架构:日立内容平台至 MinIO

借助我们的 HCP-to-MinIO 工具&#xff0c;从 Hitachi Content Platform &#xff08;HCP&#xff09; 过渡到 MinIO 从未如此简单。该工具旨在支持客户不断变化的存储需求&#xff0c;可在 GitHub 上免费获得&#xff0c;大大简化了迁移过程。许多组织正在转型&#xff0c;以利…

supOS助力油气行业数智化转型

在油气行业&#xff0c;高温高压、易燃易爆的特殊环境对生产安全和效率提出了极高的要求。传统工厂管理模式往往存在信息孤岛、决策滞后、响应速度慢等问题&#xff0c;难以适应现代工业化发展的需求。 从传统工厂到智能工厂&#xff0c;首先要实现企业经营运营自动化和生产过程…