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

【C】堆的应用1 -- 堆排序

  之前学习了堆,堆的一棵以顺序结构存储的完全二叉树,堆本身又氛围大根堆和小根堆,假设以大根堆为例,由于堆顶部元素是一棵二叉树里面最大的元素,所以如果每次都取堆顶的元素,那么取出的元素就是一个降序排列的序列。至此,我们发现了一个堆的特别重要的一个应用,就是堆排序。


目录

1  问题解析

2  算法分析

3  代码 

4  时空复杂度分析

(1) 时间复杂度

(2) 空间复杂度


1  问题解析

  堆排序顾名思义就是用堆结构来实现对一个数组的排序,但是在排序过程中是不能使用堆这个数据结构的。如:有一个数组 a[] = {2, 4, 10, 9,  2,  3},通过堆排序这个排序算法之后,数组 a 里面的数据变为了 a[] = {2, 2, 3, 4, 9, 10} 升序排列;或者是 a[]  = {10, 9, 4, 3, 2, 2} 降序排列。


2  算法分析

  该算法共分为两步:

  1) 首先对于给定的一个数组,数组里面的数据都是乱序的,既然是堆排序,我们就需要先让该数组里面的数据变成一个堆,将数组中的数据变成一个堆的算法为(这里是建大堆,建小队逻辑类似):
  这里利用的是向下调整算法,因为向下调整算法的时间效率是比向上调整算法的时间效率高的(上一篇文章有所讲解),而向下调整算法又需要其左右子树各自都是一个堆,所以首先选择最后一个节点作为孩子节点,让其父亲向下调整,这样最后一棵子树就变成了一个堆,然后再以当前孩子节点的上一个节点作为下一个孩子节点,让其父亲向下调整,直至所有的子树都被调整为了一个堆。该过程如图所示:

 

其本质就是从最小的一个子树建堆,然后使子树规模依次扩大,最后扩大为整棵树。

  2)数组建完堆之后,由于堆顶数据总是最大的,所以我们选择让堆顶数据和最后一个节点的数据进行交换,这样最后一个数据就是有序的,然后让交换后的堆顶数据再向下建堆,但是注意这次建堆的范围应是 n - 1 个数据(n 为数组中数据的个数);那么当前我们执行完 n - 1 次该操作之后,最大的 n - 1 个数据就会被升序的放到后 n - 1 个位置,所以就实现了升序排列。该算法如图所示:

  通过理解该算法,如果要排升序的话,那么应该建大堆;排降序的话,应该建小堆。


3  代码 

//升序的话,建大堆;降序的话,建小堆
//这里升序排列
void Swap(int* x, int* y)
{int tmp = *x;*x = *y;*y = tmp;
}void AdjustDown(int* arr, int parent, int n)
{int child = 2 * parent + 1;while (child < n){if (arr[child + 1] > arr[child] && child + 1 < n){child++;}if (arr[child] > arr[parent]){Swap(&arr[child], &arr[parent]);parent = child;child = 2 * parent + 1;}else{break;}}
}//Heap是堆的意思,Sort是排序的意思
void HeapSort(int* arr, int n)
{//先用所给的数组向下调整建一个堆for (int i = (n-1-1)/2;i >= 0;i--){AdjustDown(arr, i, n);}//然后每次交换堆顶元素和最后一个元素,让剩余元素建大堆int end = n;while (end > 0){//先交换Swap(&arr[0], &arr[--end]);//然后剩下元素建大堆AdjustDown(arr, 0, end);}
}

测试用例:

void Test()
{int arr[] = { 10, 9, 2, 4, 6, 11, 56, 20, 15, 19};int n = sizeof(arr) / sizeof(arr[0]);HeapSort(arr, n);for (int i = 0; i < n; i++){printf("%d ", arr[i]);}
}int main()
{Test();return 0;
}

4  时空复杂度分析

(1) 时间复杂度

  在上一篇文章中,我们分析了向下调整算法的时间复杂度为 O(logn) 的,而在堆排序里面共有两次循环,第一次循环会执行 n/2 - 1 次,第二次循环会执行 n 次,而这两次循环里面都嵌套了向下调整算法,所以时间复杂度为 O( (n/2 - 1)*logn + nlogn),去除常数项和低阶项,堆排序时间复杂度就是 O(nlogn)的。

(2) 空间复杂度

  由于堆排序算法仅用了几个变量,并为额外开辟空间,所以空间复杂度为 O(1)。

相关文章:

【C】堆的应用1 -- 堆排序

之前学习了堆&#xff0c;堆的一棵以顺序结构存储的完全二叉树&#xff0c;堆本身又氛围大根堆和小根堆&#xff0c;假设以大根堆为例&#xff0c;由于堆顶部元素是一棵二叉树里面最大的元素&#xff0c;所以如果每次都取堆顶的元素&#xff0c;那么取出的元素就是一个降序排列…...

BGP配置华为——路径优选验证

实验拓扑 实验要求 实现通过修改AS-Path属性来影响路径选择实现通过修改Local_Preference属性来影响路径选择实现通过修改MED属性来影响路径选择实现通过修改preferred-value属性来影响路径选择 实验配置与效果 1.改名与IP配置 2.as300配置OSPF R3已经学到R2和R4的路由 3.…...

【原创】Windows11安装WSL“无法解析服务器的名称或地址”问题解决方法

原因分析 出现这个问题一开始以为WSL设置了某个服务器&#xff0c;但是通过运行 nslookup www.microsoft.com 出现下面的提示 PS C:\Windows\system32> nslookup www.microsoft.com 服务器: UnKnown Address: 2408:8000:XXXX:2b00:8:8:8:8非权威应答: 名称: e13678…...

【CS285】高斯策略对数概率公式的学习笔记

公式介绍 在【CS285】中提到了高斯策略对数概率公式的公式如下&#xff1a; log ⁡ π θ ( a t ∣ s t ) − 1 2 ∥ f ( s t ) − a t ∥ Σ 2 const \log \pi_{\theta}(\mathbf{a}_t | \mathbf{s}_t) -\frac{1}{2} \left\| f(\mathbf{s}_t) - \mathbf{a}_t \right\|_{\S…...

R与RStudio简介及安装

目录 一、R与RStudio关系 二、R简介 2.1. 发展历史 2.2. R语言特点 三、安装指南 3.1 R安装指南 3.2 R studio安装指南 一、R与RStudio关系 R是统计领域广泛使用的工具&#xff0c;属于GNU系统的一个自由、免费、源代码开放的软件&#xff0c;是 用于统计计算和统计绘图…...

TTL和CMOS的区别【数电速通】

CMOS电平&#xff1a;电压范围在3&#xff5e;15V&#xff1b;常见电压在12V。 TTL电平&#xff1a;电压范围在0&#xff5e;5V&#xff0c;常见都是5V CMOS的特点&#xff1a;电平由电源VDD​ 决定&#xff0c;而不是外部电源电平。 COMS电路的使用注意事项 我们在使用CMOS…...

Linux红帽:RHCSA认证知识讲解(二)配置网络与登录本地远程Linux主机

Linux红帽&#xff1a;RHCSA认证知识讲解&#xff08;二&#xff09;配置网络与登录本地远程Linux主机 前言一、使用命令行&#xff08;nmcli 命令&#xff09;配置网络&#xff0c;配置主机名第一步第二步修改主机名称 二、使用图形化界面&#xff08;nmtui 命令&#xff09;配…...

Threejs教程一【三要素】

场景 场景是一个容器&#xff0c;用于容纳所有的物体、光源、相机等元素。 // 创建场景 const scene new THREE.Scene(); //修改背景颜色&#xff0c;颜色支持十六进制、rgb、hsl、贴图等 scene.background new THREE.Color(0x000000);相机 相机决定了渲染的结果&#xff…...

3-1 WPS JS宏工作簿的新建与保存(批量新建工作簿)学习笔记

************************************************************************************************************** 点击进入 -我要自学网-国内领先的专业视频教程学习网站 *******************************************************************************************…...

明日方舟一键端+单机+联网+安装教程+客户端apk

为了学习和研究软件内含的设计思想和原理&#xff0c;本人花心血和汗水带来了搭建教程&#xff01;&#xff01;&#xff01; 教程不适于服架设&#xff0c;严禁服架设&#xff01;&#xff01;&#xff01;请牢记&#xff01;&#xff01;&#xff01; 教程仅限学习使用&…...

Redis基操

redis 存储在内存中 key-value存储 主要存储热点数据(短时间大量的访客去访问) 启动命令 redis-server.exe redis.windows.conf 客户端链接redis服务器 redis-cli.exe redis-cli.exe -h localhost -p 6379 redis-cli.exe -h localhost -p 6379 -a 123456 退出 exit 命令不区分…...

学习笔记03——《深入理解Java虚拟机(第三版)》类加载机制知识总结与面试核心要点

《深入理解Java虚拟机&#xff08;第三版&#xff09;》类加载机制知识总结与面试核心要点 一、章节核心脉络 核心命题&#xff1a;JVM如何将.class文件加载到内存并转换为运行时数据结构&#xff1f; 核心流程&#xff1a;加载 → 验证 → 准备 → 解析 → 初始化 → 使用 →…...

w227springboot旅游管理系统设计与实现

&#x1f64a;作者简介&#xff1a;多年一线开发工作经验&#xff0c;原创团队&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的网站项目。 代码可以查看文章末尾⬇️联系方式获取&#xff0c;记得注明来意哦~&#x1f339;赠送计算机毕业设计600个选题excel文…...

漏洞文字版表述一句话版本(漏洞危害以及修复建议),通常用于漏洞通报中简洁干练【持续更新中】

漏洞文字版表述一句话版本(漏洞危害以及修复建议) SQL注入漏洞 危害描述&#xff1a; SQL注入漏洞允许攻击者通过构造恶意的SQL语句&#xff0c;绕过应用程序的安全检查&#xff0c;直接访问或操作数据库。这可能导致数据泄露、数据篡改、甚至数据库被删除等严重后果&#xf…...

项目——仿RabbitMQ实现消息队列

1.项目介绍 曾经在学习Linux的过程中&#xff0c;我们学习过阻塞队列 (BlockingQueue) 。 当时我们说阻塞队列最大的用途, 就是用来实现生产者消费者模型。 生产者消费者模型是后端开发的常用编程方式&#xff0c; 它存在诸多好处&#xff1a; 解耦合支持并发支持忙闲不均削峰…...

嵌入式硬件篇---滤波器

文章目录 前言一、模拟电子技术中的滤波器1. 基本概念功能实现方式 2. 分类按频率响应低通滤波器高通滤波器带通滤波器带阻滤波器 按实现方式无源滤波器有源滤波器 3. 设计方法巴特沃斯滤波器&#xff08;Butterworth&#xff09;切比雪夫滤波器&#xff08;Chebyshev&#xff…...

JAVA最新版本详细安装教程(附安装包)

目录 文章自述 一、JAVA下载 二、JAVA安装 1.首先在D盘创建【java/jdk-23】文件夹 2.把下载的压缩包移动到【jdk-23】文件夹内&#xff0c;右键点击【解压到当前文件夹】 3.如图解压会有【jdk-23.0.1】文件 4.右键桌面此电脑&#xff0c;点击【属性】 5.下滑滚动条&…...

《筑牢元宇宙根基:AI与区块链的安全信任密码》

在科技浪潮汹涌澎湃的当下&#xff0c;元宇宙已不再是科幻作品中的遥远构想&#xff0c;而是逐渐步入现实&#xff0c;成为人们热议与探索的前沿领域。从沉浸式的虚拟社交&#xff0c;到创新的数字经济模式&#xff0c;元宇宙的发展前景广阔&#xff0c;潜力无限。但要让元宇宙…...

云原生周刊:云原生和 AI

开源项目推荐 FlashMLA DeepSeek 于北京时间 2025 年 2 月 24 日上午 9 点正式开源了 FlashMLA 项目。FlashMLA 是专为 NVIDIA Hopper 架构 GPU&#xff08;如 H100、H800&#xff09;优化的高效多头潜在注意力&#xff08;MLA&#xff09;解码内核&#xff0c;旨在提升大模型…...

rust笔记9-引用与原始指针

Rust 中的指针类型和引用类型是理解其内存管理机制的关键部分。& 引用和 * 原始指针在底层原理上确实都可以认为是指针,它们都存储了某个内存地址,并指向该地址处的数据。然而,它们在安全性、使用方式和编译器支持上有显著的区别。下面我会详细解释它们的异同点,帮助你…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明&#xff1a; 想象一下&#xff0c;你正在用eNSP搭建一个虚拟的网络世界&#xff0c;里面有虚拟的路由器、交换机、电脑&#xff08;PC&#xff09;等等。这些设备都在你的电脑里面“运行”&#xff0c;它们之间可以互相通信&#xff0c;就像一个封闭的小王国。 但是&#…...

黑马Mybatis

Mybatis 表现层&#xff1a;页面展示 业务层&#xff1a;逻辑处理 持久层&#xff1a;持久数据化保存 在这里插入图片描述 Mybatis快速入门 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6501c2109c4442118ceb6014725e48e4.png //logback.xml <?xml ver…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止

<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet&#xff1a; https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

1688商品列表API与其他数据源的对接思路

将1688商品列表API与其他数据源对接时&#xff0c;需结合业务场景设计数据流转链路&#xff0c;重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点&#xff1a; 一、核心对接场景与目标 商品数据同步 场景&#xff1a;将1688商品信息…...

macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用

文章目录 问题现象问题原因解决办法 问题现象 macOS启动台&#xff08;Launchpad&#xff09;多出来了&#xff1a;Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显&#xff0c;都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

Frozen-Flask :将 Flask 应用“冻结”为静态文件

Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是&#xff1a;将一个 Flask Web 应用生成成纯静态 HTML 文件&#xff0c;从而可以部署到静态网站托管服务上&#xff0c;如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

QT: `long long` 类型转换为 `QString` 2025.6.5

在 Qt 中&#xff0c;将 long long 类型转换为 QString 可以通过以下两种常用方法实现&#xff1a; 方法 1&#xff1a;使用 QString::number() 直接调用 QString 的静态方法 number()&#xff0c;将数值转换为字符串&#xff1a; long long value 1234567890123456789LL; …...

selenium学习实战【Python爬虫】

selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...

【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统

目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索&#xff08;基于物理空间 广播范围&#xff09;2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...