选择排序(直接选择排序与堆排序)----数据结构-排序②

1、选择排序

1.1 基本思想

        每一次从待排序的数据元素中选出最小(或最大)的一个元素,放在序列的起始位置,直到全部待排序的数据元素排完就停止 。

1.2 直接选择排序

排序思想:

①在元素集合array[i]--array[n-1]中选择数值最大(小)的数据元素。

②若它不是这组元素中的最后一个(第一个)元素,则将它与这组元素中的最后一个(第一个)元素交换,使最大(最小)的元素来到数据的最后(开始)。

③在剩余的array[i]--array[n-2](array[i+1]--array[n-1])集合中,重复上述步骤,直到集合剩余1个元素。

动图演示:

 动图解释:

①遍历区间 [ 0, n-1 ] 的所有数,选出最小的数放到我们所遍历区间的最左端,第一次遍历区间最左端是0。

②遍历区间 [ 1, n-1 ] 的所有数,选出最小的数放到我们所遍历区间的最左端,第而二次遍历区间最左端是1。

③不断重复上述步骤,直至区间内的元素个数为一个时,停止遍历。

代码实现:

void Swap(int* p1, int* p2)
{
	int tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}


void SelectSort2(int* a, int n)
{
	int begin = 0, end = n - 1;
	// 区间为 [begin , end]
	while (begin < end)  // 当 begin == end 时,表明区间内还剩一个元素,停止遍历
	{
		// 假设最小值都为区间的最左端元素
		int mini = begin;

		for (int i = begin + 1; i <= end; i++)
		{
			// 在区间内遇到更小的数就更新 mini
			if (a[i] < a[mini])
				mini = i;
		}
		// 第一次遍历结束,mini位置的值为该区间的最小值 
		Swap(&a[begin], &a[mini]);// 将最小值放到该区间的最左端

		// 缩小区间的长度
		begin++;
	}
}

代码优化:

        实际上在每一次的遍历中,我们不仅可以选出最小值放到区间的最左端,同时我们还可以选出最大值放到区间的最右端,这样可以减少我们的遍历次数。 

优化代码实现:

void Swap(int* p1, int* p2)
{
	int tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}

void SelectSort(int* a, int n)
{
	int begin = 0, end = n - 1;
	// 区间为 [begin , end]
	while(begin < end)  // 当 begin == end 时,表明区间内还剩一个元素,停止遍历
	{
		// 假设最大值与最小值都为区间最左端元素
		int maxi = begin, mini = begin;
		for (int i = begin + 1; i <= end; i++)
		{
			// 在区间内遇到更大的数就更新 maxi
			if (a[i] > a[maxi])
				maxi = i;

			// 在区间内遇到更小的数就更新 mini
			if (a[i] < a[mini])
				mini = i;
		}
		// 第一次遍历结束,maxi、mini位置的值为该区间的最大值与最小值 
		Swap(&a[begin], &a[mini]);// 将最小值放到该区间的最左端

		// 当我们的区间最大值位于 begin 位置时,即maxi = begin时
		//因为我们上面的交换,导致begin位置的值已经被换到 mini 位置
		//所以现在最大值的下标是 mini

		if (maxi == begin)//当最大的数据在 begin 位置时,
			maxi = mini; 

		Swap(&a[end], &a[maxi]); // 将最大值放到该区间的最右端

		// 缩小区间的长度
		begin++;
		end--;
	}
}

 直接选择排序的特性总结:

1. 直接选择排序思考非常好理解,但是效率不是很好。实际中很少使用

2. 时间复杂度:O(N^2)

3. 空间复杂度:O(1)

4. 稳定性:不稳定

不稳定的原因:当数组已经接近有序或已经完全有序时,每一次还是会进行找大找小,这样就会导致时间上的巨大浪费。

1.3 堆排序

       堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种,但相较于直接选择排序来说提升了许多 。它是通过堆(完全二叉树)来进行选择数据。需要注意的是排升序要建大堆,排降序建小堆。(如果还未学习堆的同学,可以移步到我的上一篇文章,里面有堆的详细介绍)

堆排序的排序思想:

如果我们想利用堆排升序:

①首先我们需要建立一个有N个数据的大堆;

②将堆顶的数据(最大)与最后一个数据(下标是N-1)交换,此时我们最大的数据就来到了最后(N-1的位置),这时我们就不用再需要去考虑最后一个元素了,因为最后一个元素已经是最大;

③再对前N-1个数据再次进行堆排序即可。

注意:此刻交换到堆顶的数据并不一定满足大堆的性质,所以还需要对堆顶的数据进行向下调整,使得满足大堆的性质。
 

示意图:


void Swap(HPDataType* p1, HPDataType* p2)
{
	HPDataType tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}
 
void AdjustDown(HPDataType* a, int size,int parent)
{
	int child = 2 * parent + 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 = 2 * parent + 1;
		} 
		else     // 如果父节点更大表明不用再交换了 ,跳出循环
		{
			break;
		}
	}
}
 
void HeapSort(int* a, int n)
{
	// 利用向下调整算法建立一个大堆
	for (int i = (n - 1-1) / 2; i >= 0; i--)  // n-1 是最后一个节点,(n-1-1)/2就是第一个非叶子节点
	{
		AdjustDown(a, n,i);
	}
    int end = n-1;  // end 表示最后一个元素的下标
	while(end>0)  //如果数据个数大于1个,才进行排序
	{
		Swap(&a[0], &a[end]);   // 堆顶与最后一个元素进行交换
		AdjustDown(a, end, 0); // 将堆顶的数据向下调整
		end--;           // 每排好一个就不用再考虑最后一个元素,相当与堆的数据减少一个
	}
}

堆排序的特性总结: 

1. 堆排序使用堆来选数,效率就高了很多

2. 时间复杂度:O(N*logN)

3. 空间复杂度:O(1)

4. 稳定性:不稳定

不稳定的原因与直接选择排序类似,当数组已经有序或接近有序时,还需要建堆从而导致已经有序或接近有序的数据又会被从新打乱进行排序,同样会造成时间上的浪费。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java项目如何外发告警日志到企业微信

前言 最近领导交代了一个需求,就是有些许客户不单单满足平台告警日志外发到邮箱、短信的形式,还要以消息聊天的形式外发给企业微信。 具体操作 1、注册企业微信。 2、登录企业微信,找到应用管理,创建应用。 3、创建完之后需要记录以下图片中两个值的信息。 4、然后记录下…

stanfordcorenlp+python做中文nlp任务,得到的结果中全是空字符串,而不是中文字符串

问题描述 代码&#xff1a; from stanfordcorenlp import StanfordCoreNLP import logging#中文中的应用&#xff0c;一定记得下载中文jar包&#xff0c;并标志lang‘zh’ nlp_zh StanfordCoreNLP(rD:\stanford-corenlp-full-2016-10-31, port8094, langzh,quietFalse,logg…

【排序算法】总结篇

✨✨这些 排序算法都是指的 需要进行比较的排序算法 ✨✨下面都是略微讲解一下思路&#xff0c;如果需要详细了解哪一个排序&#xff0c;点击&#x1f449;链接即可 ✨✨对于时间、空间复杂度、稳定性&#xff0c;希望你&#x1f9d1;‍&#x1f393;能够理解记忆&#x1f9d1;…

SpeedyBee飞塔F405 V3 50A

遥控器常用的几种协议&#xff1a; 一文打尽PWM协议、PPM协议、PCM协议、SBUS协议、XBUS协议、DSM协议 | STM32的通用定时器TIM3实现PPM信号输出 - 蔡子CaiZi - 博客园 (cnblogs.com) SpeedyBee飞塔的官方教程&#xff1a; FlowUs 息流 - 新一代生产力工具 为8位电调刷写固…

【纯血鸿蒙】——自适应布局如何实现?

界面级一多能力有 2 类&#xff1a; 自适应布局: 略微调整界面结构 响应式布局&#xff1a;比较大的界面调整 本文章先主要讲解自适应布局&#xff0c;响应式布局再后面文章再细讲。话不多说&#xff0c;开始了。 自适应布局 针对常见的开发场景&#xff0c;方舟开发框架提…

融合创新:Web3如何重新定义网络生态

随着区块链技术的不断发展和Web3时代的到来&#xff0c;我们正在见证着互联网生态的巨大变革。Web3将传统的互联网架构转变为去中心化、开放、透明的新网络生态&#xff0c;为创新和合作提供了全新的可能性。本文将深入探讨Web3如何重新定义网络生态&#xff0c;探索融合创新的…

HAL STM32F1 通过查表方式实现SVPWM驱动无刷电机测试

HAL STM32F1 通过查表方式实现SVPWM驱动无刷电机测试 &#x1f4cd;相关篇《基于开源项目HAL STM32F4 DSP库跑SVPWM开环速度测试》 ✨针对STM32F1系列&#xff0c;没有专门的可依赖的DSP库&#xff0c;为了实现特定函数的浮点运算快速计算&#xff0c;通过查表方式来实现&#…

搭建多平台比价软件你必须知道的几大知识板块

为了搭建一个多平台比价系统并使其发挥作用&#xff0c;你需要考虑以下几个关键的平台支持方面&#xff1a; 数据API采集平台&#xff1a; 电商平台&#xff1a;如亚马逊、淘宝、京东等&#xff0c;这些平台提供了丰富的商品信息和价格数据。旅行服务平台&#xff1a;如携程、…

git凭证

默认是manager # 将凭证缓存到内存中&#xff0c;默认缓存15分钟 git config --global credential.helper cache# 将凭证存储到磁盘上的纯文本文件中 git config --global credential.helper store# 使用 Git 凭证管理器 git config --global credential.helper manager-core查…

红队神器Evil-winrm的使用

前言 Evil-winrm 工具最初是由 Hackplayers 团队开发的。开发该工具的目的是尽可能简化渗透测试&#xff0c;尤其是在 Microsoft Windows 环境中。 Evil-winrm 使用 PowerShell 远程协议 (PSRP)&#xff0c;且系统和网络管理员经常使用Windows Remote Management 协议进行上传和…

C++基础四:C++模板编程

目录 一:函数模板 二:类模板 空间配置器allocator 一:函数模板 模板代码只能同一实现,不能先声明,再在另一文件实现,模板代码都是放在头文件当中的,在头文件中直接实现 二:类模板 template<typename T=int> class SeqStack // 模板名称+类型参数列表 = 类名称…

2024 年最全的 21 款数据恢复工具软件汇总

使用其中任何一款免费数据恢复工具&#xff0c;您都可以找回那些您认为已经永远消失的文件。我根据这些程序对我而言的易用性和它们提供的功能对这些程序进行了排名。 这些应用程序从您的硬盘、USB 驱动器、媒体卡等恢复文档、视频、图像、音乐等。我建议每个计算机所有者都安装…

list模拟与实现(附源码)

文章目录 声明list的简单介绍list的简单使用list中sort效率测试list的简单模拟封装迭代器insert模拟erase模拟头插、尾插、头删、尾删模拟自定义类型迭代器遍历const迭代器clear和析构函数拷贝构造&#xff08;传统写法&#xff09;拷贝构造&#xff08;现代写法&#xff09; 源…

C盘满了怎么办,Windows11的C盘没有磁盘清理选项怎么办,一次搞定

问题&#xff1a; 太久没清电脑了&#xff0c;满的跟垃圾堆一样。。。C盘红色看上去很不妙。 一. C盘满了怎么办&#xff1a; 1. 删除临时文件 找到 C:\Windows\Temp&#xff0c;进入Temp资料夹&#xff0c;选中所有文件夹和文件&#xff0c;按下ShiftDelete键&#xff0c;彻…

张宇1000和李林880究竟哪个更难?

24李林跌落神坛&#xff0c;张宇一战封神&#xff01; 张宇1000和李林880&#xff0c; 谁的基础篇更“超纲”&#xff1f; 谁覆盖的知识点更多&#xff1f; 谁的概念题更多&#xff1f; 谁的“强化难度”题更难&#xff1f; 基础篇里为什么有“跨专题”的题&#xff0c;都…

SpringBoot Elasticsearch07-以黑马商场为例-黑马程序员学习笔记

06篇已经导入了大量数据到elasticsearch中&#xff0c;实现了商品数据的存储。不过查询商品数据时依然采用的是根据id查询&#xff0c;而非模糊搜索。 接下来研究下elasticsearch的数据搜索功能。Elasticsearch提供了基于JSON的DSL&#xff08;Domain Specific Language&#…

简单通用的系统安装、备份、还原方法,支持 ARM 系统【Ventory+FirePE+DiskGenius】

文章目录 0. 简介1. 制作 Ventory 启动盘1.1. 下载 Ventory1.2. 制作 Ventory 启动盘 2. 添加 FirePE 等系统镜像到启动盘2.1. 下载 FirePE2.2. 导出 .iso 系统镜像文件2.3. .iso 系统镜像文件添加至启动盘 3. 启动 FirePE 等系统镜像3.1. 在 bios 中选择启动盘启动3.2. 启动系…

“安全生产月”专题报道:AI智能监控技术如何助力安全生产

今年6月是第23个全国“安全生产月”&#xff0c;6月16日为全国“安全宣传咨询日”。今年全国“安全生产月”活动主题为“人人讲安全、个个会应急——畅通生命通道”。近日&#xff0c;国务院安委会办公室、应急管理部对开展好2024年全国“安全生产月”活动作出安排部署。 随着科…

本地部署GLM-4-9B清华智谱开源大模型方法和对话效果体验

GLM-4-9B是清华大学和智谱AI推出的最新一代预训练模型GLM-4系列中的开源版本。在语义、数学、推理、代码和知识等多方面的数据集测评中&#xff0c;GLM-4-9B及其人类偏好对齐的版本GLM-4-9B-Chat均表现出较高的性能&#xff0c;其通用能力评测结果甚至超越了Llama-3-8B开源大模…

MPC控制简化版

MPC控制算法简化版 模型预测控制&#xff08;Model Predictive Control&#xff0c;MPC&#xff09;是一种先进的控制策略&#xff0c;广泛应用于人形机器人的运动控制。具体实现过程中&#xff0c;还需结合机器人的实际动力学模型和更多的物理约束条件。以下是一个人形机器人…