堆排序基本思想以及代码实现

news2024/9/20 14:49:34

1、基本思想

堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(n*logn),它也是不稳定排序。
堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆, 注意 : 没有要求结点的左孩子的值和右孩子的值的大小关系。
每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆(此题用小顶堆)

另外要注意,堆要用数组来储存

堆排序基本思想是:

将待排序序列构造成一个小顶堆
此时,整个序列的最大值就是堆顶的根节点。
将其与末尾元素进行交换,此时末尾就为最大值。
然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了。
可以看到在构建大顶堆的过程中,元素的个数逐渐减少,最后就得到一个有序序列了2、

2、代码实现

#include<iostream>
using namespace std;

void FelterDown(int* data, int start, int end)
{
	int i = start, j = 2 * i + 1;
	int tmp = data[i];
	while (j <= end)
	{
		if (j<end && data[j]>data[j + 1])
		{
			j++;
		}
		if (tmp <= data[j]) break;
		data[i] = data[j];
		i = j;
		j = 2 * i + 1;
	}
	data[i] = tmp;
}
void HeapSort(int* ar, int n)
{
	int pos = (n - 2) / 2;
	while (pos >= 0)
	{
		FelterDown(ar, pos, n - 1);
		pos--;
	}
	int j = n - 1;
	while (j >= 0)
	{
		swap(ar[0], ar[j]);
		j--;
		FelterDown(ar, 0, j);
	}
}
void Print(int* arr, int n)
{
	for (int i = 0; i < n; i++)
	{
		cout << arr[i] << " ";
	}
	cout << endl;
}
int main()
{
	int ar[] = { 12,34,45,67,78,8 };
	int n = sizeof(ar) / sizeof(ar[0]);
	HeapSort(ar, n);
	Print(ar, n);
	return 0;
}

3、堆排序算法的常见问题
 

最坏情况性能:
堆排序的最坏情况时间复杂度是O(n log n),但这是在特定输入下才会发生的,例如输入数组已经是完全逆序的。在大多数实际应用中,堆排序的性能通常接近最优。
避免方法:由于堆排序的最坏情况并不常见,通常不需要特别避免。如果确实关心最坏情况性能,可以考虑使用其他算法,如快速排序或归并排序。

非稳定排序:
堆排序不是稳定的排序算法,这意味着相等的元素在排序后可能会改变它们的原始顺序。
避免方法:如果稳定性是必需的,可以考虑使用稳定的排序算法,如归并排序或插入排序。

原地排序的空间复杂度:
堆排序是原地排序算法,它不需要额外的存储空间,但需要空间来维护堆结构,这可能会对内存使用产生影响。
避免方法:如果内存使用是一个问题,可以考虑使用其他原地排序算法,如快速排序。

构建初始堆的时间开销:
在堆排序中,构建初始堆的时间复杂度是O(n),这可能会增加算法的总体时间开销。
避免方法:对于小规模数据集,构建初始堆的开销可能不是问题。对于大规模数据集,可以考虑使用其他排序算法,或者优化堆的构建过程。

递归实现的栈空间限制:
堆排序的递归实现可能会因为数据集过大而导致栈溢出。
避免方法:可以使用非递归版本的堆排序来避免这个问题,或者使用尾递归优化的版本。

数据局部性:
堆排序在操作过程中可能会破坏数据的局部性,这可能会影响缓存的性能。
避免方法:对于需要高缓存性能的应用,可以考虑使用其他具有更好数据局部性的排序算法,如插入排序或归并排序。

不适合小数据集:
由于构建堆和堆调整的开销,堆排序在小数据集上的性能可能不如一些简单的排序算法,如插入排序或选择排序。
避免方法:对于小数据集,可以使用更简单的排序算法,或者设置一个阈值,在数据集大小小于该阈值时使用简单排序算法。

代码复杂度:
堆排序的实现相对复杂,特别是对于不熟悉堆数据结构的开发者。
避免方法:可以使用标准库提供的排序函数,这些函数通常已经优化过,并且能够处理各种复杂情况。

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

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

相关文章

Vue3路由如何携带 # 路由模式选择

vue3中创建路由的时候&#xff0c;有两种可选模型 hash模式、HTML5模式、服务端渲染模式 createWebHashHistory&#xff08;hash模式&#xff09; const router createRouter({// hash模式&#xff0c;带 # 号history: createWebHashHistory(), //函数可携带参数&#xff0c;…

C++11 容器emplace方法刨析

如果是直接插入对象 push_back()和emplace_back()没有区别但如果直接传入构造函数所需参数&#xff0c;emplace_back()会直接在容器底层构造对象&#xff0c;省去了调用拷贝构造或者移动构造的过程 class Test { public:Test(int a){cout<<"Test(int)"<<…

使用Web控制端和轻量级客户端构建的开放Web应用防火墙(OpenWAF)

目录 1. 简介2. 项目结构3. Web控制端3.1. 功能概述3.2. 审计&#xff08;攻击&#xff09;日志查看3.3. 多个WAF的集中监控和操作3.4. 使用socket进行封装3.5. 日志的高效存储和检索&#xff08;Redis&#xff09; 4. 轻量级客户端4.1. 功能概述4.2. 对Web程序的防护4.3. 网络…

36.UART(通用异步收发传输器)-RS232(3)

&#xff08;1&#xff09;串口发送模块visio视图&#xff1a; &#xff08;2&#xff09;串口发送模块Verilog代码: /* 常见波特率&#xff1a; 4800、9600、14400、115200 在系统时钟为50MHz时&#xff0c;对应计数为&#xff1a; (1/4800) * 10^9 /20 -1 10416 …

鸿蒙语言基础类库:【@system.vibrator (振动)】

振动 说明&#xff1a; 本模块首批接口从API version 4开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。从API Version 8开始&#xff0c;该接口不再维护&#xff0c;推荐使用新接口[ohos.vibrator]。该功能使用需要对应硬件支持&#xff0c;仅支持…

学生信息管理系统-优化版

springbootthymeleafmybatis 记录一下闲来无事&#xff0c;将之前做的1.0页面优化。 一、【管理员】首页 1、增加了【批量删除】、【导出学生信息】、【分页】、【统计及格率、平均分、优秀率】等功能。 2、将页面样式优化了一下&#xff0c;做的好看些 原来&#xff1a; 现…

.NET C# 配置 Options

.NET C# 配置 Options 使用 options 模式可以带来许多好处&#xff0c;包括清晰的配置管理、类型安全、易于测试和灵活性。但在使用过程中&#xff0c;也需要注意配置复杂性、性能开销和依赖框架等问题。通过合理设计和使用&#xff0c;可以充分发挥 options 模式的优势&#…

【链表】算法题(二) ----- 力扣/牛客

一、链表的回文结构 思路&#xff1a; 找到链表的中间节点&#xff0c;然后逆置链表的后半部分&#xff0c;再一一遍历链表的前半部分和后半部分&#xff0c;判断是是否为回文结构。 快慢指针找到链表的中间节点 slow指针指向的就是中间节点 逆置链表后半部分 逆置链表后半部分…

【JavaScript 算法】图的遍历:理解图的结构

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 一、深度优先搜索&#xff08;DFS&#xff09;深度优先搜索的步骤深度优先搜索的JavaScript实现 二、广度优先搜索&#xff08;BFS&#xff09;广度优先搜索的步骤 三、应用场景四、总结 图的遍历是图论中的基本操作之一&am…

安卓 mvp 的架构的详细介绍

MVP 架构介绍 MVP&#xff08;Model-View-Presenter&#xff09;是一种软件架构模式&#xff0c;常用于构建用户界面&#xff08;UI&#xff09;。它将应用程序的逻辑划分为三个部分&#xff1a;Model、View 和 Presenter。MVP 的主要目标是分离视图和业务逻辑&#xff0c;使代…

ECU通讯:CAN总线仿真测试

01.ECU 在软件定义汽车的大背景下&#xff0c;几乎每一个汽车功能都需要依靠ECU&#xff08;Electronic Control Unit&#xff0c;电子控制单元&#xff09;来实现&#xff1a;有些功能靠ECU独立实现&#xff0c;有些功能则需要多个ECU联合实现。总体来说&#xff0c;ECU绝大多…

解决SonarQube中Vue项目中deep选择器报错的问题

1. 前言 当使用SonarQube对Vue项目进行代码质量审查时&#xff0c;可能会遭遇因Vue特有的deep选择器&#xff08;旨在实现样式深度穿透&#xff09;而触发的错误或警告。由于SonarQube默认并不识别这一Vue特有的语法&#xff0c;这些错误报告可能会成为审查过程中的干扰项。为了…

Mysql sql技巧与优化

1、解决mysql同时更新、查询问题 2、控制查询优化 hint 3、 优化 特定类型的查 优化 COUNT() 查询 使用 近似值 业务能接受近似值的话&#xff0c;使用explain拿到近似值 优化关联查询 优化子查询 4、优化group by和distinct 优化GROUP BY WITH ROLLUP 5、优化 limit分页 其他…

【MySQL-19】一文带你了解存储函数

前言 大家好吖&#xff0c;欢迎来到 YY 滴MySQL系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; YY的《C》专栏YY的《C11》专栏YY的《Lin…

Richteck立锜科技电源管理芯片简介及器件选择指南

一、电源管理简介 电源管理组件的选择和应用本身的电源输入和输出条件是高度关联的。 输入电源是交流或直流&#xff1f;需求的输出电压比输入电压高或是低&#xff1f;负载电流多大&#xff1f;系统是否对噪讯非常敏感&#xff1f;也许系统需要的是恒流而不是稳压 (例如 LED…

应届生软件测试面经_一名应届生的软件测试面试题目

1.你为什么选择软件测试行业 因为之前有了解软件测试这个行业&#xff0c;觉得他的发展前景很好&#xff0c; 2.根据你以前的项目经验描述一下软件开发、测试过程&#xff0c;由那些角色负责&#xff0c;你做什么 要有架构师、开发经理、测试经理、程序员、测试员。我在里面…

什么是死锁 , 以及产生的原因详细介绍

死锁 一. 什么是死锁 指的是两个或者两个以上的线程在执行的过程中由于竞争同步锁而产生的一种阻塞现象;如果没有外力的作用,他们将无法继续执行下去,这种情况称之为死锁, 通俗的说死锁产生的原因主要是由于线程的相互等待 , 导致程序无法进行下去 二. 代码阐述 这里我们写…

科技论文在线--适合练习期刊写作和快速发表科技成果论文投稿网站

中国科技论文在线这个平台可以作为练手的一个渠道&#xff0c;至少可以锻炼一下中文写作&#xff0c;或者写一些科研方向的简单综述性文章。当然&#xff0c;如果你的老师期末要求也是交一份科技论文在线的刊载证明的话&#xff0c;这篇文章可以给你提供一些经验。 中国科技论…

数据结构 - 队列(精简介绍)

文章目录 单端队列单端队列操作&#xff1a;Queue实现 双端队列双端队列操作&#xff1a;Deque实现 循环队列循环队列手动实现 优先级队列Q 不断取最大礼物并开方 单端队列 普通队列为单端队列&#xff0c;先进先出&#xff08;FIFO&#xff09; 只能从尾部插入&#xff0c;头…

jscolor 赋值input 没能引起前边色框的颜色变化

&#x1f3c6;本文收录于《CSDN问答解答》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&…