[算法]——堆排序(C语言实现)

        简单的介绍一下用堆排序的算法对整形数据的数据进行排序。

一、堆的概念

        堆是具有下列性质的完全二叉树每个结点的值都大于或等于其左右孩子节点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。

大顶堆和小顶堆的示意图:

 

二、堆排序的算法

        因为数组具有顺序结构,而我们的完全二叉树可以使用顺序结构来表示,所以我们可以用堆对数组进行排序。

(一)、算法思路

        这里介绍一下排升序的方法,等明白了思路后,排降序自然也会了。

        假设数组的元素个数为n,将待排序的数组构造成一个大顶堆。此时,整个数组的最大值就是堆顶的根节点。将它移走(将其与堆数组的末尾元素进行交换,此时末尾元素就是最大值),这样我们待排序的数组的最大值就排到了正确的位置上。然后我们把剩余的n-1个元素重新构成一个大顶堆,这样堆顶元素就是我们的次大值,将其移走,次大值的元素也就排好了。如此反复执行,就得到了一个升序的数组。如果我们要排降序的数组,则需要建小顶堆。

        于是我们就有了两个问题。一是:如何把一个无序的数组构建成大顶堆?在将堆顶元素移走后要怎么将剩余的数组元素重新调整为堆?

(二)、向上调整和向下调整

        向上调整针对的是当将一个新的元素插入到一个堆中时,将新插入的元素向上进行调整,将其二叉树保持原来的堆的结构。如果是使用堆来对一个数组进行排序的话,使用向下调整就足够了,所以我们先讲向下调整,当我们实现了对数组的堆排序后,再回来看向上调整。

1、向下调整

        向下调整的作用就是,当我们在一个堆的结构中,把堆顶元素给替换成别的值后,其堆顶处极可能已经不满足大顶堆和小顶堆的要求了,这个时候我们就需要把这个堆顶位置的元素向下调整到合适的位置,使其重新满足堆的要求。

例如下面这个例子:

        这是一个大顶堆,当我们用20替换其堆顶元素时,其不再满足大顶堆的结构,这时我们需要对堆顶的20进行向下调整。具体方法如如下:

 

具体代码:

//向下调整为大顶堆
void AdjustDown(int* arr,int left,int right)//传入数组和要向下调整的区间
{int pos = left;//记录向下调整的位置int temp = arr[pos];//保存向下调整的值for (int i = left * 2; i <= right; i *= 2)//遍历其要向下调整的结点的孩子{//找到其左孩子和右孩子的最大值 如果右孩子不存在,则最大值就算为左孩子if (i + 1 <= right && arr[i] < arr[i + 1])i++;//此时i指向右孩子if (temp < arr[i]) //如果要向下调整的值不如孩子大arr[pos] = arr[i];elsebreak;//更新要向下调整的值的下标位置pos = i;}//向下调整完毕,此时pos的位置就是要向下调整的值的最终位置arr[pos] = temp;
}

2、向上调整

        向上调整非常简单,只需要将插入的值的结点与其双亲结点相比较,如果比双亲大,那么就交换位置,一直重复该过程。

 

//向上调整为大堆顶
void AdjustUp(int* arr,int index)
{int pos = index;//记录向上调整的值的位置int temp = arr[index];//保存向上调整的值//遍历其双亲节点进行向上调整,如果向上调整的下标为0或比双亲小就结束for (int i = pos / 2; pos > 0; i /= 2){if (temp > arr[i])arr[pos] = arr[i];elsebreak;//更新pos的位置pos = i;}//向上调整完毕,此时pos位置就是向上调整的值的位置arr[pos] = temp;
}

 (三)、将无序数组转化为大顶堆

        实现方法:从最后一个叶子结点(就是数组的最后一个元素的下标的位置的结点)处的双亲结点开始,对该结点以及该结点之前的所有结点进行向下调整操作,这样就可以把无序数组转化为了大顶堆的结构。下面是将一个无序数组转化为大顶堆的示意图(标识为蓝色的值就是需要依次进行向下调整的结点。)

        

         就这样,我们就将一个无序的数组转化为了一个具有大顶堆结构的数组了。

        我们也可以从0开始遍历数组,每次执行一次向上调整,这样也可以建堆,但是其消耗比较大。因为需要对每个结点进行向上调整操作,而我们的向下调整建堆是不需要对最后一层的结点进行向下调整的,在一棵满二叉树中,最后一层的结点数就占了整棵树一半的结点数,这意味着向上调整建堆比向下调整建堆多用了很多时间。

(四)、堆排序的最终实现

        我们以一个大顶堆为例,看看将大顶堆转化成一个升序的数组的过程。

        来看下面这个大顶堆,是如何变升序的。

         此时90排好了。

 此时80就排好了。

如此往复...... 

 

具体代码:

//堆排序
void HeapSort(int* arr, int nums)
{//先从最后一个节点的双亲结点注逐一往前进行向下调整,将数组调整为大堆for (int i = (nums - 1) / 2; i >= 0; i--){AdjustDown(arr,i, nums - 1);}//将最大值放置到末尾然后将其与堆的联系解除,然后再对堆顶元素向下调整for (int i = nums - 1; i >= 1; i--){swap(arr[0], arr[i]);AdjustDown(arr, 0, i - 1);}
}

 三、堆排序的时间复杂度

        堆排序不需要额外开辟空间,所以空间复杂度为O(1)。

        时间消耗上主要在初始建堆和在反复重建堆的时间上。而我们对无序数组进行建堆所需要的时间复杂度为O(n),而我们在排序时,每次都需要对堆顶进行向下排序,其时间复杂度为O(nlogn)。所以堆排序的时间复杂度为O(nlogn)

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GenAI 用于客户支持 — 第 1 部分:构建我们的概念验证

作者&#xff1a;来自 Elastic Chris Blaisure 欢迎来到 Inside Elastic 博客系列&#xff0c;我们将展示 Elastic 的内部运营如何解决实际业务挑战。本系列将揭示我们将生成式 AI&#xff08;gererative AI - GenAI&#xff09;集成到客户成功和支持运营中的历程&#xff0c;让…

ctfshow web入门 sqli-labs web517--web524

web517 注入点id ?id-1’union select 1,2,3– 确认是否能够注入 ?id-1union select 1,database(),3-- 爆出库名 security爆出表名 ?id-1union select 1,(select group_concat(table_name) from information_schema.tables where table_schemasecurity),3-- emails,refer…

几个常见的FPGA问题之序列发生器、编码器、D触发器

几个常见的FPGA问题之序列发生器、编码器、D触发器 语言 :Verilg HDL 、VHDL EDA工具: Vivado 几个常见的FPGA问题之序列发生器、编码器、D触发器一、引言二、背景1、序列发生器(Sequence Generator)2、编码器(Encoder)3、D触发器(D Flip-Flop)二、问题及解决方案1. 序…

二进制方式部署consul单机版

1.consul的下载 mkdir -p /root/consul/data && cd /root/consul wget https://releases.hashicorp.com/consul/1.18.0/consul_1.18.0_linux_amd64.zip unzip consul_1.18.0_linux_amd64.zip mv consul /usr/local/bin/ 2.配置文件 // 配置文件路径&#xff1a; /roo…

将深度相机的实时三维坐标数据保存为excel文档

一、如何将数据保存为excel文档 1.excel文件库与相关使用 &#xff08;1&#xff09;导入相应的excel文件库&#xff0c;导入前先要进行pip安装&#xff0c;pip install xlwt import xlwt # 导入用于创建和写入Excel文件的库 (2) 建立一个excel文档&#xff0c;并在第0行写…

web安全渗透测试十大常规项(一):web渗透测试之Fastjson反序列化

渗透测试之Java反序列化 1. Fastjson反序列化1.1 FastJson反序列化链知识点1.2 FastJson反序列化链分析1.3.1 FastJson 1.2.24 利用链分析1.3.2 FastJson 1.2.25-1.2.47 CC链分析1.3.2.1、开启autoTypeSupport:1.2.25-1.2.411.3.2.2 fastjson-1.2.42 版本绕过1.3.2.3 fastjson…

C++调试技巧总结

1.调试准备 常用调试 Crash调试 调试信息&#xff1a; Windows系统&#xff1a;符号单独PDB文件/链接时生成&#xff0c;从外部的符号服务器下载。&#xff08;微软&#xff09; LInux&#xff1a; 调试符号与目标模块在一个文件内&#xff0c;编译时产生调试信息。模块发布时…

手机数据恢复篇:如何在OPPO中恢复永久删除的视频?

说到丢失重要的记忆&#xff0c;如何在OPPO设备中恢复永久删除的视频是一个经常困扰许多用户的话题。意外删除重要视频的情况并不少见&#xff0c;对许多人来说&#xff0c;意识到它们已经消失可能很困难。但是&#xff0c;在正确的指导、方法和工具的帮助下&#xff0c;可以找…

运行CDN

背景 CDN代码&#xff0c;调试运行 日常 git clone代码配置虚拟环境 puthon3.8,pip install r requirements.txt改项目数据集路径&#xff0c;在hico.py文件里面 # PATHS {# train: (root / images / train2015, root / annotations / trainval_hico.json),# val: …

性能优化:Java垃圾回收机制深度解析 - 让你的应用飞起来!

文章目录 一、什么是垃圾回收二、Java 内存区域划分三、垃圾回收算法1. 标记-清除&#xff08;Mark-Sweep&#xff09;算法2. 复制&#xff08;Copying&#xff09;算法3. 标记-整理&#xff08;Mark-Compact&#xff09;算法4. 分代收集&#xff08;Generational Collecting&a…

[XYCTF新生赛2024]-PWN:EZ2.0?(arm架构,arm架构下的系统调用)

查看保护 查看ida 完整exp&#xff1a; from pwn import*pprocess(./arm) premote(gz.imxbt.cn,20082) svc0x0001c58c mov_r2_r4_blx_r30x00043224 pop_r70x00027d78 pop_r40x000104e0 pop_r30x00010160 pop_r10x0005f824 pop_r00x0005f73c sh0x0008A090payloadba*0x44 payloa…

cesium使用cesium-navigation-es6插件创建指南针比例尺

cesium-navigation-es6 是一个为 Cesium.js 提供导航控件的库&#xff0c;它提供了一些常见的用户界面组件&#xff0c;用于在 Cesium 场景中实现用户导航和交互。下面将介绍如何在项目中使用 cesium-navigation-es6。 使用步骤 1. 安装 cesium-navigation-es6 首先&#xf…

环回接口处理 IP 数据报的过程及 Loopback 接口的主要作用

环回接口处理 IP 数据报的过程 IPv4 中 传给环回地址&#xff08;127.0.0.1&#xff09;的任何数据均作为 IP 输入&#xff0c;直接送到环回接口&#xff08;环回&#xff1a;IP 输入队列&#xff09;。 传给广播地址或多播地址的数据报&#xff0c;会复制一份传给环回接口&…

七人团购新风尚:数字化时代的购物革命

在数字化时代的浪潮中&#xff0c;购物方式正经历着前所未有的变革。其中&#xff0c;七人团购模式以其独特的互动性和价值共享理念&#xff0c;为消费者带来了全新的购物体验。下面&#xff0c;我们将深入探讨这一模式的运作机制&#xff0c;以及它如何为标价599元的热销商品创…

WordPress Quiz Maker插件 SQL注入漏洞复现(CVE-2024-6028)

0x01 产品简介 WordPress Quiz Maker插件是一款功能强大的测验生成工具,旨在帮助用户轻松、快速地构建复杂的测验和考试。插件支持多种问题类型,包括单选框(MCQ)、复选框(MCQ)、下拉列表(MCQ)、文本、短文本、数字、日期等。还支持横幅(HTML)显示信息性消息、填空题…

自养号测评助力:亚马逊、沃尔玛电商高效测评补单技巧,轻松实现销量与补单双赢

要在竞争激烈的市场中通过测评补单的方式提升产品权重和销售&#xff0c;构建一个稳定且高效的测评补单系统至关重要。通过精心培养一批高质量的买家账号&#xff0c;并深入了解真实买家的行为数据&#xff0c;结合对风控数据的精准把控&#xff0c;我们能够自主推动推广进程&a…

循环神经网络——RNN

循环神经网络 在之前NLP基础章节-语言模型中我们介绍了 n n n 元语法&#xff0c;其中单词 x t x_t xt​ 在时间步 t t t 的条件概率仅取决于前面 n n n 个单词&#xff0c;若是想要将之前单词的影响也加入那么模型参数数量会指数级增长。但是可能之前的单词存在重要的信息…

58岁TVB前视后近况曝光

众所周知&#xff0c;不少早年的TVB视帝视后如今在内地都很吃香&#xff0c;就比如说今年58岁的邓萃雯&#xff08;雯女&#xff09;。 近日由她与演员赵文瑄、张凯丽等合演的话剧《鳄鱼》在内地巡回演出&#xff0c;吸引了大批粉丝到场支持&#xff0c;不过就在雯女准备进入演…

vue3 动态配置element 的table

需求 合并行、合并标题、列宽可调整、列顺序可调整、可以控制列是否显示、列布局可保存、导出excel… 参考效果 代码 引入 npm i xlsx npm install element-plus --savetable组件 <template><div><div class"table-btn"><el-tooltip conte…

手写一个基于SpringBoot的MVC架构,默认实现CRUD和导入导出功能

文章目录 前言正文一、项目结构二、技术点三、部分核心代码3.1 core-tool 中的核心代码3.1.1 所有实体的通用父类 SuperEntity3.1.2 所有枚举的父接口 BaseEnum3.1.3 所有业务异常的父接口 BaseException 3.2 mvc-tool 中的核心代码3.2.1 CrudController 接口定义3.2.2 默认的C…