堆排序算法的原理与应用
堆排序(Heap Sort)是一种基于堆数据结构的比较排序算法。它具有时间复杂度为 O(n log n) 的优点,并且空间复杂度为 O(1),是一种不稳定的排序算法。本文将详细介绍堆排序的工作原理、步骤以及它的应用场景。
一、堆排序的基本概念
堆是一种特殊的二叉树数据结构,具有以下两个重要特性:
- 完全二叉树:所有的层都是满的,除了最后一层,且最后一层的节点从左到右依次排列。
- 堆的性质:
- 最大堆:对于每个非叶子节点,父节点的值都大于或等于其子节点的值。
- 最小堆:对于每个非叶子节点,父节点的值都小于或等于其子节点的值。
堆排序的核心思想是:利用堆这种结构,每次将堆顶元素(最大或最小)取出,然后调整剩余的堆,直到所有元素都被排好序。
1. 堆排序的流程
堆排序的基本过程可以分为以下几个步骤:
- 构建最大堆:将无序数组调整为一个符合最大堆性质的结构。
- 取出堆顶元素:将最大堆的根节点(即最大值)与最后一个节点交换,并把最大值放在数组末尾。此时,最大值已在正确的位置。
- 重新调整堆:去掉已排好的元素,重新调整剩下的部分,使其再次成为一个最大堆。
- 重复步骤 2 和 3:直到堆中只剩下一个元素,排序完成。
二、堆排序的详细步骤
接下来,我们具体看看如何实现堆排序。以下是堆排序的步骤说明:
1. 构建最大堆
将一个无序数组变成一个最大堆的过程称为堆化。堆化的过程是从最后一个非叶子节点开始,自底向上依次调整每个节点,使其符合最大堆的性质。堆化的时间复杂度为 O(n)。
2. 取出堆顶元素
最大堆的堆顶元素是整个数组的最大值。将这个值与数组的最后一个元素交换,并缩小堆的范围(忽略已排好序的部分)。这时,堆顶可能不再是最大值,需要通过堆调整重新恢复最大堆的性质。
3. 堆调整
堆调整是保持堆的性质的核心操作。每次调整时,将新的堆顶元素下沉到合适的位置,确保每个父节点都大于等于它的子节点。堆调整的时间复杂度是 O(log n),因为树的高度是 log n。
4. 重复构建和调整
重复取出堆顶元素和堆调整,直到所有元素排序完毕。由于每次取出一个元素都需要堆调整,因此总的时间复杂度为 O(n log n)。
代码示例
为了让读者更直观理解堆排序的实现,下面是堆排序的伪代码描述:
# 堆排序主函数
def heap_sort(arr):n = len(arr)# 1. 构建最大堆for i in range(n // 2 - 1, -1, -1):heapify(arr, n, i)# 2. 取出堆顶元素并重新调整堆for i in range(n - 1, 0, -1):arr[i], arr[0] = arr[0], arr[i] # 交换堆顶与最后一个元素heapify(arr, i, 0) # 重新调整堆# 堆调整函数
def heapify(arr, n, i):largest = i # 初始化当前节点为最大left = 2 * i + 1 # 左子节点right = 2 * i + 2 # 右子节点# 如果左子节点存在且大于父节点if left < n and arr[left] > arr[largest]:largest = left# 如果右子节点存在且大于父节点if right < n and arr[right] > arr[largest]:largest = right# 如果最大值不是父节点,则进行交换,并继续调整if largest != i:arr[i], arr[largest] = arr[largest], arr[i]heapify(arr, n, largest)
在上面的代码中,heap_sort 函数是堆排序的主函数,而 heapify 函数负责维护最大堆的性质。每次调整完堆后,最大的元素会被移到数组的末尾,剩下的部分继续调整直到整个数组有序。
三、堆排序的优缺点
优点
- 时间复杂度稳定:堆排序的时间复杂度始终为 O(n log n),无论输入数据的有序程度如何。
- 空间复杂度为 O(1):堆排序是一种原地排序算法,不需要额外的辅助空间。
- 不受输入数据影响:堆排序的效率不依赖于输入数据是否有序,在最坏、最好和平均情况下的时间复杂度都为 O(n log n)。
缺点
- 不稳定:堆排序是一种不稳定排序算法,也就是说,相同的元素在排序前后可能会改变相对顺序。
- 常数开销大:尽管时间复杂度为 O(n log n),但由于堆的调整操作涉及较多次的交换,导致实际性能可能不如其他 O(n log n) 的排序算法(如归并排序和快速排序)。
四、堆排序的应用场景
堆排序由于其 O(n log n) 的时间复杂度和 O(1) 的空间复杂度,适合用于内存有限且需要稳定性能的场景。例如:
- 大数据量排序:在大数据量排序中,堆排序表现较为稳定,并且由于其空间复杂度低,适合在内存有限的设备上进行排序任务。
- 优先级队列:堆排序常用于实现优先级队列。通过最大堆或最小堆,可以快速找到队列中最大或最小的元素。
- 实时排序系统:堆排序适合在需要随时调整数据顺序的系统中,如实时交易系统、调度系统等。
五、总结与讨论
堆排序作为一种高效且节省空间的排序算法,在许多大数据和系统应用中都有其独特的优势。尽管它在实际应用中的普及程度不如快速排序,但在某些特殊场景下,它凭借稳定的时间复杂度和原地排序的特性,仍然是一个有力的选择。你在实际开发中有没有遇到过需要选择堆排序的情况?相比其他排序算法,你认为它在哪些应用场景下表现更好?欢迎分享你的经验和看法!
相关文章:
堆排序算法的原理与应用
堆排序(Heap Sort)是一种基于堆数据结构的比较排序算法。它具有时间复杂度为 O(n log n) 的优点,并且空间复杂度为 O(1),是一种不稳定的排序算法。本文将详细介绍堆排序的工作原理、步骤以及它的应用场景。 一、堆排序的基本概念…...
【2024版本】Mac/Windows IDEA安装教程
IDEA 2024版本真的很强大,此外JDK发布了最新稳定版 JDK21 ,只有新版本支持JDK 21、JDK22。原来数据库插件不支持redis等一些NoSql的数据库的连接,如果要使用需要自己单独装收费的插件。直接打开idea就很吃内存了,再打开其他一大堆…...
Oracle bbed编译安装及配置
1. 什么是bbed ? Oracle Block Brower and EDitor Tool,是一个可以对oracle data block进行查看,编辑修改的内置工具。对于bbed,oracle本身是不提供支持的。 2. 如何编译bbed环境? 10g版本: 1) 编译bbed cd $ORACL…...
MindSearch 部署到Github Codespace 和 Hugging Face Space
conda init后需要重开终端,不然一键复制会导致后续pip install会安装错环境 还是报错 ImportError: cannot import name AutoRegister from class_registry (/opt/conda/envs/mindsearch/lib/python3.10/site-packages/class_registry/__init__.py)pip install --…...
【Maven】依赖管理,Maven仓库,Maven核心功能
Maven 是一个项目管理工具,基于 POM(Project Object Model,项目对象模型)的概念,Maven 可以通过一小段描述信息来管理项目的构建,报告和文档的项目管理工具软件 大白话:Maven 是一个项目管理工…...
Android wifi信号和漫游信号设置
1.wifi信号 /packages/modules/Wifi/framework/java/android/net/wifi/WifiManager.java Deprecated public static int calculateSignalLevel(int rssi, int numLevels) { if (rssi < MIN_RSSI) { //*/update wifi signal return 1;…...
检查cuda和显卡的可用性
检查cuda和显卡的可用性 import torch device_gpu torch.device(cuda if torch.cuda.is_available() else cpu) print(device_gpu) print(torch.cuda.is_available())...
Kotlin:2.0.20 的新特性
一、概述 Kotlin 2.0.20英文版官方文档 Kotlin 2.0.20发布了!这个版本包括对Kotlin 2.0.0的性能改进和bug修复,我们在其中宣布Kotlin K2编译器为Stable。以下是本次发布的一些亮点: 数据类复制函数将具有与构造函数相同的可见性来自默认目标层次结构的源集的静态访…...
Python内存管理与泄漏排查实战
Python内存管理与泄漏排查实战 Python作为一种高级编程语言,因其易读性和丰富的标准库而备受开发者青睐。然而,随着项目的复杂度增加,内存管理问题可能会影响程序的性能,甚至导致内存泄漏。为了构建健壮且高效的应用程序…...
828华为云征文|华为云Flexus云服务器X实例搭建部署H5美妆护肤分销商城、前端uniapp
准备国庆之际,客户要搭个 H5 商城系统,这系统好不容易开发好啦,就差选个合适的服务器上线。那可真是挑花了眼,不知道哪款性价比高呀!就像在琳琅满目的选择前。最终慧眼识珠,选择了华为云 Flexus X。至于为什…...
初学51单片机之I2C总线与E2PROM二
总结下上篇博文的结论: 1:ACK信号在SCL为高电平期间会一直保持。 2:在字节数据传输过程中如果发送电平跳变,那么电平信号就会变成重复起始或者结束的信号。(上篇博文的测试方法还是不能够明确证明这个结论࿰…...
Kafka学习笔记(一)Kafka基准测试、幂等性和事务、Java编程操作Kafka
文章目录 前言4 Kafka基准测试4.1 基于1个分区1个副本的基准测试4.2 基于3个分区1个副本的基准测试4.3 基于1个分区3个副本的基准测试 5 Java编程操作Kafka5.1 引入依赖5.2 向Kafka发送消息5.3 从Kafka消费消息5.4 异步使用带有回调函数的生产消息 6 幂等性6.1 幂等性介绍6.2 K…...
结合vueuse实现图片懒加载
介绍 为什么要有懒加载? 在一个网页中如果有很多张图片,那么用户初进这个页面的时候不必一次性把所有图片都加载出来,否则容易造成卡顿和浪费。应该是,用户的视图页面滑到该图片的位置,然后再把该图片加载出来。 前置…...
Mysql数据库--聚合查询、分组查询、联合查询(不同的连接方式)
文章目录 1.查询的进阶版1.1查询搭配插入进行使用1.2聚合查询1.3group by分组查询1.4联合查询之笛卡尔积1.5左外连接,右外连接介绍join on1.6自连表 1.查询的进阶版 1.1查询搭配插入进行使用 我们首先创建两张表,一个叫做student,一个叫做student2,两个…...
计算机视觉——图像修复综述篇
目录 1. Deterministic Image Inpainting 判别器图像修复 1.1. sigle-shot framework (1) Generators (2) training objects / Loss Functions 1.2. two-stage framework 2. Stochastic Image Inpainting 随机图像修复 2.1. VAE-based methods 2.2. GAN-based methods …...
集中式架构和分布式架构
数据是企业的核心资产和战略资源。面对爆炸性的数据增长,如何有效地组织、管理和利用数据成为企业的重大挑战。数据架构作为企业数据管理的蓝图和框架,发挥重要作用。本文就来详细说下当下主流的两种数据架构的类型。 首先明确数据架构定义:…...
Redis: 集群高可用之故障转移和集群迁移
故障转移 故障转移,包括自动故障转移和手动故障转移 1 )自动故障转移 Redis 集群,主节点挂了,从节点可以顶上来继续提供服务常用制造故障的两种方式 第一,对其中一个节点进行 SHUTDOWN 操作第二,kill 掉…...
记账软件在线、会计记账网站、财务记账官网、记账云、云记账、在线免费做账以及易舟云财务软件
记账软件在线、会计记账网站、财务记账官网、记账云、云记账、在线免费做账以及易舟云财务软件,以下是一些详细的介绍和推荐: 一、记账软件在线与会计记账网站 记账软件和会计记账网站是现代财务管理中不可或缺的工具,它们能够帮助企业或个人…...
Elasticsearch基础_3.基础操作
文章目录 一、索引操作1.1、创建索引1.2、删除索引 二、映射操作2.1、查看映射2.2、扩展映射 三、文档操作3.1、单条写入文档3.2、更新单条文档3.3、查看单条文档3.4、删除单条文档3.5、根据条件删除文档 一、索引操作 1.1、创建索引 PUT /${index_name} {"settings&quo…...
PHP永久性Cookie的含义
PHP中的永久性Cookie(也称为持久性Cookie)是指在用户的计算机上存储的一种持久性的HTTP Cookie。与常规的临时Cookie不同,永久性Cookie在浏览器关闭后依然保留,并且可以在用户下次访问该网站时被读取和使用。 主要特点 持久存储…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...
【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...
React Native 开发环境搭建(全平台详解)
React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...
Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...
多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...
Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...
python执行测试用例,allure报乱码且未成功生成报告
allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...
