数据结构——排序上

news2024/11/13 14:49:38

1.排序的概念及其运用


1.1排序的概念


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

稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排序算法是稳定的;否则称为不稳定的

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

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


1.2排序运用


 1.3 常见的排序算法


1.4 查看各个排序算法动态演示效果

Comparison Sorting Visualization (usfca.edu)icon-default.png?t=N7T8https://www.cs.usfca.edu/~galles/visualization/ComparisonSort.html


2.常见排序算法的实现

2.1 插入排序

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

比如:扑克牌


2.1.1 直接插入排序

直接插入排序的特性:

                                1. 元素集合越接近有序,直接插入排序算法的时间效率越高

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

                                3. 空间复杂度:O(1),它是一种稳定的排序算法

                                4. 稳定性:稳定

// 直接插入排序
//时间复杂度:O(N^2)  最坏的情况:逆序  
//最好的情况:O(N)
void InsertSort(int* a, int n)
{
	//整个区间end是[0,n-1],n是在end的下一个位置
	for (int i = 0; i < n - 1; i++)
	{
		//最后一组是[0,n-2]
		int end=i;
		//为了防止end--的时候覆盖掉end+1,将end+1赋给临时变量tmp
		int tmp = a[end + 1];
		while (end >= 0)
		{
			if (a[end] > tmp)
			{
				a[end + 1] = a[end];
				--end;
			}
			else//end<0
			{
				break;
			}
		}//因为end是小于0的,所以end+1就在它的后面
			//也就是>=0的
		a[end + 1] = tmp;
	}
	
}


2.1.2 希尔排序( 缩小增量排序 )

时间复杂度:O(N ^ 1.3)

希尔排序:1.先进行预排序(gap)(让数组接近有序)

                   2.再插入排序

希尔排序的特性总结:

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

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

gap是取两数直接的间隔,比如4个数的间隔就是3

预排序

1. gap越大,大的可以越快跳到后面,小的数可以越快跳到前面,越不接近有序

2. gap越小,跳得越慢,但是越接近有序。当gap==1相当于插入排序就有序了

3. gap取值按:gap=gap/3+1 来取  , +1保证最后一个gap一定是1

A. 5/3 + 1=2    B. 2/3 + 1=1

  

3. 希尔排序的时间复杂度不好计算,因为gap的取值方法很多,导致很难去计算,因此在好些树中给出的希尔排序的时间复杂度都不固定

4. 稳定性:不稳定

结合下面这段代码:i初始为0赋值给end,++i每次往后走一步然后end的每一组(int tmp = a[end + gap]) 的下一次就为end + gap,进行多组一起走 

	for (size_t i = 0; i < n - gap; ++i)
	{
		int end = i;
//为了防止end--的时候覆盖掉end+gap,将end+gap赋给临时变量tmp
		int tmp = a[end + gap];




// 希尔排序
// 时间复杂度:O(N ^ 1.3)
//使用多组一起走
// O(N ^ 1.3)
void ShellSort(int* a, int n)
{
	int gap = n;
	while (gap > 1)
	{
		// +1保证最后一个gap一定是1
		// gap > 1时是预排序
		// gap == 1时是插入排序
		gap = gap / 3 + 1;

		/*i初始为0赋值给end,++i每次往后走一步
		然后end的每一组(int tmp = a[end + gap])
		的下一次就为end + gap,进行多组一起走*/
		for (size_t i = 0; i < n - gap; ++i)
		{
			int end = i;
	//为了防止end--的时候覆盖掉end+gap,将end+gap赋给临时变量tmp
			int tmp = a[end + gap];
			while (end >= 0)
			{
				if (tmp < a[end])
				{
					a[end + gap] = a[end];					
					end -= gap;//end=end-gap是小于0的
				}
				else//end<0
				{
					break;
				}
			}//因为end是小于0的,所以end+gap就在它的后面
			//也就是>=0的
			a[end + gap] = tmp;
		}
	}
}


2.2 选择排序

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

2.2.1 直接选择排序:


1. 在元素集合array[i]--array[n-1]中选择关键码最大(小)的数据元素

2. 若它不是这组元素中的最后一个(第一个)元素,则将它与这组元素中的最后一个(第一个)元素交换

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


直接选择排序的特性:

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

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

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

                                4. 稳定性:不稳定

// 选择排序
void SelectSort(int* a, int n)
{
	int begin = 0, end = n - 1;

	while (begin < end)
	{
		int mini = begin, maxi = begin;
		for (int i = begin + 1; i <= end; ++i)
		{
			if (a[i] > a[maxi])
			{
				maxi = i;
			}

			if (a[i] < a[mini])
			{
				mini = i;
			}
		}

		Swap(&a[begin], &a[mini]);
		Swap(&a[end], &a[maxi]);
		++begin;
		--end;
	}
}


2.2.2 堆排序(Heapsort)


堆排序是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。它是通过堆来进行选择数据

需要注意的是排升序要建大堆,排降序建小堆

直接选择排序的特性:

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

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

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

                                        4. 稳定性:不稳定

// 堆排序
void HeapSort(int* a, int n)
{
	// 向下调整建堆 O(N)
	for (int i = (n - 1 - 1) / 2; i >= 0; i--)
	{
		AdjustDown(a, n, i);
	}

	// O(N*logN)
	int end = n - 1;
	while (end > 0)
	{
		Swap(&a[0], &a[end]);
		AdjustDown(a, end, 0);
		--end;
	}
}

2.3 交换排序


交换排序的特点是:将值较大的记录向序列的尾部移动,值较小的记录向序列的前部移动

2.3.1冒泡排序

冒泡排序的特性:

                                1. 冒泡排序是一种非常容易理解的排序

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

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

                                4. 稳定性:稳定

//冒泡排序
// 最坏:O(N^2)     最好:O(N)   
void BubbleSort(int* a, int n)
{
	for (int j = 0; j < n; j++)
	{
		// 单趟
		int flag = 0;
		for (int i = 1; i < n - j; i++)
		{
			if (a[i - 1] > a[i])
			{
				Swap(&a[i - 1], &a[i]);
				flag = 1;
			}
		}

		if (flag == 0)
		{
			break;
		}
	}
}


石粒有限,先到此为止吧~

感谢观看~

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

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

相关文章

多目标应用:基于自组织分群的多目标粒子群优化算法(SS-MOPSO)的移动机器人路径规划研究(提供MATLAB代码)

一、机器人路径规划介绍 移动机器人&#xff08;Mobile robot&#xff0c;MR&#xff09;的路径规划是 移动机器人研究的重要分支之&#xff0c;是对其进行控制的基础。根据环境信息的已知程度不同&#xff0c;路径规划分为基于环境信息已知的全局路径规划和基于环境信息未知或…

美国海外仓可以用哪家海外仓系统好?

随着全球贸易的增长&#xff0c;美国已经成为了海外仓储业务的一个重要市场。美国海外仓的数量不断增加&#xff0c;竞争也愈加激烈。为应对这种竞争&#xff0c;并优化仓储和供应链管理&#xff0c;WMS&#xff08;仓库管理系统&#xff09;成为了海外仓的重要工具。 一、WMS…

Wx64ST:一款轻松可修改的C语言Shellcode模板

关于windows_x64_shellcode_template windows_x64_shellcode_template简称为Wx64ST&#xff0c;它是一款功能强大的Shellcode模板&#xff0c;该模板基于C语言编写&#xff0c;其简单、可扩展和易于修改等特性可以帮助广大安全研究人员轻松开发适用于Windows x64的Shellcode。…

kali (linux) 安装配置 共享文件夹 samba

一、samba 安装 sudo apt-get install samba 二、启动samba 服务 systemctl enable nmb systemctl enable smb systemctl start nmb systemctl start smb 三、查看 samba状态 systemctl status nmb systemctl status smb 四、创建共享文件夹 &#xff0c;并修改权限 …

技术指南:5分钟零成本实现本地AI知识库搭建

你一定经历过各种通用大模型一本正经胡说八道的时候吧&#xff0c;AI一通丝滑输出让人真假难辨&#xff0c;防不胜防。这种情况被称为AI幻觉。 大模型产生幻觉不幸“翻车”的原因很大程度上是“先天不足”&#xff0c;例如训练时来自特定领域的训练数据就比较缺失或存在偏差等…

20-22 - 打造专业的编译环境

---- 整理自狄泰软件唐佐林老师课程 文章目录 1. 大型项目的编译&#xff08;无第三方库&#xff09;1.1 大型项目的目录结构&#xff08;无第三方库&#xff09;1.2 项目结构设计分析1.3 需要打造的编译环境1.4 解决方案设计 2. 第 1 阶段任务2.1 关键的实现要点2.2 模块 make…

MES管理系统如何提升产品质量与可追溯性

在智能制造的新纪元里&#xff0c;MES管理系统正逐步崭露头角&#xff0c;成为驱动制造业转型升级的幕后英雄。MES管理系统不仅重新定义了生产过程的管理与控制方式&#xff0c;还以数据为驱动&#xff0c;引领着制造业迈向更高效、更智能、更可持续的未来。 智能制造的赋能者&…

U-Mail垃圾邮件过滤网关‍是如何过滤垃圾邮件的?

随着互联网的普及&#xff0c;垃圾邮件已经成为计算机网络安全的又一个公害。因此&#xff0c;反垃圾邮件已经成为互联网应用研究中一个重要课题。为了防止垃圾邮件首先要学会保护自己的邮件地址&#xff0c;避免在网上随意登记和使用邮件地址&#xff0c;预防垃圾邮件骚扰。其…

ALV Tree Control树控件

ALV Tree Control CL_GUI_ALV_TREE 效果&#xff1a; 自定义函数调用&#xff0c;在函数里画屏幕定义树控件显示 FUNCTION ZFI_YSYWLX_HELP_NEW . *"---------------------------------------------------------------------- *"*"本地接口&#xff1a; *&qu…

zset使用lua实现取最高分数中的随机成员

zset使用lua实现取最高分数中的随机成员 这种场景适用队列中不想要先入先出、先入后出因为zset的命令都是带有排序功能的&#xff0c;所以取值时要不从大到小要不从小到大所以我使用lua实现随机取成员使用lua是因为可以保持原子性在执行过程中Lua脚本是不会被其他命令或请求打…

C语言典型例题59

《C程序设计教程&#xff08;第四版&#xff09;——谭浩强》 题目&#xff1a; 例题4.11 译密码。为使电文保密&#xff0c;往往按一定规律将其转换为密码&#xff0c;收报人再按约定的规律将其译回原文。 例如&#xff0c;可以按以下规律将电文变为密码&#xff1a; 将字母A…

我不是非酋之-天空概率

最近入坑了dnf手游&#xff0c;染上了合天空&#xff0c;大黑蛋子一个&#xff0c;突发奇想&#xff0c;模拟下合天空概率&#xff0c;看看是否真的有20%。 梳理代码逻辑如下&#xff1a; 不考虑礼包和其他东西 条件&#xff1a; 合成概率20%&#xff0c;每次需要2个装扮和一个…

格式化的磁盘数据能恢复吗?五个看完即可掌握的恢复方法

磁盘是大多数电子设备都必须具有的一个存储介质&#xff0c;在平时使用的过程中&#xff0c;很多用户为了途一时的方便&#xff0c;经常会需要一键将磁盘里面的数据执行格式化&#xff0c;以实现清空或者删除的情况。然而&#xff0c;在执行完具体的操作后&#xff0c;过了一段…

Vue(十三) 路由、路由嵌套、query、param传参、propos、replace属性。编程式路由导航,特有的生命周期函数,路由守卫

文章目录 路由1. 基本使用2. 多级(嵌套)路由3. 路由query传参4. 命名路由5. 路由param传参6. propos属性7. replace属性8. 编程式路由导航9. 缓存路由组件10. actived&#xff0c;deactived生命周期函数11. 路由守卫1、全局路由2、独享路由3、组件内路由守卫 12. 路由器工作的两…

干货含源码!如何用Java后端操作Docker(命令行篇)

目录 干货含源码&#xff01;如何用Java后端操作Docker&#xff08;命令行篇&#xff09; 一、为什么要用后端程序操作Docker 二、安装Docker 1、安装Docker 2、启动Docker 三、使用Java后端操作docker 1、构建docker镜像并生成容器 2、执行完毕后删除容器和镜像 3、在…

怎么删除谷歌浏览器的下载记录

定期删除谷歌浏览器的下载记录&#xff0c;对于保护个人隐私和提升浏览器性能都非常的重要。为了帮助大家安全的进行谷歌浏览器下载记录的清除&#xff0c;本文为大家分享了实用的操作方法&#xff0c;一起来看看吧。 删除谷歌浏览器下载记录的原因说明 1、保护隐私&#xff1…

【算法 动态规划 简单多状态 dp 问题】打家劫舍题型

打家劫舍题型 按摩师 (easy)解题思路代码 打家劫舍II &#xff08;medium&#xff09;解题思路代码 删除并获得点数&#xff08;medium&#xff09;解题思路代码 按摩师 (easy) 题目链接 该题是打家劫舍的变形 解题思路 状态表示 分析: 注意题目, 对于当天的预约, 可以接受…

车辆远控功能自动化测试方案:打造高效可靠的测试流程

随着汽车逐步走向智能化、网联化&#xff0c;整车的功能已经不再局限于驾驶员在车内进行本地操作。在远离车辆时&#xff0c;驾驶员也可以通过手机APP下发控制指令来实现对车辆的远程控制。 近几年&#xff0c;伴随远控功能项不断增多&#xff0c;其功能逻辑也越来越复杂&…

python开发--信息的增删改

部门信息的增删改 1. 增加 点击新建部门 跳转到新建部门页面&#xff1a;http://127.0.0.1:8000/depart/add/ 在views.py里面增加如下代码&#xff0c;可以将用户输入的信息添加到数据库中 def depart_add(request):if request.method GET:return render(request, depart…

STL之my_list容器

前言&#xff1a;各位老铁好久不见了&#xff0c;今天分享的知识是自己实现一个简单的list容器&#xff0c;为什么我先跳过vector容器的自我实现呢&#xff1f;我个人觉得vector相对于list的自我实现简单一点&#xff0c;所以今天先分享实现my_list的知识 我们要实现my_list&a…