数据结构与算法_堆排序

堆排序,即利用堆的思想来进行排序。要实现堆排序,首先要建堆,建堆又分为建大堆和建小堆;然后再一步一步地删除堆的元素来进行排序。

目录

一、堆排序的时间复杂度

二、建堆

向上调整

向下调整

三、堆排序

四、代码实现

向上调整

向下调整

堆排序


一、堆排序的时间复杂度

相比冒泡排序,它的时间复杂度为O(N^2),堆排序的时间复杂度为O(N*logN)。优点就在此。

假如现在要分别对1000个和1000000个数据进行排序,那么

N冒泡排序堆排序
1000100000010000
10000001E+1220000000

可见,堆排序的次数更少,更能有效节省时间。

二、建堆

建堆有两种,分别是向上建堆和向下建堆,应该根据需求建大堆或是小堆。

向上调整

以建小堆为例,2是新插入的数据,让他和父节点5比较,发现父节点比它大,就交换。

然后再和新的父节点1比较,发现新的父节点比它小,就不需要再进行交换了。

再以建大堆为例,这是一个无序的数组:

它们的逻辑结构如下:

现对它进行向上调整,建大堆,通过调试可以发现,数组元素的值有所改变:

最终,它的逻辑结构如下:

以建小堆为例,向上调整思想如下:

①将要插入的数据与其父节点数据比较

②若子节点数据小于父节点数据,则交换

若子节点数据大于父节点数据,则不交换,不需要调整,已经满足堆的结构

建大堆只是比较大小有所不同。

向下调整

向下调整的一个重要前提是左右子树必须是堆,如图所示:

 以建小堆为例:

 首先让父节点27和第一个子节点比较大小,发现父节点比子节点大,那么两者交换;

让27和它的第一个子节点比较,发现父节点又比子节点大,那么两者再次交换;

27和它的第一个子节点比较大小,发现第一个子节点比父节点大,那么不交换,让父节点和第二个子节点比较大小,发现父节点比第二个子节点大,那么让两者进行交换。

到了叶子节点了,叶子节点没有子节点,停止比较。最终得到了小堆。

以建成小堆为例,向下调整的思想如下:

①从根节点开始,选出左右孩子节点中值较小的一个

②让父亲与较小的孩子比较

若父亲大于此孩子,那么交换

若父亲小于此孩子,则不交换

③结束条件

1、父亲<=小的孩子则停止

2、调整到叶子节点,(叶子节点特征为没有左孩子,就是数组下标超出了范围,就不存在了)

三、堆排序

堆排序思想如下:

以升序为例,堆排序的思想如下:

①将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。

②将其与末尾元素进行交换,此时末尾就为最大值。

③然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了。

四、代码实现

向上调整

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

向下调整

void AdjustDown(int *a,int parent,int n)
{int child = parent * 2 + 1;while (child < n){if (child + 1 < n && a[child + 1] < a[child]){child++;}if (a[child] < a[parent]){Swap(&a[child], &a[parent]);parent = child;child = parent * 2 + 1;}else{break;}}
}

不论是向上调整还是向下调整,要想建立大堆或小堆,关键在父节点和子节点比较时的符号,可自行修改。

堆排序

void HeapSort(int* a, int n)
{// 建堆 -- 向上调整建堆 -- O(N*logN)/*for (int i = 1; i < n; ++i){AdjustUp(a, i);}*/// 建堆 -- 向下调整建堆 -- O(N)for (int i = (n - 1 - 1) / 2; i >= 0; --i){AdjustDown(a, n, i);}int end = n - 1;while (end > 0){Swap(&a[end], &a[0]);AdjustDown(a, end, 0);--end;}
}

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

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

相关文章

【案例实战】高并发业务的多级缓存架构一致性解决方案

我们在高并发的项目中基本上都离不开缓存&#xff0c;那么既然引入缓存&#xff0c;那就会有一个缓存与数据库数据一致性的问题。 首先&#xff0c;我们先来看看高并发项目里面Redis常见的三种缓存读写模式。 Cache Aside 读写分离模式&#xff0c;是最常见的Redis缓存模式&a…

react菜鸟教程学习笔记

目录 第一个react实例 react安装 对react机制最直观的理解 如果你第一次用npm 关于初始化package.json的问题 使用 create-react-app 快速构建 React 开发环境 项目目录结构 修改一下代码执行源头APP.js React元素渲染 将元素渲染到DOM中 更新元素渲染 关于vue的更新…

golang 结构体struct转map实践

1、反射 type sign struct { Name string json:"name,omitempty" Age int json:"age,omitempty" } var s sign s.Name "csdn" s.Age 18 //方式1 反射 var data make(map[string]interface{}) t : reflect.TypeOf(s) v : …

记录使用ffmpeg把mp4转换成m3u8

背景:公司需要上一些视频资源,平均每一个都在600m以上,经过考虑以后采取视频分片以后上传到oss上进行加速播放的流程.这里记录一下使用ffmpeg进行转换视频格式的过程中的一些命令. 准备工作: 下载ffmpeg到本地,以及配置ffmpeg到环境变量中,这里就不多说了. 使用的时候先打开…

【IMX6ULL驱动开发学习】14.Linux驱动开发 - GPIO中断(设备树 + GPIO子系统)

代码自取【14.key_tree_pinctrl_gpios_interrupt】&#xff1a; https://gitee.com/chenshao777/imx6-ull_-drivers 主要接口函数&#xff1a; 1. of_gpio_count&#xff08;获得GPIO的数量&#xff09; static inline int of_gpio_count(struct device_node *np)2. kzalloc…

用四元数表示旋转

旋转四元数以及如何使用它们 英文版参考链接:Quaternions 四元数&#xff0c;它是一种用四个实数表示复数的推广&#xff0c;可以用来高效地表示和计算三维空间中的旋转1。 旋转四元数的性质: All rotation quaternions must be unit quaternions.|q| 1For rotation quater…

Elasticsearch:使用 Redis 让 Elasticsearch 更快

Elasticsearch 是一个强大的搜索引擎&#xff0c;可让你快速轻松地搜索大量数据。但是&#xff0c;随着数据量的增长&#xff0c;响应时间可能会变慢&#xff0c;尤其是对于复杂的查询。在本文中&#xff0c;我们将探讨如何使用 Redis 来加快 Elasticsearch 搜索响应时间。 Re…

台阶仪是干什么的?在太阳能光伏行业能测什么?

太阳能作为应用广、无排放、无噪声的环保能源&#xff0c;在近些年迎来快速发展&#xff0c;而在各类型的太阳能电池及太阳能充电系统中&#xff0c;多会镀一层透明的ITO导电薄膜&#xff0c;其镀膜厚度对电池片的导电性能有着非常重要的影响&#xff0c;因而需要对镀膜厚度进行…

C/C++指针内存泄漏的原因详解及如何避免与问题定位

作为C/C开发人员&#xff0c;内存泄漏是最容易遇到的问题之一&#xff0c;这是由C/C语言的特性引起的。C/C语言与其他语言不同&#xff0c;需要开发者去申请和释放内存&#xff0c;即需要开发者去管理内存&#xff0c;如果内存使用不当&#xff0c;就容易造成段错误(segment fa…

Learn Mongodb 可是工具及基本命令的使用 ③

作者 : SYFStrive 博客首页 : HomePage &#x1f4dc;&#xff1a; PHP MYSQL &#x1f4cc;&#xff1a;个人社区&#xff08;欢迎大佬们加入&#xff09; &#x1f449;&#xff1a;社区链接&#x1f517; &#x1f4cc;&#xff1a;觉得文章不错可以点点关注 &#x1f44…

【H5】文件上传(ajax)

系列文章 【移动设备】iData 50P 技术规格 本文链接&#xff1a;https://blog.csdn.net/youcheng_ge/article/details/130604517 【H5】avalon前端数据双向绑定 本文链接&#xff1a;https://blog.csdn.net/youcheng_ge/article/details/131067187 【H5】安卓自动更新方案&a…

【Python实战】Python采集某大夫文字数据

前言 今天&#xff0c;有一位粉丝找到我&#xff0c;希望我出一期关于某大夫数据采集的文章&#xff0c;今天&#xff0c;我们就来采集某大夫的问诊数据。 环境使用 python 3.9pycharm 模块使用 requests 模块介绍 requests requests是一个很实用的Python HTTP客户端库&…