【数据结构】堆排序

大家好,我是苏貝,本篇博客带大家了解堆排序,如果你觉得我写的还不错的话,可以给我一个赞👍吗,感谢❤️
在这里插入图片描述


目录

  • 一. 堆的概念
  • 二. 堆排序(以升序为例)
  • 三. 代码

一. 堆的概念

如果有一个关键码的集合K,把它的所有元素按 完全二叉树 的顺序存储方式存储在一个一维数组中,并满足:任意一个双亲结点的值<=孩子节点的值(或任意一个双亲结点的值>=孩子节点的值),则称为小堆(或大堆)。堆排序即利用堆的思想来进行排序

在这里插入图片描述
在这里插入图片描述


二. 堆排序(以升序为例)

思路:

1.将待排序的数组构成一个大堆,此时堆顶元素就是最大的
2.将堆顶元素与最后一个元素交换,此时最后一个元素就是最大值
3.删除最后一个元素(实际上没有删除,只是不再和其它元素一起构成大堆),让其它元素再次构成大堆
4.重复第2、3步:将堆顶元素与最后一个元素(其实是倒数第二个)交换,此时它就是最大值(其实是次大值)……

1
为什么不用小堆?

因为小堆只能保证孩子节点的值>=双亲结点的值,不能保证兄弟节点也是按升序排列的,如:

在这里插入图片描述
从上面我们可以看出,该数组最后并不是升序排列的,因此我们不能构建小堆

2
如何构建大堆?

【数据结构】实现堆
在上篇博客中,我们在实现堆时,在插入函数中用了向上调整的方法,在这里我们同样也可以采用向上调整的方法。插入第二个元素判断位置是否合适,如果该节点的值>双亲结点的值就向上调整,调整结束后,再插入并判断第三个元素是否合适……循环结束,大堆也就构建好了。

在这里插入图片描述

//void AdjustUp(int* a, int child)
//{
//	int parent = (child - 1) / 2;
//	while (child > 0)
//	{
//		if (a[child] > a[parent])
//		{
//			swap(&a[child], &a[parent]);
//			child = parent;
//			parent = (child - 1) / 2;
//		}
//		else
//		{
//			break;
//		}
//	}
//}
for (int i = 1; i < n; i++){AdjustUp(a, i);}

3
将堆顶元素与最后一个元素交换,然后删除最后一个元素(实际上没有删除)

在这里插入图片描述

//void AdjustDown(int* a, int size, int parent)
//{
//	int child = parent * 2 + 1;
//	while (child < size)
//	{
//		if (child + 1 < size && a[child + 1] > a[child])
//		{
//			child++;
//		}
//		if (a[parent] < a[child])
//		{
//			swap(&a[parent], &a[child]);
//			parent = child;
//			child = parent * 2 + 1;
//		}
//		else
//		{
//			break;
//		}
//	}
//}int end = n - 1;//n是数组的元素个数while (end > 0){swap(&a[0], &a[end]);AdjustDown(a, end, 0);end--;}

4
建大堆的另一种思路

上面的2利用了插入思想,从第二个元素插入开始判断位置是否合适,不合适就向上调整,调整结束后,再插入并判断第三个元素是否合适……也就是说,在再次插入元素之前,所有的元素已经构成了大堆,插入元素后,再次调整直到为大堆。那如果我一次性插入所有的元素,此时双亲结点和孩子节点没有任何关系,是否还有方法能建成大堆呢?
在这里插入图片描述
从第一个非叶子节点开始,不断向前移动,直到到根节点,每个节点都向下调整。i = (n - 1 - 1) / 2中,n-1是最后一个节点的索引,(孩子节点-1)/ 2==双亲结点的索引

for (int i = (n - 1 - 1) / 2; i >= 0; i--){AdjustDown(a, n, i);}

5
向上和向下调整建堆的时间复杂度

在这里插入图片描述

在这里插入图片描述

因为向上调整的时间复杂度为O(N*logN),向下调整的时间复杂度为O(N),所以向下调整的方法(上面的4)更好。


三. 代码

#include<stdio.h>
#include<time.h>
#include<stdlib.h>void swap(int* a, int* b)
{int tmp = *a;*a = *b;*b = tmp;
}void AdjustUp(int* a, int child)
{int parent = (child - 1) / 2;while (child > 0){if (a[child] > a[parent]){swap(&a[child], &a[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}
}void AdjustDown(int* a, int size, int parent)
{int child = parent * 2 + 1;while (child < size){if (child + 1 < size && a[child + 1] > a[child]){child++;}if (a[parent] < a[child]){swap(&a[parent], &a[child]);parent = child;child = parent * 2 + 1;}else{break;}}}//升序
void HeapSort(int* a, int n)
{//1.建大堆/*for (int i = 1; i < n; i++){AdjustUp(a, i);}*/for (int i = (n - 1 - 1) / 2; i >= 0; i--){AdjustDown(a, n, i);}//2.排序int end = n - 1;while (end > 0){swap(&a[0], &a[end]);AdjustDown(a, end, 0);end--;}
}int main()
{int a[] = { 2,4,3,1,9,6,7,8 };int n = sizeof(a) / sizeof(int);HeapSort(a, n);for (int i = 0; i < n; i++){printf("%d ", a[i]);}return 0;
}

在这里插入图片描述


好了,那么本篇博客就到此结束了,如果你觉得本篇博客对你有些帮助,可以给个大大的赞👍吗,感谢看到这里,我们下篇博客见❤️

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

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

相关文章

rust入门(1)创建项目

安装 vscode 安装插件 rust-analyzerNative Debug vscode 配置自动格式化代码 settings.json{"editor.defaultFoldingRangeProvider": null,"[rust]": {"editor.defaultFormatter": "rust-lang.rust-analyzer", // Makes the magi…

3. 在Go语言项目中使用Zap日志库

文章目录 一、介绍二、 默认的Go Logger1. 实现Go Logger2. 设置Logger3. 使用Logger4. Logger的运行5. Go Logger的优势和劣势 三、Uber-go Zap1. 为什么选择Uber-go zap2. 安装3. 配置Zap Logger4. 定制logger4.1 将日志写入文件而不是终端4.2 将JSON Encoder更改为普通的Log…

GlusterFS性能调优

转载说明&#xff1a;如果您喜欢这篇文章并打算转载它&#xff0c;请私信作者取得授权。感谢您喜爱本文&#xff0c;请文明转载&#xff0c;谢谢。 相关文章&#xff1a; 分布式存储——GlusterFS 关于GlusterFS的卷 GlusterFS—新手陷阱 GlusterFS常用命令集 GlusterFS系…

时间序列-AR MA ARIMA

一、AR模型(自回归) AR探索趋势和周期性 预测依赖于过去的观测值和模型中的参数。模型的阶数 p pp 决定了需要考虑多少个过去时间点的观测值。 求AR模型的阶数 p和参数 ϕ i \phi_i ϕi​ &#xff0c;常常会使用统计方法如最小二乘法、信息准则&#xff08;如AIC、BIC&#xf…

安全先行,合规的内外网文件摆渡要重点关注什么?

内外网隔离在政府、军工部门、科研单位等已成为很常见的网络安全建设措施&#xff0c;内外网隔离是一种网络安全措施&#xff0c;用于保护内部网络免受外部网络的攻击和威胁。 内外网隔离的目的在于限制内外网之间的通信和数据交换&#xff0c;但网络隔离后&#xff0c;仍有数据…

少儿编程机器人技术开发公司的创新之路

行业背景&#xff0c;国家政策利好 随着科技的不断发展&#xff0c;少儿编程机器人技术作为一种新兴的教育方式逐渐受到人们的关注。这项技术将编程与机器人技术相结合&#xff0c;通过互动性强、趣味性高的方式&#xff0c;帮助儿童学习编程知识&#xff0c;培养逻辑思维和创…

大模型产业落地,安全运营能否迎来“自动驾驶”时刻?

科技云报道原创。 通过一段文字描述&#xff0c;就能生成60秒堪比大片的视频&#xff0c;来自大模型Sora的出色表现&#xff0c;让全球都为之震撼。 无论是ChatGPT还是Sora&#xff0c;都只是大模型走出实验室的第一步&#xff0c;大模型如何在产业中落地&#xff0c;为具体的…

华为CSS堆叠技术介绍与实现

厦门微思网络​​​​​​https://www.xmws.cn 华为认证\华为HCIA-Datacom\华为HCIP-Datacom\华为HCIE-Datacom Linux\RHCE\RHCE 9.0\RHCA\ Oracle OCP\CKA\K8S\ CISP\CISSP\PMP\ ​ 什么是CSS&#xff1f; CSS交换机系统CSS&#xff08;Cluster Switch System&#xff09;&am…

【解决(几乎)任何机器学习问题】:交叉验证

在上⼀章中&#xff0c;我们没有建⽴任何模型。原因很简单&#xff0c;在创建任何⼀种机器学习模型之前&#xff0c;我们必须知道什么是交叉检验&#xff0c;以及如何根据数据集选择最佳交叉检验数据集。 那么&#xff0c;什么是 交叉检验 &#xff0c;我们为什么要关注它&…

云原生基础知识:容器技术的历史

容器化的定义&#xff1a; 容器化是一种轻量级的虚拟化技术&#xff0c;将应用程序及其所有依赖项&#xff08;包括运行时、系统工具、系统库等&#xff09;打包到一个称为容器的单独单元中。容器提供了一种隔离的执行环境&#xff0c;使得应用程序可以在不同的环境中运行&…

【机器人学导论笔记】四、操作臂逆运动学

4.1 本章任务 本章是将思路逆转过来&#xff0c;已知机械臂的位置和姿态&#xff0c;计算关节角&#xff0c;由此即为逆运动学。 这个任务可以分为两个小问&#xff1a;第一&#xff0c;进行坐标系变换&#xff0c;求出相对于基坐标系&#xff5b;B&#xff5d;的腕部坐标系&…

Day37 socket、TCP、UDP

socket类型 流式套接字(SOCK_STREAM) TCP 提供了一个面向连接、可靠的数据传输服务&#xff0c;数据无差错、无重复的发送且按发送顺序接收。内设置流量控制&#xff0c;避免数据流淹没慢的接收方。数据被看作是字节流&#xff0c;无长度限制。 数据报套接字(SOCK_DGRAM) UD…

【设计模式 04】建造者模式

如果要构建的对象很复杂&#xff0c;那么可以将整个构建过程拆分成多个步骤&#xff0c;并为每一个步骤定义一个抽象的接口。并添加一个指导者用来控制构建产品的顺序和步骤。 Java实现&#xff1a; // 产品类 class Product {private String part1;private String part2;pub…

Node.js 最佳实践:改善你的应用程序设计 | 开源日报 No.191

goldbergyoni/nodebestpractices Stars: 92.4k License: CC-BY-SA-4.0 Node.js Best Practices 是一个关于 Node.js 最佳实践的开源项目。该项目汇总了许多顶级内容&#xff0c;包括 80 多个最佳实践、样式指南和架构技巧。以下是该项目的核心优势和主要功能&#xff1a; 提供…

每日一题-合成两个有序链表

&#x1f308;个人主页: 会编辑的果子君 &#x1f4ab;个人格言:“成为自己未来的主人~” 以上是题目信息&#xff1a; 下面是解答过程 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/ typedef struct Lis…

Redis6 搭建主从集群架构

文章目录 搭建Redis主从集群架构1.集群结构2.准备实例和配置3.启动4.开启主从关系5.测试 搭建Redis主从集群架构 安装部署单机版Redis6可参考&#xff1a; 安装部署单机版Redis6 1.集群结构 我们搭建的主从集群结构如图&#xff1a; 我们计划是在一台虚拟机里去部署三个R…

腾讯云轻量服务器Windows系统使用IIS实现公网直链访问文件

windows方便所以服务器装的windows系统&#xff0c;windows默认不能分享文件直链&#xff0c;只要用IIS建个站点就行了 先弄一台有公网ip的windows系统服务器打开服务器管理器&#xff0c;添加这个 打开IIS右键添加网站 程序池默认&#xff0c;路径选个文件夹作为网站根目录 …

css3中nth-child属性作用及用法剖析

hello宝子们...我们是艾斯视觉擅长ui设计和前端开发10年经验!希望我的分享能帮助到您!如需帮助可以评论关注私信我们一起探讨!致敬感谢感恩! 标题&#xff1a;CSS3中nth-child属性作用及用法剖析 摘要&#xff1a;CSS3中的nth-child选择器允许我们根据元素位置来定位特定的元素…

JAVA开发第一个Springboot WebApi项目

一、创建项目 1、用IDEA新建一个SpringBoot项目 注意JDK与Java版本的匹配 2、添加依赖 (1)、Lombok (2)、Spring Web (3)、Mybatis Framework (4)、MySqlDriver 项目中的配置 pom.xml 如下 <?xml version="1.0" encoding="UTF-8"?> …

Idea 开启热部署 Devtools

一、背景 当我们在 idea 中修改代码的时候&#xff0c;idea 并不会自动的重启去响应我们修改的内容&#xff0c;而是需要我们手动的重新启动项目才可以生效&#xff0c;这个是非常不方便&#xff0c;但是可以在 idea 中开启这个自动热部署的功能。 我的 idea 版本为 2022.3.3 。…