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

【数据结构初阶】堆排序

目录

前言

概念

堆排序的实现

1.建堆

 (1)堆向上调整算法

(2)堆的向下调整算法

2. 利用堆删除思想来进行排序

3.堆排序的时间复杂度

4.源码

总结


前言

前边我们学习了堆的实现,对堆的每个接口都进行了详细的讲解,所以这篇文章就来看一看堆到底有哪些应用。


概念

堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。堆排序可以说是一种利用堆的概念来排序的选择排序。分为两种方法:

  1. 大顶堆:每个节点的值都大于或等于其子节点的值,在堆排序算法中用于升序排列;
  2. 小顶堆:每个节点的值都小于或等于其子节点的值,在堆排序算法中用于降序排列;

堆排序的平均时间复杂度为 Ο(nlogn)。

我们之前学习的冒泡排序的时间复杂度为o(n^2),此处的堆排序确是Ο(nlogn),这样直接看并不能看出堆排序的优势,如果我们使用数字代入就会发现,如果我们有1000个数,进行排序时,冒泡排序是100万次,若是堆排序只需1万次,对于更大的数差别也会更大,所以堆排序是很有优势的。

堆排序的实现


 

1.建堆

我们根据上节课的学习,我们知道了向上调整算法和向下调整算法,他们都可以建立一个堆。

我们要切记,需要升序排列时要建一个大堆,需要降序排列时要建一个小堆。

 (1)堆向上调整算法

现在我们给出一个数组,逻辑上看做一颗完全二叉树。我们从第二个位置向上调整,直到最后一个位置的数为止。
​
void hpSort(int* a, int n)
{assert(a);//从第二个数开始向上调整for (int i = 1; i < n; i++){adjustUp(a, i);}
}​

(2)堆的向下调整算法

现在我们给出一个数组,逻辑上看做一颗完全二叉树。我们通过从根节点开始的向下调整算法可以把它调整成一个小堆。向下调整算法有一个前提:左右子树必须是一个堆,才能调整。

 有人可能认为向下调整算法的时间复杂度为o(n*log2n),其实并不是,时间复杂度其实为o(n),由于在倒数第二层时,每个元素只调整了一次,倒数第三层调整了两次,也可以通过数学公式来证明,通过错位相减法,最终得到了向下调整算法的时间复杂度为o(n)。

 

void hpSort(int* a, int n)
{assert(a);//从非叶子结点开始向下调整for (int i = (n-1)-1/2; i >= 0; i--){adjustDown(a, n, i);}
}

从非叶子结点开始调整,可以从最后一个结点的父节点处开始,进行向下调整,直至调整到根节点。


2. 利用堆删除思想来进行排序

(1)当我们要对数据进行降序排列时,我们先建立一个小堆,即父节点的数据小于子节点的数据。

(2)将最后一个结点与第一个结点互换,此时得到的最后一个结点的数据就是最小的数。

(3)此时对第一个结点向下调整,使其恢复成为一个小堆,此时堆顶元素就是整个堆中次小的数。

(4)此时,我们把最后一个结点与原来结点分离,只是看作分离,只是将其余结点从新进行之前的操作,直至堆的大小为1。

 

 

void hpSort(int* a, int n)
{assert(a);//从第二个数开始向上调整/*for (int i = 1; i < n; i++){adjustUp(a, i);}*///从非叶子结点开始向下调整for (int i = (n-1)-1/2; i >= 0; i--){adjustDown(a, n, i);}for(int end=n - 1 ; end > 0 ; end--){swap(&a[0], &a[end]);adjustDown(a, end ,0);}
}

 


3.堆排序的时间复杂度

我们知道了向下调整算法来建堆的时间复杂度为o(n),所以我们选择向下调整算法来建堆,在建完堆之后,我们就进行交换并且向下调整,排序的时间复杂度为o(n*log2n),所以总和的时间复杂度为o(n*log2n)。

4.源码

hpsort.c

void hpSort(int* a, int n)
{assert(a);//从第二个数开始向上调整/*for (int i = 1; i < n; i++){adjustUp(a, i);}*///从非叶子结点开始向下调整for (int i = (n-1)-1/2; i >= 0; i--){adjustDown(a, n, i);}for(int end=n - 1 ; end > 0 ; end--){swap(&a[0], &a[end]);adjustDown(a, end ,0);}
}

test.c

void test1()
{//TestTopk();int a[] = { 70, 56, 30, 25, 15, 10, 75, 33, 50, 69 };for (int i = 0; i < sizeof(a) / sizeof(a[0]); ++i){printf("%d ", a[i]);}printf("\n");hpSort(a, sizeof(a) / sizeof(a[0]));for (int i = 0; i < sizeof(a) / sizeof(a[0]); ++i){printf("%d ", a[i]);}printf("\n");}

总结

今天我们学习了堆排序的概念,实现,以及时间复杂度,过两天我会继续发布关于各种排序的文章,希望大家支持。

相关文章:

【数据结构初阶】堆排序

目录 前言 概念 堆排序的实现 1.建堆 &#xff08;1&#xff09;堆向上调整算法 &#xff08;2&#xff09;堆的向下调整算法 2. 利用堆删除思想来进行排序 3.堆排序的时间复杂度 4.源码 总结 前言 前边我们学习了堆的实现&#xff0c;对堆的每个接口都进行了详细的讲…...

Day5: platformDriver-1

Platform Driver (1) Linux kernel中大部分设备可以归结为平台设备&#xff0c;因此大部分的驱动是平台驱动&#xff08;patform driver&#xff09; 什么是平台设备 平台设备是linux的设备模型中一类设备的抽象。 内核中的描述&#xff1a; Platform devices are devices t…...

开发手册——一、编程规约_7.控制语句

这篇文章主要梳理了在java的实际开发过程中的编程规范问题。本篇文章主要借鉴于《阿里巴巴java开发手册终极版》 下面我们一起来看一下吧。 1. 【强制】在一个 switch 块内&#xff0c;每个 case 要么通过 break / return 等来终止&#xff0c;要么注释说明程序将继续执行到哪…...

python每日学9 : windows上配置gitee的远程仓库,git的初步使用

在开发中&#xff0c;如果遇到复杂的项目&#xff0c;使用版本控制是非常有必要的&#xff0c;如果涉及到多端开发&#xff0c;那么还需要使用远程仓库。本文作个简单记录&#xff0c;记录下git初步使用。 1 下载与安装 git还有几个ui版本&#xff0c;但是开始使用的话&#…...

精确率与召回率,ROC曲线与PR曲线

精确率与召回率&#xff0c;ROC曲线与PR曲线 在机器学习的算法评估中&#xff0c;尤其是分类算法评估中&#xff0c;我们经常听到精确率(precision)与召回率(recall)&#xff0c;ROC曲线与PR曲线这些概念&#xff0c;那这些概念到底有什么用处呢&#xff1f; 首先&#xff0c…...

现代操作系统——Linux架构与学习

小白的疑惑 在我决定从事嵌入式&#xff08;应用层&#xff09;方面的工作时&#xff0c;我查询了大量资料该如何学习&#xff0c;几乎所有观点不约而同的都指向了学习好Linux&#xff0c;大部分工作都是在Linux环境下来进行工作的。于是我雄心勃勃的去下载Linux&#xff0c;可…...

中文代码82

PK 嘚釦 docProps/PK 嘚釦羸 r docProps/app.xml潙蚽?勶曻Q顗濔S? 錞礖剅D柍珘m?鳞?ぷ辷f硌?2?upc厭Y樐8 rU y搪m眾&a?珪?紓 玺鶋瑣襚? ?i嘲rN?布倖儇?攊橌??嚗猝)芻矂2吟腊K湞?CK臶>鸘\?ΔF滋齢q旮T?桀?;偉 A軥v蕯朾偤佷3?е…...

顺序表(一篇带你掌握顺序表)

目录 一、顺序表是什么 1.1 概念 1.2 分类 1.3 结构 二、顺序表的基本操作 2.1 前绪准备 2.2 初始化 2.3 扩容 2.5 尾插 2.6 打印 2.7 尾删 2.8 头插 2.9 头删 2.10 在pos位置插入 2.11 删除pos位置的数据 2.12 查找 三、完整代码 3.1 Test.c文件 3.2 SeqList.h…...

【SpringCloud】SpringCloud教程之Feign实战

目录前言SpringCloud Feign远程服务调用一.需求二.两个服务的yml配置和访问路径三.使用RestTemplate远程调用(order服务内编写)四.构建Feign(order服务内配置)五.自定义Feign配置(order服务内配置)六.Feign配置日志(oder服务内配置)七.Feign调优(order服务内配置)八.抽离Feign前…...

嵌入式linux必备内存泄露检测神器

Valgrind介绍 Valgrind是一个可移植的动态二进制分析工具集&#xff0c;主要用于发现程序中的内存泄漏、不合法内存访问、使用未初始化的内存、不正确的内存释放以及性能问题等&#xff0c;可在Linux和Mac OS X等平台上使用。 Valgrind由多个工具组成&#xff0c;其中最常用的…...

设计模式之行为型模式

四、行为型模式 行为型模式用于描述程序在运行时复杂的流程控制&#xff0c;即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务&#xff0c;它涉及算法与对象间职责的分配。 行为型模式分为类行为模式和对象行为模式&#xff0c;前者采用继承机制来在…...

解密 三岁的三岁到底为什么叫做三岁?

机缘 那一年&#xff0c;一次奇奇怪怪的挫折与一次奇奇怪怪的成长。 在学习Python的路上总觉得少了点什么&#xff0c;是心情&#xff1f;是机遇&#xff1f;还是力量&#xff1f; 都不是又都是&#xff01; 缺少一个实践和记忆的平台 记性不好是硬伤 前一天学的下一秒就忘记了…...

id选择器

id选择器可以为特定的id的标签进行css美化 使用方法&#xff1a; 标签内设好 id值&#xff0c; CSS的id选择器以“#id名”来调用 注意 所有标签都有id值id属性值类似于身份证号码&#xff0c;在一个页面中是唯一的值&#xff0c;不可重复一个标签上只能有一个id属性值一个id属性…...

《科技之巅3》读书笔记

文章目录书籍信息人工智能&#xff0c;“吃一堑长一智”的机器人机交互&#xff0c;为解决“交流障碍”问题而生硬件与算法&#xff0c;好马还需好鞍模式创新&#xff0c;赋予技术新的定义云与数据共享&#xff0c;灵活应对信息的爆发式增长“机器人”&#xff0c;从电影和小说…...

18.用于大型程序的工具

文章目录用于大型程序的工具18.1异常处理18.1.1抛出异常栈展开栈展开过程中对象被自动销毁析构函数与异常异常对象18.1.2捕获异常查找匹配的处理代码重新抛出捕获所有异常的处理代码18.1.3函数try语句块与构造函数18.1.4noexcept异常说明违反异常说明异常说明的实参noexcept运算…...

mysql一主键uuid和自增的选择

文章目录 1.自增ID的优缺点1.1 优点1.2 缺点1.3 不适合以自增ID主键作为主键的情况2.UUID作为主键2.1 介绍2.2 优点2.3 缺点3.有序UUID作为主键3.1 介绍3.2 演示使用3.2.1 前提知识3.2.1.1 数据类型 - binary3.2.1.2 函数 - hex()3.2.1.3 函数 - unhex()3.2.2 数据库层3.2.3 JA…...

【EDA工具使用】——VCS和Verdi的联合仿真的简单使用

目录 1.芯片开发所需的工具环境 2.编译仿真工具 3.三步式混合编译仿真&#xff08;最常用&#xff09;​编辑 4.两步式混合编译仿真​编辑 5.VCS的使用 ​6.verdi的使用 1.产生fsdb文件的两种方法​编辑 1.芯片开发所需的工具环境 2.编译仿真工具 3.三步式混合编译仿真…...

【Java学习笔记】4.Java 对象和类

前言 本章介绍Java的对象和类。 Java 对象和类 Java作为一种面向对象语言。支持以下基本概念&#xff1a; 多态继承封装抽象类对象实例方法重载 本节我们重点研究对象和类的概念。 对象&#xff1a;对象是类的一个实例&#xff08;对象不是找个女朋友&#xff09;&#x…...

39. 实战:基于api接口实现视频解析播放(32接口,窗口化操作,可导出exe,附源码)

目录 前言 目的 思路 代码实现 需要导入的模块 1. 导入解析网站列表&#xff0c;实现解析过程 2. 设计UI界面 3. 设置窗口居中和循环执行 4. 注意事项 完整源码 运行效果 总结 前言 本节将类似34. 实战&#xff1a;基于某api实现歌曲检索与下载&#xff08;附完整…...

基于灵动 MM32 微控制器的便携式血氧仪方案

基于灵动 MM32 微控制器的便携式血氧仪&#xff1a; - Cortex-M0() 最高主频 72MHz 可实现血氧饱和度信号采集、算法操作和 LED 显示操作 - 高性能的 1Msps 12b ADC 能对光电采样结果进行大数据量的暂存和处理&#xff0c;提高采样的效率并有助于对结果做高精度的计算 - 100…...

应用升级/灾备测试时使用guarantee 闪回点迅速回退

1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间&#xff0c; 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点&#xff0c;不需要开启数据库闪回。…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器

一.自适应梯度算法Adagrad概述 Adagrad&#xff08;Adaptive Gradient Algorithm&#xff09;是一种自适应学习率的优化算法&#xff0c;由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率&#xff0c;适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...

在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module

1、为什么要修改 CONNECT 报文&#xff1f; 多租户隔离&#xff1a;自动为接入设备追加租户前缀&#xff0c;后端按 ClientID 拆分队列。零代码鉴权&#xff1a;将入站用户名替换为 OAuth Access-Token&#xff0c;后端 Broker 统一校验。灰度发布&#xff1a;根据 IP/地理位写…...

oracle与MySQL数据库之间数据同步的技术要点

Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异&#xff0c;它们的数据同步要求既要保持数据的准确性和一致性&#xff0c;又要处理好性能问题。以下是一些主要的技术要点&#xff1a; 数据结构差异 数据类型差异&#xff…...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户&#xff0c;但你不希望用 root 权限运行 ns-3&#xff08;这是对的&#xff0c;ns3 工具会拒绝 root&#xff09;&#xff0c;你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案&#xff1a;创建非 roo…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面

代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口&#xff08;适配服务端返回 Token&#xff09; export const login async (code, avatar) > {const res await http…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…...

return this;返回的是谁

一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请&#xff0c;不同级别的经理有不同的审批权限&#xff1a; // 抽象处理者&#xff1a;审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...