【数据结构】排序(1)

news2024/9/20 14:57:56

目录

一、概念:

二、直接插入排序:

三、希尔排序:

四、直接选择排序:

五、堆排序:

六、冒泡排序:


一、概念:

排序的概念:

        使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。

排序又分为内部排序和外部排序:

内部排序:数据元素全部放在内存中的排序。

外部排序:数据元素太多不能同时放在内存中,根据排序过程的要求不能在内外存之间移动数据的排序。

常见的排序算法:

二、直接插入排序:

基本思想

待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列 。

例如在我们玩扑克牌斗地主时的码牌操作中就运用到了这个思想。

代码实现:

当插入第i(i>=1)个元素时,前面的a[0],a[1],…,a[i-1]已经排好序,此时用a[i]的排序码与 a[i-1],a[i-2],…的排序码顺序进行比较,找到插入位置即将a[i]插入,原来位置上的元素顺序后移即可。

//时间复杂度: O(N^2)	逆序
//最好的情况: O(N)	顺序有序
void InsertSort(int* a, int n)
{
	for (int i = 0; i < n - 1; i++)// i小于n-1是为下面条件做铺垫,防止越界
	{
		// 设置end为下标,将其与tmp下标位置的数进行比较,并不断更新end
		int end = i;
		int tmp = a[end + 1];// 在单趟排序中,tmp固定

		// 设置数组最小数的条件
		while (end >= 0)
		{
			// 对tmp和end位置数进行比较
			if (tmp < a[end]) 
			{
				// 将end位置数复制在end+1处,本质上是更新去排序后对应的位置
				a[end + 1] = a[end];
				end--;// 更新end
			}
			else
			{
				break;
			}
		}
		// 将tmp数放入对应的位置
		a[end + 1] = tmp;
	}
}

直接插入排序的特性总结:

  1. 元素集合越接近有序,直接插入排序算法的时间效率越高
  2. 时间复杂度:O(N^2)
  3. 空间复杂度:O(1),它是一种稳定的排序算法 
  4. 稳定性:稳定

三、希尔排序:

又称缩小增量排序 

基本思想:

先选定一个整数gap,把待排序文件中所有记录分成gap个组,所有距离为gap的记录分在同一组内,并对每一组内的元素进行排序。

gap越大,大的值更快调到后面,小的值可以更快的调到前面,越不接近有序。

gap越小,跳的越慢,但是越接近有序,如果gap == 1,就是直接插入排序。

代码实现:

void ShellSort(int* a, int Size)
{
	int gap = Size;
	// gap > 1时是预排序,目的让他接近有序
	// gap == 1是直接插入排序,目的是让他有序
	while (gap > 1)
	{
		gap = gap / 3 + 1;//保证最后一次gap是1,就是直接插入排序,但是数列已经非常接近有序了
						 //gap代表的是有多少组

		// 这里就跟直接插入排序的模板一样
		for (int i = 0; i < Size - gap; i++)
		{
			int end = i;
			int tmp = a[end + gap];
			while (end >= 0)
			{
				if (tmp < a[end])
				{
					a[end + gap] = a[end];
					end -= gap;
				}
				else
				{
					break;
				}
			}
			a[end + gap] = tmp;
		}
	}
}

希尔排序的特性总结:

  1. 希尔排序是对直接插入排序的优化。

  2. 当gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,就是直接插入排序。

  3. 希尔排序的时间复杂度不好计算,因为gap的取值方法很多。

  4. 时间复杂度(平均):O(N^1.3)

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

  6. 稳定性:不稳定。

四、直接选择排序:

基本思想:

每一次从待排序的数据元素中选出最小/最大的一个元素,存放在序列的起始/末尾位置,直到全部待排序的数据元素排完 。

代码实现:

  • 在元素集合a[i]--a[n-1]中选择关键码最大(小)的数据元素
  • 若它不是这组元素中的最后一个(第一个)元素,则将它与这组元素中的最后一个(第一个)元素交换
  • 在剩余的a[i]--a[n-2](a[i+1]--a[n-1])集合中,重复上述步骤,直到集合剩余1个元素
// 时间复杂度: O(N^2)
// 最好的情况: O(N^2) 即使原本就有序,还是要暴力取数
// 空间复杂度: O(1)
void SelectSort(int* a, int Size)// 升序
{
	//设置下标
	int begin = 0;
	while (begin < Size)
	{
		int min = begin;
		// 暴力选数
		for (int i = begin + 1; i < Size; i++)
		{
			if (a[i] < a[min])
			{
				min = i;
			}
		}

		swap(a[begin], a[min]); //这里的swap使用的是库函数中写好了的,
								// 使用自己写的注意形参与实参
		begin++;
	}
}

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

  1. 直接选择排序思考非常好理解,但是效率不是很好。实际中很少使用
  2. 时间复杂度:O(N^2)
  3. 空间复杂度:O(1)
  4. 稳定性:不稳定

五、堆排序:

基本思想:

利用堆删除思想来进行排序使用向下调整。需要注意的是排升序要建大堆,排降序建小堆。

代码实现:

// 向下调整:升序建大堆
void AdjustDown(int* a, int size, int parent)
{
	int child = parent * 2 + 1;

	// 一层层的往下判别
	while (child < size)
	{
		// 在保证不越界的前提下找出数大的子节点
		if (child + 1 < size && a[child + 1] > a[child])
		{
			child++;
		}

		if (a[child] > a[parent])
		{
			swap(a[child], a[parent]);// 这里的swap使用的是库函数中写好了的,
                                      // 使用自己写的注意形参与实参
			// 更新父,子节点
			parent = child;
			child = child * 2 + 1;
		}
		else
		{
			break;
		}
	}
}

// 升序
void HeapSort(int* a, int Size)
{
	// O(N)
	// 要排升序,所以建大堆->找最后一个分叶节点向下调整,然后向前依次操作
	for (int i = (Size - 1 - 1) / 2; i >= 0; i--)
	// Size是个数,要下标所以-1,结合找最后一个分叶结点公式化简
	{
		AdjustDown(a, Size, i);
	}

	// O(N*logN)

	int end = Size - 1;
	while (end > 0)
	{

		swap(a[0], a[end]);

		// 在向下调整使用end时,取的值是小于end,默认忽略最后一位,由前Size-1个数进行向下调整
		AdjustDown(a, end, 0);
		end--;
	}
}

堆排序的特性总结:

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

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

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

  4. 稳定性:不稳定

六、冒泡排序:

基本思想:

       两两元素相比,前一个比后一个大就交换,直到将最大/最小(升序/降序)的元素交换到末尾位置。这为一趟;一共进行 n-1 趟这样的交换将可以把所有的元素排序好。

代码实现:

//时间复杂度: O(N^2)	乱序
//最好的情况: O(N)   有序
void BubbleSort(int* a, int Size)
{
	// n个数只需排 n - 1 躺即可
	for (int i = 0; i < Size - 1; i++)
	{
		// 设置一个条件,判断一趟排序下来是否有位置交换
		bool exchange = false;
		for (int j = 1; j < Size - i; j++)
		{
			if (a[j - 1] > a[j])
			{
				swap(a[j - 1], a[j]); // 这里的swap使用的是库函数中写好了的,
                                      // 使用自己写的注意形参与实参
				exchange = true;
			}
		}

		// 如果单趟下来并没有数交换位置则说明这个数列本就有序
		if (exchange = false)
		{
			break;
		}
	}
}

冒泡排序的特性总结:

  1. 冒泡排序是一种非常容易理解的排序
  2. 时间复杂度:O(N^2)
  3. 空间复杂度:O(1)
  4. 稳定性:稳定 

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

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

相关文章

阿里巴巴店铺宝藏全揭秘:一键获取所有商品信息,电商业务效率飙升

阿里巴巴店铺所有商品API接口技术全解析 一、引言 在阿里巴巴这个全球领先的电商平台上&#xff0c;店铺所有商品API接口&#xff08;item_search_shop&#xff09;为开发者提供了一个便捷的途径&#xff0c;能够获取店铺的所有商品信息。通过这一接口&#xff0c;无论是数据…

PostgreSQL教程(十一):SQL语言(四)之数据类型

一、数值类型 数值类型由 2 字节、4 字节或 8 字节的整数以及 4 字节或 8 字节的浮点数和可选精度的十进制数组成。 下表列出了所有可用类型。 数值类型 名字存储长度描述范围smallint2 字节小范围整数-32768 到 32767integer4 字节常用的整数-2147483648 到 2147483647bigi…

【无标题】旋转链表与力扣报错:member access within null pointer of type ‘struct ListNode‘

项目场景&#xff1a; 做单链表反转题目&#xff0c;报错&#xff1a;member access within null pointer of type ‘struct ListNode’ 题目链接:LINK 问题描述 我明明在初始化指针时候&#xff0c;已经处理了n2->next情况却依然报错 这个报错提示含义是&#xff1a;大概就…

HTTPS(超文本传输安全协议)被恶意请求该如何处理。

HTTPS&#xff08;超文本传输安全协议&#xff09;端口攻击通常是指SSL握手中的一些攻击方式&#xff0c;比如SSL握手协商过程中的暴力破解、中间人攻击和SSL剥离攻击等。 攻击原理 攻击者控制受害者发送大量请求&#xff0c;利用压缩算法的机制猜测请求中的关键信息&#xf…

每天一个知识点 - 如何快速熟悉后端项目

入职一家新公司的时候&#xff0c;不可避免的就是接触到新公司的项目&#xff0c;有些项目一启动就是好几年&#xff0c;业务功能极其复杂&#xff0c;下面我总结几个方法让大家快速熟悉后端项目&#xff08;图文结合&#xff09; 用例图简析 用例是系统中的一个功能单元&…

顶级性能更有AI助力 RTX AI轻薄本竟强大如斯?华硕无畏Pro15 2024体验

不知觉&#xff0c;2024龙年腾飞之年俨然到来。回望这过去的一年里&#xff0c;我们的生活发生了很多变化&#x1f3ee; 有对身体健康的焦虑&#xff0c;也有对事业发展的迷茫&#xff0c;也时常回过头来反思自己在过去的一年里都有哪些不足、希冀在新的一年里努力改进自己&am…

Windows环境下查看磁盘层级占用空间的解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

Unity之ShaderGraph如何实现水面波浪

前言 这几天通过一个水的波浪数学公式,实现了一个波浪效果,感觉成就感满满,下面给大家分享一下 首先先给大家看一下公式; 把公式转为ShaderGraph 第一行公式:waveType = z*-1*Mathf.Cos(wave.WaveAngle/360*2*Mathf.PI)+x*Mathf.Sin(WaveAngle/360*-2*Mathf.PI) 转换…

基于JAVA的公司货物订单管理系统 开源项目

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 客户管理模块2.2 商品维护模块2.3 供应商管理模块2.4 订单管理模块 三、系统展示四、核心代码4.1 查询供应商信息4.2 新增商品信息4.3 查询客户信息4.4 新增订单信息4.5 添加跟进子订单 五、免责说明 一、摘要 1.1 项目…

端口占用:Web server failed to start. Port XXX was already in use.原因分析-解决方案

一、windows 1.Web server failed to start. Port XXX was already in use出错原因分析 端口被占用了&#xff0c;我们只需要换一个端口就可以了&#xff0c;如果就想要用特定的端口&#xff0c;我们需要使用下面的命令&#xff0c;先找到对应端口号的进程号&#xff0c;然后结…

【QT-lineEidte动画效果

QT-lineEidte动画效果 一、演示效果二、核心代码三、下载链接 一、演示效果 二、核心代码 #ifndef DynamicUnderlineLineEdit_H #define DynamicUnderlineLineEdit_H#include <QWidget> #include <QLineEdit> #include <QPainter> #include <QPaintEvent…

产品渲染3D效果图一张多少钱,哪个平台更有性价比?

产品渲染3D效果图的价格受到多方面因素的影响&#xff0c;包括但不限于产品类型、渲染难度以及输出尺寸等。如果效果图需要后期处理&#xff0c;还有可能增加其他费用。接下来&#xff0c;我们来了解一下产品渲染效果图的费用情况。 1.产品渲染3D效果图一张多少钱&#xff1f; …

最长的回文串

开始想的简单了&#xff0c;确实没想到奇数字母删去一个后也能用 解法&#xff1a; 桶排序 #include<iostream> #include<vector> #include<algorithm> using namespace std; #define endl \n #define int long long signed main() {int t;cin >> t…

【C++11】lambda表达式 | 函数包装器

文章目录 一、lambda表达式1. 为什么需要lambda表达式2. lambda的定义3. lambda的语法捕捉列表 4. 函数对象和lambda表达式的底层原理 二、函数包装器1. function包装器2. bind包装器用bind包装器绑定固定参数用bind包装器调整传参顺序无意义的绑定 3. bind包装器的意义 一、la…

【Spring】Spring MVC

目 录 一.什么是 Spring MVC&#xff1f;1.MVC 定义2.MVC 和 Spring MVC 的关系 二.为什么要学 Spring MVC&#xff1f;三.怎么学 Spring MVC&#xff1f;1.Spring MVC 创建和连接综上连接方式&#xff1a; 2.获取参数1.传递单个参数2.获取多个参数3.获取对象4.获取表单参数5.接…

Google谷歌通过文本、图像从而生成音频和视频的多模态学习模型:VideoPoet

VideoPoet是一种多模态学习模型&#xff0c;本身是一个大型语言模型&#xff08;LLM&#xff09;&#xff0c;能够理解和处理文本、图像、音频等多种信息&#xff0c;并将其融合到视频生成过程中。它不仅能够根据文字描述生成视频&#xff0c;还能给视频添加风格化效果、修复和…

8杯水要怎么喝才能防止或减轻肥胖状态?

为什么说&#xff0c;人每天要喝足8杯水呢&#xff1f;原因很多&#xff0c;皮肤干了要多喝水&#xff0c;因为皮肤缺水&#xff0c;需要滋养&#xff1b;身体底子差要多喝水&#xff0c;实际身体底子差不光要多喝水&#xff0c;还要注意饮食营养和运动锻炼&#xff1b;身体健康…

【html学习笔记】3.表单元素

1.文本框 1.1 语法 <input type "text">表示文本框。且只能写一行 1.2 属性 使用属性size 设置文本框大小 <input type"text" size"10">2. 使用属性value 来设置文本框的默认文字 <input type"text" size"…

深度学习发展里程碑事件2006-2024

2006-2024年&#xff0c;深度学习发展经历众多的里程碑事件&#xff0c;一次次地刺激着人们的神经&#xff0c;带来巨大的兴奋。电影还在继续&#xff0c;好戏在后面&#xff0c;期待…… 2006年 深度信念网络&#xff08;DBNs&#xff09;&#xff1a;Geoffrey Hinton与他的学…

maven的聚合和生命周期

什么是maven的聚合呢?就是父类直接将子类项目一起统一打包安装统一maven的生命周期 1.maven的生命周期 2.在父亲类pom文件指定需要打包的项目 实例代码: <!--maven的聚合 通过modules指定需要打包的maven项目--> <modules><module>../ithema-jopo</m…