【八大排序(一)】排序还只会用冒泡?进来给我学!

news2024/11/27 7:36:55

💓博主CSDN主页:杭电码农-NEO💓

⏩专栏分类:八大排序专栏⏪

🚚代码仓库:NEO的学习日记🚚

🌹关注我🫵带你学习排序知识
  🔝🔝


在这里插入图片描述

插入,希尔排序

  • 1. 前言🚩
  • 2. 插入排序🚩
    • 2.1 基本思路🏁
    • 2.2 画图理解🏁
    • 2.3 代码实现🏁
  • 3. 选择排序🚩
    • 3.1 基本思想🏁
    • 3.2 画图理解🏁
    • 3.3 代码实现🏁
    • 3.4 代码优化🏁
  • 4. 算法效率分析🚩
  • 5. 总结与网站分享🚩

1. 前言🚩

博主前段时间接到了专业课老师的任务:
让我设计个排序算法用来给学生成绩排名.
我心里一惊!
这不是为难我这个只会冒泡的大学生嘛

在这里插入图片描述


于是我删掉了王者荣耀,删掉了吃鸡
我奋不顾身,我披星戴月的肝八大排序
终于!我现在学成归来
下面就给大家分享八大排序中的前两个:

  • 插入排序
  • 选择排序

2. 插入排序🚩

2.1 基本思路🏁

基本思想:

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

玩斗地主抓牌实际上就是一种插入排序:

在这里插入图片描述

2.2 画图理解🏁

单趟插入:
比如我们先定义一个有序数组:

int a[100]={2,4,5,10};

我们再把数据3插入到这个数组中:

插入排序


2.3 代码实现🏁

在我们实际生活中
最常见的就是把一个无序数组变成有序
所以还不能是单纯的插入到有序数组中

这里我们将一个无序数组变为有序
直接在原数组中操作
这里我们定义一个无序数组:

int a[9]={2,9,5,7,4,1,3,8,6}

要想直接在原数组中操作,相当于要进行元素个数这么多次单趟插入,我们定义两个变量,end和x,一个指向第一个元素,一个指向第二个元素,end<x就不移动,end>x就开始往后走

画图:

原数组插入


// 插入排序
void InsertSort(int* a, int n)
{
	assert(a);
	for (int i = 0; i < n - 1; i++)//将一个数组中所有元素升序
	{                              //,这里必须是n-1,不然后面数组会越界
		int end=i;
		int x=a[end+1];//x始终指向end下一个位置的值
		while (end >= 0)//每趟插入最多挪动end-1个数据
		{
			if (a[end] > x)//x前一个数大于x,就将数据往后移一格
			{
				a[end + 1] = a[end];//这里数组的值会往后覆盖
				                    //但是没关系,我们已经将a[end+1]的值保存在x当中了
				end--;
			}
			else
			{
				break;//跳出里面的while循环
			}
		}
		a[end + 1] = x;
	}
}

3. 选择排序🚩

3.1 基本思想🏁

基本思想:

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

不知道你们有没有经历过这种痛:
小学排队的时候老师对我说:
你,最矮!到最前面来排着.

在这里插入图片描述

当然大家可能之前接触过选择排序
但是我分享的选择排序是做了优化的
以前我们是每一趟选一个最大或最小
优化后:一趟选两个,最大的和最小的
分别放在数组的左右端


3.2 画图理解🏁

我们先定义一个1~9的无序数组:

int a[9]={6,2,5,3,9,4,8,5,1,7}

这里的视频理解中,一趟只选出了一个
我们只要理解这个优化的思路就好了

选择排序


3.3 代码实现🏁

因为选择排序会用到交换
所以我们直接写一个交换函数

//交换函数
void swap(int* x, int* y)
{
	int tmp = *x;
	*x = *y;
	*y = tmp;
}

然后下面是我们的代码版本一:

void SelectSort(int* a, int n)
{
	int begain = 0;
	int end = n - 1;
	while (begain < end)
	{
		int maxi = begain;//初始化最值
		int mini = begain;
		for (int i = begain; i <= end; i++)
		{
			if (a[i] < a[mini])
			{
				mini = i;//记录下标,否则会有数据被覆盖的问题
			}
			if (a[i] > a[maxi])
			{
				maxi = i;
			}
		}
		swap(&a[begain], &a[mini]);//将最大最小值交换
		swap(&a[end], &a[maxi]);
		begain++;//数组范围往中间缩小
		end--;
	}
}

3.4 代码优化🏁

但是这个代码会出现一个问题:当数组中的最大值位于数组的第一个位置时,我们把begin和mini交换后,maxi指向的位置还是第一个元素,也就是最小值mini.再将maxi与end交换,就把最小值换到最后了!我们画图理解一下:

在这里插入图片描述


修改后的版本二

// 选择排序
void SelectSort(int* a, int n)
{
	int begain = 0;
	int end = n - 1;
	while (begain < end)
	{
		int maxi = begain;
		int mini = begain;
		for (int i = begain; i <=end; i++)
		{
			if (a[i] < a[mini])
			{
				mini = i;//记录下标,否则会有数据被覆盖的问题
			}
			if (a[i] > a[maxi])
			{
				maxi = i;
			}
		}
		swap(&a[begain], &a[mini]);
		if (maxi == begain)//当最大值为begain时,交换最小值和开头元素后,maxi指向的值不再是最大值了.
		{
			maxi = mini;
		}
		swap(&a[end], &a[maxi]);
		begain++;
		end--;
	}
}

4. 算法效率分析🚩

  1. 插入排序时间复杂度分析
  • 最优情况:待排序的数组是有序的.

只需当前数跟后一个数比较一下
一共需要比较N- 1次

时间复杂度为 : O ( N )

  • 最坏情况:待排序数组是逆序的

总次数记为:1+2+3+…+N-1
1代表第二个元素要移动一次.
2代表第三个元素要移动两次…
总共要挪动:(1+N-1)*(N-1)/2次

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


  1. 选择排序时间复杂度分析

选择排序不管数组有序还是无序
它都需要一遍一遍的遍历数组
即使我们这里做了一些优化
它还是要走2/N次,再乘以次数N

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


5. 总结与网站分享🚩

我们的八大排序中,插入排序选择和冒泡
可以分为一类,可以横向对比
经过我们刚才的分析可以得出一个结论:

插入排序 > 冒泡排序 > 选择排序

好家伙
合着冒泡还不是最菜的是吧(狗头保命)

在这里插入图片描述


这里给大家分享两个动图网站
里面的动图可以帮助我们理解
算法和数据结构的问题.

分别是:

  1. https://visualgo.net/en 点击即可访问

在这里插入图片描述

包括各大排序,链表,二叉树,哈希表等等

我们可以在左上角将英文转换成中文


  1. https://www.cs.usfca.edu/~galles/visualization/about.html
    点击即可访问

在这里插入图片描述

这个网站大家可以自己探索一下
小编也是最近才发现这个网站的


🔎 下期预告:希尔排序 🔍

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

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

相关文章

【Protobuf】Protobuf快速使用 Java版、Python版

【Protobuf】Protobuf快速使用 Java版、Python版 Protobuf介绍 快速使用(Java版) 创建 .proto文件&#xff0c;定义数据结构 安装Protobuf编译器(二选一) 使用IDEA编译(二选一) 使用编译后的文件 快速使用(Python版) 创建 .proto文件&#xff0c;定义数据结构 安装Prot…

【Spring源码解读三】IoC容器之AnnotationConfigApplication的refresh()刷新方法其二

invokeBeanFactoryPostProcessors() PriorityOrdered接口 Ordered接口 invokeBeanDefinitionRegistryPostProcessors() registerBeanPostProcessors() getBeanNamesForType() initMessageSource() initApplicationEventMulticaster() onRefresh() registerListeners()…

听我一句劝,别去外包,干了三年,真废了....

先说一下自己的情况&#xff0c;大专生&#xff0c;18年通过校招进入湖南某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试…

找不到xinput1_3.dll怎么办?xinput1_3.dll丢失的四个修复方法

在我们打开游戏的或者软件的时候&#xff0c;电脑提示“找不到xinput1_3.dll&#xff0c;无法继续执行此代码”怎么办&#xff1f;相信困扰着不少小伙伴&#xff0c;我再在打开吃鸡的时候&#xff0c;然后花了一上午的时候时间研究&#xff0c;现在终于知道xinput1_3.dll文件是…

Windows10系统开启 Telnet客户端 功能

1、应用场景 在实际工作中&#xff0c;经常有查看机器端口连通性的场景&#xff08;主要为了确认某台机器上的服务是否正常&#xff0c;比如&#xff1a;查看的端口 9091&#xff09; telnet 192.168.166.159 9091如下状态说明telnet 端口是通的 Ctrl ] ,退出Telnet连接&a…

探究Vue源码:mustache模板引擎(2) mustache使用方法

mustache是最早的模板引擎 比vue的诞生还要早很多 而他的语法 就是基于 {{ }} 这样的双花括号 mustache属于通用性的应用 他既可以在浏览器中直接用 也可以在npm中使用 这里 我们为了方便 就直接去拿在浏览器中使用的包了 没必要再自己搭个环境 大家可以下载我上传的资源 vue源…

职场老油条表示真干不过,部门新来的00后测试员已把我卷崩溃,想离职了...

在程序员职场上&#xff0c;什么样的人最让人反感呢? 是技术不好的人吗?并不是。技术不好的同事&#xff0c;我们可以帮他。 是技术太强的人吗?也不是。技术很强的同事&#xff0c;可遇不可求&#xff0c;向他学习还来不及呢。 真正让人反感的&#xff0c;是技术平平&#x…

Linux学习之vim正常模式和插入模式

使用vim新建或者打开一个文件后&#xff0c;首先进入的就是正常模式&#xff0c;从正常模式按不同的按键能够进入其他三种模式。 在正常模式下&#xff0c;按i&#xff0c;I&#xff08;大写的i键&#xff09;&#xff0c;a&#xff0c;A&#xff0c;o&#xff08;小写的o&…

【3DsMAX】从零开始建房(6)

目录 1. 制作广告牌 2. 制作屋顶小船船身 1. 制作广告牌 先创建一个长方体 转换为可编辑多边形&#xff0c;选中面&#xff0c;插入 挤出 添加两个圆柱体作为支架 用轮廓工具收一下面 选中这三个物体打组 统一材质 设置线条颜色为黑色 2. 制作屋顶小船船身 先添加一个球体&…

顺序表刷题(1~3)

目录 移除元素 删除有序数组重复项 合并有序数组 移除元素 方法一&#xff1a; 如果找到一个删除一个这样的时间复杂度为O(n^2)&#xff08;最坏删除所有数据&#xff09;删除后还要挪动数据。我们可以将符合条件的数组元素放入一个临时数组中&#xff0c;这种方法的时间复杂…

什么是数据结构

一、什么是数据结构 1、数据结构的定义 数据&#xff1a;从计算机的角度来看&#xff0c;数据是所有能被输入到计算机中且能被计算机处理的符号的集合。它是计算机操作的对象的总称&#xff0c;也是计算机处理信息的某种特定的符号表示形式&#xff08;二进制码的抽象表示&am…

【高级篇】服务异步通信

服务异步通信-高级篇 消息队列在使用过程中&#xff0c;面临着很多实际问题需要思考&#xff1a; 1.消息可靠性 消息从发送&#xff0c;到消费者接收&#xff0c;会经理多个过程&#xff1a; 其中的每一步都可能导致消息丢失&#xff0c;常见的丢失原因包括&#xff1a; 发送…

030 JavaWeb Html CSS

目录 JavaWeb概述1.访问web的原理2.C/S软件和B/S软件区别3.静态网站和动态网站 HTMLHTML的概述Table表格详细用法见W3CSchool.chm合并单元格课程表 img标签table和img标签组合使用a标签表单表单Get提交和post提交 div和span CSS1.CSS概述2.CSS语法3.CSS三种写法行内样式内部样式…

VueX使用简明笔记

1、作用&#xff1a; vuex是使用vue中必不可少的一部分&#xff0c;基于父子、兄弟组件&#xff0c;我们传值可能会很方便&#xff0c;但是如果是没有关联的组件之间要使用同一组数据&#xff0c;就显得很无能为力&#xff0c;那么vuex就很好的解决了我们这种问题&#xff0c;…

Knife4j的使用、SpringFox和SpringDoc介绍

knife4j是一个Swagger的增强工具&#xff0c;能够完善项目的接口文档。 官网&#xff1a; Knife4j 集Swagger2及OpenAPI3为一体的增强解决方案. | Knife4j Swagger的生成的默认文档确实不好用&#xff08;不美观、不支持搜索、不能导出&#xff09; 在Swagger2中使用 想一想…

Android 12.0 原生SystemUI下拉通知栏每条通知默认展开

1.前言 在12.0的系统rom原生开发中,在在对SystemUI下拉通知栏做定制的时候,在下拉状态栏的时候,通知栏中 最后一条通知默认是收缩的 点击按钮 就会展开 原生系统systemui就是如此,为了更美观 所以要求最后一条通知也默认展开,显得更美观 最终效果图: 2.原生SystemUI下拉通…

C++/C按照时间命名保存bin文件

背景 在Linux应用编程过程中&#xff0c;使用C或者C语言保存、读取bin文件是比较常见的需求。这里详细记录一下使用C保存bin文件&#xff0c;也可以使用C语言实现。 代码 C/C语言保存bin文件函数&#xff0c;C中也能使用 正确写入返回0&#xff0c;错误返回-1 // C 保存bi…

双重检查锁定与延迟初始化

双重检查锁定的由来 在Java程序中&#xff0c;有时候可能需要推迟一些高开销的对象初始化操作&#xff0c;并且只有在使用这些对象时才进行初始化。此时&#xff0c;程序员可能会采用延迟初始化。但要正确实现线程安全的延迟初始化需要一些技巧&#xff0c;否则很容易出现问题…

51单片机操作系统——RTX51 Tiny

简介 RTX51 是keil公司开发的一款实时操作系统&#xff0c;其有两个版本&#xff1a; 1.Tiny 2.Full&#xff0c;区别如下&#xff1a; RTX51 Full &#xff1a;使用四个任务优先权完成同时存在时间片轮转调度和抢先的任务切换 RTX51工作与中断功能相似的状态下 &#xff0c…

华为OD机试真题 JavaScript 实现【最远足迹】【2022Q4 100分】,附详细解题思路

一、题目描述 某探险队负责对地下洞穴进行探险。探险队成员在进行探险任务时&#xff0c;随身携带的记录器会不定期地记录自身的坐标&#xff0c;但在记录的间隙中也会记录其他数据。探索工作结束后&#xff0c;探险队需要获取到某成员在探险过程中相对于探险队总部的最远的足…