排序(插入,希尔,堆排,冒泡)

news2024/9/28 12:27:14

常见的排序算法:
在这里插入图片描述

插入排序:
直接插入排序:是一种简单的插入排序法,其基本思想是:把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列 。保证插入之前的数组是有序的,插入后也保证是有序的。时间复杂度:原数组如果和需要排的顺序逆序的时候是最坏的情况,O(N^2),和冒泡排序时间复杂度相同。最好的情况是O(N),顺序有序。

// 直接插入插入排序
void InsertSort(int* a, int n)
{
	//多趟排序
	for(int i = 0; i < n-1; ++i) // 当n = n-2时,插入的就是第n-1的位置的值,就完成了n个数的插入。
	{
		// 单趟排序 把tmp插入数组[0,end]的有序区间
		int end = i; // 从后往前判断,end 就是当前判断的最后一个值
		int tmp = a[end + 1]; // end外面要插入的数据
		while(end >= 0) // 从后往前,end--
		{
			if(tmp < a[end])
			{
				a[end + 1] = a[end]; //让end位置的值放在end+1的位置
				end--; 
			}
			else
				break; // 说明tmp >= a[end-1]
		}
		a[end + 1] = tmp; // 需要在end-1的后面 也就是end+1的位置存放tmp
	}
} 

希尔排序:再插入排序的基础上,让数组首先接近于有序。也就是1.预排序 ->让数组接近有序,2.直接插入排序。
预排序 ->先分组,对分组的数据进行插入排序。间隔为gap的分成一组,对一组进行插入排序。
蓝色的整体为一组,红色的整体为一组,绿色的整体为一组。每次比较的时候只比较各自颜色指向的数字,以蓝色为例,也就是9,5,8,5相比较后进行排序。
gap越大,说明大的数和小的数可以更快的挪到对应的位置,但gap越大越不接近有序。gap越小则相反。
如果gap==1,则就是直接插入排序。排序的规则就是gap = 5, gap = 3, gap = 1来三次就完成希尔排序。
希尔排序的时间复杂度不好计算,需要进行推导,推导出来平均时间复杂度: O(N^1.3- N^2)
在这里插入图片描述

 // 希尔排序
void ShellSort(int* a, int n)
{
	int gap = n;
	// 整个循环最坏是O(N*log3(N))
	while(gap > 1) // n/3/3/3/3/../3 = 1截至 -> 3^x = n, x = log3(N)就是while的次数
	{
		gap = (gap / 3 + 1); //这样可以保证gap最后一次是1。
		// i<n-gap 则对应上图的话就到蓝色8这个位置,i一直加到这个位置可以把蓝色红色和绿色全部处理完。
		// 也就是 先蓝色,再红色,再绿色,再蓝色,再红色,再绿色,再蓝色(8这个位置)就完了。因为后面红色绿色只有一个数。
		// gap很大时是预排序让它接近有序,就是O(N)。
	    // gap很小时,本应该是O(N*N),但是经过了预排序,数组很接近有序,所以也接近于O(N)
	    // 因此,这个for循环就是O(N)
		for(int i = 0; i < n-gap; ++i) 
		{
			int end = i;
			int tmp = a[end + gap]; //要插入的值
			while(end >= 0) // 间隔为gap的排序,类似于直接插入排序(间隔为1)
			{
				if(tmp < a[end])
				{
					a[end + gap] = a[end];
					end -= gap;
				}
				else
					break;
			}
			a[end + gap] = tmp;
		}
	}
}

直接选择排序:在数组中直接选择最大的,次大的放到相应位置直接排。

void Swap(int* p1, int* p2)
{
	int tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}
// 选择排序 O(N^2) 无论如何都会遍历一遍选择数
void SelectSort(int* a, int n)
{
	// 将最小的放在最左边,最大的放在最右边,让左右位置往中间夹
	int left = 0;
	int right = n-1;
	while(left < right)
	{
		int minIndex = left, maxIndex = left;
		for(int i=left; i<right; ++i)
		{
			if(a[i] < a[minIndex]) // 选出最小的
				minIndex = i;
			if(a[i] > a[maxIndex]) //选出最大的
				maxIndex = i;
		}
		Swap(&a[left], &a[minIndex]); 
		//如果最大值在left位置,上面交换后max就被换走了 换到minIndex的位置去了 修正位置。
		if(left == maxIndex) 
		{
			maxIndex = minIndex;
		}
		Swap(&a[right], &a[maxIndex]);
		++left;
		--right;
	}
}

堆排序:先得有个堆然后再选择出放到特定位置的选择排序方法。
堆排序的详细介绍

void Swap(int* p1, int* p2)
{
	int tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}
 // 堆排序 建堆是O(N) 每次调整需要O(logN)(调整一次走高度次,高度是logN) 因此堆排序是O(NlogN)
 //自顶向下的调整,但是parent的传参是自下而上的传,先保证最下面的parent及其子节点属于大堆,再一层一层的向上传parent。
void AdjustDwon(int* a, int n, int parent)
{
	int child = parent*2 + 1;
	while(child < n)
	{
		// 建大堆 选出左右孩子大的
		if(child + 1 < n && 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)
{
	// 建堆 parent的传参是自下而上的传,先保证最下面的parent及其子节点属于大堆,再一层一层的向上传parent。
	for(int i = (n-1-1)/2; i >=0; --i)
	{
		AdjustDwon(a, n, i);
	}
	int end = n-1;
	while(end > 0) //只剩一个数就不选了
	{
		Swap(&a[0], &a[end]);
		// 再选出次大的 因为之前已经建堆完成了,因此只有换上去到最上面的那个数不满足大堆的排序,把它排好就行
		AdjustDwon(a, end, 0)
		end--; //每次最后一个位置就是被调换过的最大的、次大的...的数
	}
}

冒泡排序:定义两个指针,指向第一个和第二个位置,前一个比后一个大就交换,然后同时向后挪接着比较,把最大的放到最后一个位置。最坏的情况:O(N^2),最好的情况:O(N)。冒泡和插入的时间复杂度差不多相同,但是当数组接近有序时,她两比起来插入好一些。
在这里插入图片描述

void Swap(int* p1, int* p2)
{
	int tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}
// 冒泡排序
void BubbleSort(int* a, int n)
{
	for(int end = n; end > 0; end--)
	{
		int exchange = 0;
		for(int i = 1; i<end; i++)
		{
			if(a[i-1] < a[i])
			{
				Swap(&a[i-1], &a[i]);
				exchange = 1;
			}
		}
		if(exchange == 0) //如果没有发生交换,可以提前结束程序
			break;
	}
}

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

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

相关文章

24 Vue3之集成TailwindCSS

Tailwind CSS Tailwind CSS是一个由js编写的CSS 框架 他是基于postCss 去解析的 官网地址Tailwind CSS 中文文档 - Tailwind CSS - 只需书写 HTML 代码&#xff0c;无需书写 CSS&#xff0c;即可快速构建美观的网站。 | TailwindCSS中文文档 | TailwindCSS中文网 对于PostCSS…

SigLIP技术小结

paperhttps://arxiv.org/abs/2303.15343githubhttps://github.com/google-research/big_vision个人博客位置http://myhz0606.com/article/siglip 1 背景 CLIP[1]自提出以来在zero-shot分类、跨模态搜索、多模态对齐等多个领域得到广泛应用。得益于其令人惊叹的能力&#xff0…

普通人如何搭乘 AI 快车,开辟 10 大赚钱新赛道

亲爱的朋友们&#xff0c;准备好了吗&#xff1f;让我们一同踏上这趟激动人心的AI淘金之旅&#xff01; 俗话说得好&#xff0c;“机不可失&#xff0c;时不再来”。如今&#xff0c;AI这列高速列车正呼啸而过&#xff0c;而我们每个人&#xff0c;都有机会成为车上的幸运儿。…

你们猜!吊打Oracle的国产数据库有哪几家?

今天闲暇之余看到某vx群聊得很火热&#xff0c;这个群聚集了国内不少数据库大咖&#xff0c;其中大家聊到国产数据库遥遥领先了。 最开始主要是一个朋友提到目前很多企业拍板的人并不懂数据库&#xff0c;甚至很多知名数据库都没听过。 然后大家就开始聊到国产数据库了&#xf…

yolov5源码分析001

文章目录 1.研究背景2.源码位置3.源码 1.研究背景 最近项目需要将前人做的YOLOv5改造项目继续改造,于是研究其代码,一步步剖析,一步步看一个个代码意义,旨在为后期攻克YOLOv10等系列做好准备. 2.源码位置 3.源码 # 下载指定文件,并保存在指定目录文件夹中,最后返回文件完整路…

大模型Agent开发框架对比:LangGraph/LlamaIndex/DIY

LLM代理&#xff08;智能体&#xff09;正处于一个发展阶段。随着多个新框架的出现和该领域的新投资&#xff0c;现代人工智能代理正在克服不稳定的起源&#xff0c;迅速取代 RAG 成为实施重点。那么&#xff0c;2024 年最终会成为自主人工智能系统接管我们写电子邮件、预订航班…

大模型辅助需求代码开发:如何提升核心编码任务生成效果

大模型在解释代码、回答代码问题、写单元测试等方面表现不错&#xff0c;但这些还只是辅助任务&#xff0c;真实项目需求开发中的设计及实现任务才是核心任务&#xff0c;而这方面尚未有成熟的方法和好的效果。一些 AI Developer 工具能够演示从零创建小应用的能力&#xff0c;…

三节课发布首张AIGC学习地图,全员学习AI真的必要吗?

上周&#xff0c;企培行业非常热闹&#xff0c;第20届中国企业培训与发展年会于成都正式举行。 据观察&#xff0c;本次企培年会有几个特点&#xff1a; ❶ 降本增效与AI赋能成为参会者最关注主题&#xff1b; ❷ 主办方取消了之前多年的学习平台专场&#xff0c;增加2个AI场…

谷歌收录查询工具,使用谷歌收录查询工具查询网站收录情况并优化内容的详细步骤

在数字营销和SEO领域&#xff0c;了解网站在谷歌搜索引擎中的收录情况至关重要。使用谷歌收录查询工具&#xff0c;可以有效地监测网站的索引状态&#xff0c;进而优化内容以提升网站排名和曝光度。以下是如何使用谷歌收录查询工具查询网站收录情况并优化内容的详细步骤&#x…

Defining Smart Contract Defects on Ethereum论文解读

背景 这一部分介绍了智能合约的概念和基础知识&#xff0c;以及 Solidity 编程语言。 智能合约&#xff1a;定义了智能合约作为一种运行在区块链上的程序&#xff0c;它能够在无需第三方干预的情况下自动执行合同条款。智能合约的不可变性&#xff1a;强调了智能合约一旦部署…

element-plus中日历组件设置起始为周一

问题描述 element-plus中的日历组件默认是周日到周六&#xff0c;因业务需求&#xff0c;需要实现从周一到周日的顺序。 解决方式 引入dayjs及本地语言包&#xff0c;使用本地时区即可。 import dayjs from dayjs import dayjs/locale/zh-cn ... // 这一句是为了让日历使用本地…

Invalid Teleport target on mount: null (object)

Failed to locate Teleport target with selector “.demon”. Note the target element must exist before the component is mounted - i.e. the target cannot be rendered by the component itself, and ideally should be outside of the entire Vue component tree main.…

银河麒麟V10下如何将TXT文件转为PDF?

银河麒麟V10下如何将TXT文件转为PDF&#xff1f; 1. 安装软件2. TXT转PS3. PS转PDF &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在银河麒麟高级服务器操作系统V10中&#xff0c;将TXT文件转换为PDF文件可以通过简单的几步完成。 1. 安装…

Linux oracle数据库静默安装

系统&#xff1a;Centos7 一、安装准备 1.1 更换依赖源 yum源进行切换&#xff08;这里采用的阿里云的yum源&#xff09;&#xff08;切换之前建议先备份 /etc/yum.repos.d 中的文件&#xff09; wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/rep…

网络工程师指南:防火墙配置与管理命令大全,零基础入门到精通,收藏这一篇就够了

本指南详细介绍了防火墙的配置与管理命令&#xff0c;涵盖了防火墙的工作原理、常见配置命令、安全策略与访问控制、日志管理与故障排查&#xff0c;并通过实战案例展示了如何有效防御网络攻击。通过学习本指南&#xff0c;网络工程师能够系统掌握防火墙的配置与管理技能&#…

收银系统源码-ERP进销存解决方案

收银系统目前已经成为门店日常经营的必备软件工具&#xff0c;功能一般需涵盖线下门店收银&#xff0c;ERP进销存、线上商城等。一套好的ERP进销存模块也能很大程度帮助门店经营管理门店。 ERP进销存功能涵盖了商品的采购、销售、调拨、盘点、库存管理、资金管理等全链路管理&…

【周末推荐】替换SwitchyOmega的Chrome浏览器插件

SwitchyOmega插件在我们这个圈子里应该无人不知无人不晓了吧&#xff0c;最近有很多朋友反馈自己的SwitchyOmega不工作了&#xff0c;今天我们将聊聊为什么SwitchyOmega不工作了&#xff0c;并推荐2款实用的Chrome浏览器插件解决这个问题。 为什么要替换SwitchyOmega&#xff…

这种膜为啥能随温度变透明?怎么制备的?有啥特点?

大家好&#xff0c;今天我们来了解一项关于纳米纤维膜的研究——《Diphylleia Grayi-Inspired Intelligent Temperature-Responsive Transparent Nanofiber Membranes》《Nano-Micro Letters》。在现代科技的发展中&#xff0c;透明材料的需求日益增长&#xff0c;传统材料已无…

VBA技术资料MF206:右键录入指定的数据及图标

我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的工作效率&#xff0c;而且可以提高数据的准确度。“VBA语言専攻”提供的教程一共九套&#xff0c;分为初级、中级、高级三大部分&#xff0c;教程是对VBA的系统讲解&#…

卡通角色检测系统源码分享

卡通角色检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vis…