冒泡,选择,插入,希尔排序

news2024/9/22 12:31:25

目录

一. 冒泡排序

1. 算法思想

2. 时间复杂度与空间复杂度

3. 代码实现

二. 选择排序

1. 算法思想

2. 时间复杂度与空间复杂度

3. 代码实现

三.插入排序

1. 直接插入排序

(1). 算法思想

(2). 时间复杂度与空间复杂度

(3). 代码实现

2. 希尔排序

(1). 算法思想

(2). 代码实现

(3). 时间复杂度与空间复杂度

一. 冒泡排序

1. 算法思想

假设排升序,从头开始两两比较选出最大的的值移到最后面(假设下标为10),再从头开始两两比较选出次大的移到下标为9的地方以此类推

2. 时间复杂度与空间复杂度

(1). 最优情况

当数据全都有序时,最快。因为此时每个元素只需比较一次就可以完成整个排序过程此时时间复杂度为   O(N)

(2). 最坏情况

当数据逆序时最慢,此时每一次比较都需要交换。时间复杂度为  O(N²)

(3). 平均情况

综上所述,平均复杂度为  O(N²)

(4). 空间复杂度

冒泡排序只需要一个额外变量来交换元素,不需要额外的数据结构来存储数据,所以空间复杂度为     O(1)

3. 代码实现
void BubbleSort(int* a, int n)//冒泡排序
{
	int count = 0;
	for(int j=0;j<n-1;j++)
	{
		for (int i = 0; i < n - j-1; i++)
		{
			if (a[i] <a[i+1] )
			{
				Swap(&a[i], &a[i + 1]);
				count = 1;
			}
		}
		if (count == 0)
			break;
	}
}

二. 选择排序

1. 算法思想

假设排升序,遍历数组,选出最大值与排序数列的最后一个元素(假设下标为10)交换,再从除最后一个元素(即下标0~9)的序列中找出次大值与下标为9的序列交换以此往复知道排序完毕

2. 时间复杂度与空间复杂度

(1). 时间复杂度

选择排序需要遍历n-1次来找到最小(或最大)元素,并且在每次遍历中都需要对剩余未排序元素进行遍历以找到最小(或最大)元素,因此选择排序的时间复杂度总是   O(N²)

(2) 空间复杂度

只需一个额外变量来存储找到的最大(或最小)元素的索引,所以空间复杂度为   O(1)

3. 代码实现

我们实现一个优化版本,同时找到最大的值与最小的值,分别与头和尾交换

void SelectSort(int* a, int n)
{
	int begin = 0, end = n -1;
	while(begin<end)
	{
		int max = begin, min = begin;
		for (int i = begin+1; i <= end; i++)
		{
			if (a[i] > a[max])
				max = i;
			if (a[i] < a[min])
				min = i;
		}

		Swap(&a[begin], &a[max]);
		Swap(&a[end], &a[min]);
		
		begin++;
		end--;
	}
}

以上代码还有一个小问题,当出现下图情况时

begin所指向的值与max所指向的值交换,那min指向的值就变为了原来max所指向的值,此时再与end交换会发生将最大的值交换过去的情况

修改代码为

void SelectSort(int* a, int n)
{
	int begin = 0, end = n -1;
	while(begin<end)
	{
		int max = begin, min = begin;
		for (int i = begin+1; i <= end; i++)
		{
			if (a[i] > a[max])
				max = i;
			if (a[i] < a[min])
				min = i;
		}
		if (begin == min)
		{
			Swap(&a[begin], &a[max]);
			Swap(&a[max], &a[end]);
		}
		else
		{
			Swap(&a[begin], &a[max]);
			Swap(&a[end], &a[min]);
		}
		begin++;
		end--;
	}
}

三.插入排序

1. 直接插入排序
(1). 算法思想

从第一个元素开始排序,先排前一个数,再排前两个数以此类推

假设排升序,第一个数自然是有序的,第二个数与第一个数比较,如果比第一个数小就与其交换,然后看第三个数,此时前两个数是有序的,第三个数先于第二个数比较,比第二个数小就与其交换,再与第一个数比较,比第一个数小就与其交换,如果不比第二个数小就看第四个数,此时前三个数都是有序的以此类推

(2). 时间复杂度与空间复杂度

① 最好情况

在有序情况下只需遍历一遍即可时间复杂度为   O(N)

②最坏情况

在逆序情况下,每一次比较都要交换,时间复杂度为 O(N²)

③平均情况

综上所述平均时间复杂度为O(N²)

④空间复杂度

只需要一个额外的空间来存储当前要插入的元素,空间复杂度为O(1)

(3). 代码实现
void InsertSort(int* a,int n)//直接插入排序
{
	for(int i=0;i<n-1;i++)
	{
		int end = i;
		int t = a[i+1];
		while (end >= 0)
		{
			if (t < a[end])
			{
				a[end+1] = a[end];
				end--;
			}
			else   
				break;
		}
		a[end+1] = t;
	}

}
2. 希尔排序
(1). 算法思想

是直接插入算法的改进版本,总体操作可大致分为两步

先进行预排序

直接插入排序

 直接插入排序是和距离为1的元素比较,而希尔排序是和距离为gap的元素比较,gap不断变小,直到变为1,此时即是直接插入排序

初始序列为 9 1 2 5 7 4 8 6 3 5 ,gap值为5进行一次预排序过程如下

预排序后序列为

当gap为2时

预排序后序列为

 我们发现预排序后一定比之前更加接近有序

从时间上讲,gap越大,大的数可以越快的到后面去,小的数可以越快的到前面去

gap越小呢,预排序完就越接近有序,gap==1就是直接插入排序

我们就可以将gap慢慢减少直到变为1从而进行直接插入排序是尽量是最好的情况

(2). 代码实现

希尔排序的代码与直接插入排序的代码十分相似,不同的地方就是gap,可以通过三层循环或四层循环实现,两者执行的次数实际是一样的

void ShellSort(int* a, int n)//希尔排序
{
	int gap = n;
	while(gap>1)
	{
		gap =gap/ 3+1;// 除3不一定会=1,但3是最合理的,所以+1保证最后一次gap一定是1 
		//for(int j=0;j<gap;j++)
		//{
		for (int i = 0; i < n - gap; i++)//一组一组的排序所以i也可以+=gap,效率没有区别,都是要走这些步数
		{
			int end = i;
			int t = a[end + gap];
			while (end >= 0)
			{
				if (t < a[end])
				{
					a[end + gap] = a[end];
					end -= gap;
				}
				else
					break;
			}
			a[end + gap] = t;
		}
		//}
	}
}
(3). 时间复杂度与空间复杂度

希尔时间复杂度的计算,需要很高的数学水平,此处只做粗略解释(我不会,嘿嘿)

①时间复杂度

我们假设每一次gap=n/3,此时每组三个数据,

最坏情况下 第一次排序消耗:(1+2)*n/3==n

下一次 

gap=n/3/3=n/9,每组9个数据

但此时由于上面的预排序,不可能是最坏情况,即

(1+2+3+4+5+6+7+8)*n\9

具体计算我也不会

但是最后一次,gap==1时(此时很接近有序)

直接插入排序消耗n

时间复杂度大致为  O(N^1.3)即N的1.3次方

②空间复杂度

由于不需要额外的空间,所以空间复杂度为O(1)


这篇文章就到这里啦

(๑′ᴗ‵๑)I Lᵒᵛᵉᵧₒᵤ❤

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

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

相关文章

MongoDB教程(十五):MongoDB原子操作

&#x1f49d;&#x1f49d;&#x1f49d;首先&#xff0c;欢迎各位来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里不仅可以有所收获&#xff0c;同时也能感受到一份轻松欢乐的氛围&#xff0c;祝你生活愉快&#xff01; 文章目录 引言一、MongoD…

2、如何发行自己的数字代币(truffle智能合约项目实战)

2、如何发行自己的数字代币&#xff08;truffle智能合约项目实战&#xff09; 1-Atom IDE插件安装2-truffle tutorialtoken3-tutorialtoken源码框架分析4-安装openzeppelin代币框架&#xff08;代币发布成功&#xff09; 1-Atom IDE插件安装 正式介绍基于web的智能合约开发 推…

netty 自定义客户端连接池和channelpool

目录标题 客户端池化运行分析问题修复 客户端池化 通信完成之后&#xff0c;一般要关闭channel&#xff0c;释放内存。但是与一个服务器频繁的打开关闭浪费资源。 通过连接池&#xff0c;客户端和服务端之间可以创建多个 TCP 连接&#xff0c;提升消息的收发能力&#xff0c;同…

PyTorch张量索引

文章目录 1、简介1.1、基本概念1.2、索引类型1.3、数据准备1.4、技术摘要⭐ 2、简单行、列索引3、列表索引4、范围索引5、布尔索引6、多维索引 &#x1f343;作者介绍&#xff1a;双非本科大三网络工程专业在读&#xff0c;阿里云专家博主&#xff0c;专注于Java领域学习&#…

Golang | Leetcode Golang题解之第241题为运算表达式设计优先级

题目&#xff1a; 题解&#xff1a; const addition, subtraction, multiplication -1, -2, -3func diffWaysToCompute(expression string) []int {ops : []int{}for i, n : 0, len(expression); i < n; {if unicode.IsDigit(rune(expression[i])) {x : 0for ; i < n &…

大规模优化问题,Scipy?Ceres?PyTorch!

背景&#xff1a; 优化问题一般通过scipy.optimize或者Ceres Solver优化器求解。但在参数量较大的优化问题上&#xff0c;scipy提供的BFGS、L-BFGS-B、CG、SLSQP等梯度优化算法其复杂度和存储需求指数级上升&#xff0c;无法满足计算效率&#xff1b;而Ceres需要额外的语言来支…

科普文:百度交易中台之系统对账篇

百度交易中台作为集团移动生态战略的基础设施&#xff0c;面向收银交易与清分结算场景&#xff0c;赋能业务、提供高效交易生态搭建。目前支持百度体系内多个产品线&#xff0c;主要包括&#xff1a;度小店、小程序、地图打车、文心一言等。本文主要介绍了百度交易中台的交易链…

如何让主机显示Docker容器的程序界面,同时支持声音播放

系统中如果安装各种应用软件&#xff0c;很容易会因为版本冲刺引发异常。一个好的办法就是用容器来隔离系统环境&#xff0c;确保主机环境不变。对于一些有界面的程序&#xff0c;可以在容器内运行&#xff0c;让其界面显示在主机上。下面以安装和使用视频剪辑软件shotcut为例&…

【一刷《剑指Offer》】面试题 42:翻转单词顺序 VS 左旋转字符串

力扣对应题目链接&#xff1a;151. 反转字符串中的单词 - 力扣&#xff08;LeetCode&#xff09; 牛客对应题目链接&#xff1a;翻转单词序列_牛客题霸_牛客网 (nowcoder.com) 核心考点 &#xff1a;子串划分&#xff0c;子串逆置。 一、题目一 1、《剑指Offer》对应内容 2、…

Delphi5实现加密程序

效果图 平面效果图 实现“确认按钮”和“加密” //点击确认输入按钮 procedure TForm1.btn1Click(Sender: TObject); //加密部分 varpasswd_2,passwd_3:string;beginpasswd_2:edt1.Text;Delete(passwd_2,3,2);passwd_3:mima;Delete(passwd_3,3,2);if(passwd_2passwd_3) thenM…

MAE(论文阅读):Masked Autoencoders are scalable vision learners

Masked Autoencoders Are Scalable Vision Learners 研究问题&#xff1a; 本文主要介绍了掩码自编码器( MAE, Masked autoencoders)是视觉领域中可扩展的自监督学习算法。MAE具体操作为随机屏蔽输入image中的patchs&#xff0c;再重建丢失的像素。其基于两个核心操作。第…

HTML5大作业三农有机,农产品,农庄,农旅网站源码

文章目录 1.设计来源1.1 轮播图页面头部效果1.2 栏目列表页面效果1.3 页面底部导航效果 2.效果和源码2.1 源代码 源码下载万套模板&#xff0c;程序开发&#xff0c;在线开发&#xff0c;在线沟通 作者&#xff1a;xcLeigh 文章地址&#xff1a;https://blog.csdn.net/weixin_4…

浅谈Canal原理

canal [kə’nl]&#xff0c;译意为水道/管道/沟渠&#xff0c;主要用途是基于 MySQL 数据库增量日志解析&#xff0c;提供增量数据 订阅 和 消费。应该是阿里云DTS&#xff08;Data Transfer Service&#xff09;的开源版本。 Canal与DTS提供的功能基本相似&#xff1a; 基于…

python Requests库7种主要方法及13个控制参数(实例实验)

文章目录 一、Requests库的7种主要方法二、kwargs:控制访问的13个参数 一、Requests库的7种主要方法 序号方法说明1requests.request()&#xff1a;提交一个request请求&#xff0c;作为其他请求的基础2requests.get()&#xff1a;获取HTML网页代码的方法3requests.head()&…

内网隧道——隧道技术基础

文章目录 一、正向连接与反向连接1.1 正向连接1.2 反向连接 二、端口转发三、端口映射四、端口复用五、代理和隧道的区别六、常见隧道穿透分类 环境&#xff1a; kali&#xff1a;192.168.92.6&#xff0c;MSF v6.3.25 win7&#xff1a;192.168.92.7 一、正向连接与反向连接 1…

python实现误差扩散、Floyd-Steinberg 抖动、有序抖动、Riemersma 抖动算法

误差扩散、Floyd-Steinberg 抖动、有序抖动、Riemersma 抖动算法 1.误差扩散算法详解算法步骤Floyd-Steinberg 算法公式Python 实现详细解释优缺点 2.有序抖动算法详解算法步骤Bayer矩阵公式Python 实现详细解释优缺点 3.Riemersma 抖动算法详解算法步骤公式Python 实现详细解释…

网络编程中的TCP和UDP

什么是TCP协议 TCP( Transmission control protocol )即传输控制协议&#xff0c;是一种面向连接、可靠的数据传输协议&#xff0c;它是为了在不可靠的互联网上提供可靠的端到端字节流而专门设计的一个传输协议。 面向连接 &#xff1a;数据传输之前客户端和服务器端必须建立连…

人工智能与语音识别:技术进步与应用前景

引言 人工智能&#xff08;AI&#xff09;作为当今科技进步的核心驱动力&#xff0c;正在各个领域展现其变革力量。其中&#xff0c;语音识别技术作为人工智能的重要应用之一&#xff0c;已经深入到我们的日常生活和工作中。从智能助手如Siri、Google Assistant&#xff0c;到智…

最新版kubeadm搭建k8s(已成功搭建)

kubeadm搭建k8s&#xff08;已成功搭建&#xff09; 环境配置 主节点 k8s-master&#xff1a;4核8G、40GB硬盘、CentOS7.9&#xff08;内网IP&#xff1a;10.16.64.67&#xff09; 从节点 k8s-node1&#xff1a; 4核8G、40GB硬盘、CentOS7.9&#xff08;内网IP&#xff1a;10…

n5.Nginx 常见模块

Nginx 常见模块 4.1 Nginx 四层访问控制4.2 Nginx 账户认证功能4.3 自定义错误页面4.4 自定义错误日志4.5 检测文件是否存在4.6 长连接配置4.7 作为下载服务器配置4.8 作为上传服务器4.9 限流限速4.10 Nginx 状态页 4.1 Nginx 四层访问控制 访问控制基于模块ngx_http_access_m…