「数据结构」八大排序1

🎇个人主页:Ice_Sugar_7
🎇所属专栏:初阶数据结构
🎇欢迎点赞收藏加关注哦!

文章目录

  • 🍉插入排序
    • 🍌直接插入排序
      • 🥝复杂度及稳定性
    • 🍌希尔排序
      • 🥝预排序
      • 🥝复杂度及稳定性
  • 🍉选择排序
    • 🍌复杂度及稳定性
  • 🍉堆排序
    • 🍌复杂度及稳定性
  • 🍉写在最后

🍉插入排序

插排就是将一个元素插入一个有序序列中合适的位置,分为直接插入排序希尔排序

🍌直接插入排序

流程如下:
①保存待插入的值:假设某一趟中有序序列最后一个元素下标为end,先保存(end+1)位置的元素,保存到临时变量tmp。

②为a[end+1]找到合适的位置:使用while循环,里面比较a[end]和a[end+1]的大小。
若前者<后者,就退出循环
反之,则将a[end]往后挪一位,覆盖掉a[end+1],end减1,然后让tmp继续往前找,直到找到比它小的元素或者end < 0(end<0说明所有元素都比tmp大,那么就应该把tmp放在a[0]),插到该元素后面。

简而言之就是让tmp向前找比它小的元素,找到就插在它的后面;找不到就是插在第一位

③至此,我们排好了一个数据,现在要排列所有元素,只需在外面套上一层for循环
(假设数组有n个元素,注意循环的终止条件是i < n-1,即i最多只能取到n-2,因为是 i 和 i+1 进行比较)

比如:

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

图解如下:
在这里插入图片描述
在这里插入图片描述

代码如下:

//n为数组元素个数
void InsertSort(int* a, int n) {
	for (int i = 0; i < n-1; i++) {
		int end = i;  //end为有序序列最后一个元素的下标
		int tmp = a[end + 1];  //tmp保存待插入的数据
		while (end >= 0)
		{
			if (a[end + 1] < a[end]) //待插入的数比end小,那么end就向后移动,给待插入的数据挪出位置
				a[end + 1] = a[end];
			else
				break;
			end--;  //更新end,向前找小 
		}
		//找到小或end == -1
		a[end + 1] = tmp;
	}
}

🥝复杂度及稳定性

时间复杂度:第一趟1次,第二趟2次……由等差数列公式可以推出是O(N^2)
空间复杂度:O(1)
稳定性:稳定


🍌希尔排序

希尔排序是直接插入排序的优化。分两步完成:预排序+直接插入排序
预排序的意义:让大的数更快到后面,小的数更快到前面。使序列趋于有序,降低直接插入排序的成本

🥝预排序

直接插入排序是让相邻的元素进行比较。预排序则是让一个元素和与它相隔几个位置的元素比较
比如:

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

在这里插入图片描述
9、5、8、5可以分为一组;1、7、6也是一组;2、4、3同理
同一组的元素进行比较,排好序。
预排序后得到:
在这里插入图片描述

这样就完成了一次预排序。希尔排序中有多次预排序,每次排完后会缩小间隔、重新分组,然后继续预排序。假设最开始的间隔为gap,那么就一直缩小,gap越小,预排序一次后序列就越趋于有序。直到gap为1,此时就是直接插入排序,这一次排好后序列就有序了

gap每次预排序一般是缩小到上一次的一半,或是1/3(注意gap除以3之后需要+1,保证gap不为0)
代码如下:

void ShellSort(int* a, int n) {
	int gap = n;
	while (gap > 1)
	{
		gap = gap / 3 + 1;  //+1确保gap至少为1,最后一次循环gap == 1
		//一次预排序
		for (int i = 0; i < n - gap; i++)  //i+gap最多取到n-1
		{
			int end = i;
			int tmp = a[end + gap];
			while (end >= 0)
			{
				if (a[end] > tmp)
					a[end+gap] = a[end];
				else
					break;
				end -= gap;
			}
			a[end + gap] = tmp;
		}
	}
}

🥝复杂度及稳定性

时间复杂度:O(N^1.3)
空间复杂度:O(1)
稳定性:不稳定。因为预排序很容易就把相同的数的相对顺序打乱了


🍉选择排序

排序思路:
●假设序列最左边、右边下标分别为begin、end
●从序列中找出最大、最小值,并分别将它们放到下标为begin、end的地方
●找出第二大和第二小,分别放到begin+1、end-1
●剩下元素也按照这样排列

在“交换位置”这一步有一个很坑的点,如果最小值刚好在end,那就会和最大值交换位置,但是此时我们的mini仍然在end,直接交换a[mini]和a[begin]就会把最大值和begin处的元素交换位置
所以在最大值和a[end]交换之后检查一下,看mini是否在end处。如果是,就将maxi赋值给mini(因为此时maxi指向的就是最小值)

void SelectSort(int* a, int n) {
	int begin = 0;
	int end = n - 1;
	while (begin < end)
	{
		int mini = begin,maxi = begin;
		for (int i = begin + 1; i <= end; i++)
		{
			if (a[maxi] < a[i])
				maxi = i;
			if (a[mini] > a[i])
				mini = i;
		}
		Swap(&a[maxi], &a[end]);
		if (end == mini)  //让mini重新指向最小值
			mini = maxi;
		Swap(&a[mini], &a[begin]);
		++begin;
		--end;
	}
}

🍌复杂度及稳定性

时间复杂度:第一趟走(n-2)次,第二趟走(n-4)次,第 i 趟走(n-2*i)次……由等差数列公式,可以得出时间复杂度为O(N^2)
空间复杂度:O(1)
稳定性:不稳定。比如1 9 9 4 2 1 3 6,第一趟第一个9就会被换到最后面


🍉堆排序

前面的文章有讲过,升序建大堆,降序建小堆
比如排升序,就建大堆,然后让堆顶元素和堆中最后一个元素交换位置,再进行调整

void HeapSort(int* a, int k) {  //a为给定数组
	for (int i = (k - 1 - 1) / 2; i >= 0; i--) {   //调整为一个堆
		AdjustDown(a, k, i);
	}

	for (int i = k - 1; i >= 0; i--) {  //采用删除结点的思想,先交换,再调整
		Swap(a[0], a[i]);
		AdjustDown(a, i, 0);
	}
}

🍌复杂度及稳定性

时间复杂度:如果有n个数据,那么堆的深度就是logn,最坏情况下,有(n-1)个数据需要调整,所以近似是(n-1)logn,又因为logn的量级比nlogn小,可以忽略,所以时间复杂度就是O(N*logN)
(注意:实际比N * logN略小一些)

上面说“近似”是因为并不是每个数据都要调整logn层,但是由于logn一般不大(参考:2的30次方是10亿多一点,此时logn就是30),它的大小一般就是几十这样子,所以相差这一点对于时间复杂度基本没影响

空间复杂度:O(1)
稳定性:不稳定


🍉写在最后

以上就是本篇文章的全部内容,如果你觉得本文对你有所帮助的话,那不妨点个小小的赞哦!(比心)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

亚信安慧AntDB携核心业务系统数据库升级改造方案亮相“2023年国有企业应用场景发布会”

近日&#xff0c;亚信安慧AntDB数据库携核心业务系统数据库升级改造方案亮相“2023年国有企业应用场景发布会”。本次国有企业应用场景发布会由北京市国资委主办、中关村发展集团承办、中关村软件园公司协办&#xff0c;以“融通创新 智引未来”为主题&#xff0c;聚焦智慧城市…

虚拟机添加显示屏

1、关闭虚拟机&#xff0c;虚拟机在为关机的情况下&#xff0c;虚拟机设置->显示器->监视器 都是灰色的&#xff0c;不能设置&#xff1b; 2、虚拟机设置->显示器->监视器 “监视器数量” 设置为2 “拉伸模式” 不要勾选 点确定 3、点击 查看->循环使用多个…

解决SyntaxError: future feature annotations is not defined,可适用其他包

方法&#xff1a;对报错的包进行降级 pip install tikzplotlib0.9.8site-packages后面是使用pip install安装的包&#xff0c;根据这个找到报错的包 想法来源&#xff1a; 环境是python3.6&#xff0c;完全按照作者要求进行环境配置&#xff0c;但仍报错。 我在网上找的解决…

【Java基础篇】常见的字符编码、以及它们的区别

常见的字符编码、以及它们的区别 ✔️ 解析✔️扩展知识仓✔️Unicode和UTF-8有啥关系?✔️有了UTF-8&#xff0c;为什么要出现GBK✔️为什么会出现乱码 ✔️ 解析 就像电报只能发出 ”滴” 和 ”答” 声一样&#xff0c;计算机只认识 0 和 1 两种字符&#xff0c;但是&#x…

Sourcetree安装和配置

先了解Sourcetree是用来做什么的 简单说就是一个有可视化界面的Gti 用途&#xff1a; &#xff08;1&#xff09;克隆(clone)&#xff1a;从远程仓库URL加载创建一个与远程仓库一样的本地仓库 提交(commit)&#xff1a;将暂存文件上传到本地仓库&#xff08;我们在Finder中对本…

目标管理(案例)

介绍 本篇Codelab将介绍如何使用State、Prop、Link、Watch、Provide、Consume管理页面级变量的状态&#xff0c;实现对页面数据的增加、删除、修改。要求完成以下功能&#xff1a; 实现一个自定义弹窗&#xff0c;完成添加子目标的功能。实现一个可编辑列表&#xff0c;可点击指…

docker-compose Install spug 3

前言 Spug 面向中小型企业设计的轻量级无 Agent 的自动化运维平台,整合了主机管理、主机批量执行、主机在线终端、文件在线上传下载、应用发布部署、在线任务计划、配置中心、监控、报警等一系列功能。 创建一键安装spug 脚本 自动化脚本兼容(ubuntu,RedHat系列及复刻系列,…

SpringBoot 接口对枚举类型的入参以及出参的转换处理

目录 1、在项目中使用枚举类型2、不做任何处理的演示效果2.1、接口出参2.2、接口入参 3、用枚举的code作为参数和返回值3.1 代码案例3.1.1、定义枚举基础接口BaseEnum&#xff0c;每个枚举都实现该接口3.1.2、性别Sex枚举并实现接口BaseEnum3.1.3、定义BaseEnum枚举接口序列化3…

P1029 [NOIP2001 普及组] 最大公约数和最小公倍数问题

网址如下&#xff1a;P1029 [NOIP2001 普及组] 最大公约数和最小公倍数问题 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 水了道题 学了求最小公倍数和最大公因数的新方法 我对辗转相除法这个东西有所耳闻&#xff0c;但是从来没有用过 所以我只会枚举法求这两个东西 而…

切换node.js不同版本

切换node.js不同版本 因新项目用到vite4创建项目&#xff0c;输入命令后报错&#xff0c;经查询得知是node版本过低导致&#xff0c;所以需要升级node版本&#xff0c;但是又有老的项目需要维护&#xff0c;因此需要多个版本的node使用需求。 流程&#xff1a; 卸载原有的node…

人机交互主板定制_基于MT8735安卓核心板的自助查询机方案

人机交互主板是一种商显智能终端主板&#xff0c;广泛应用于广告机、工控一体机、教学一体机、智能自助终端、考勤机、智能零售终端、O2O智能设备、取号机、计算机视觉、医疗健康设备、机器人设备等领域。 人机交互主板采用联发科MTK8735芯片平台&#xff0c;四核Cortex-A53架构…

使用fabric.js实现对图片涂鸦、文字编辑、平移缩放与保存功能

文章目录 背景1.初始化画布1.创建画布2.设置画布大小 2.渲染图片3.功能&#xff1a;开启涂鸦4.功能&#xff1a;添加文字5.旋转图片6.画布平移7.画布缩放8.保存图片9.上传图片10.销毁实例11.总结 背景 项目中有个需求&#xff0c;需要对图片附件进行简单的编辑操作&#xff0c…

C语言注意点(4)

1、void *a是什么意思 答&#xff1a;泛型指针&#xff0c;但不规定其类型(就是地址确定&#xff0c;但数据长度不确定)在动态分配内存时&#xff0c;malloc的返回值就是该类型&#xff0c;方便用户进行强制转换。 2、VS怎么一键规范格式 for(i0;i<10;i)enter后&#xff0c;…

在C++11中利用for()循环遍历迭代器的同时,也可对容器内的数据进行更改

一、for (auto &&it : _groups){}含义&#xff1a; for (auto &&it : _groups) 是一个范围-based for 循环&#xff08;也称为 foreach 循环&#xff09;&#xff0c;用于遍历容器 _groups 中的元素。这种循环语法在 C11 及更高版本中引入&#xff0c;允许以一…

自定义列表里面实现多选功能

需求 我们在开发过程中有时候会遇到列表里面会有多选&#xff0c;然后列表样式也要进行自定义。这里我们如果直接使用ElementUI组件el-table表格的时候这里实现起来可能比较复杂不方便&#xff0c;我们这里手写自定义一下列表里面多选的功能。 实现效果如下图所示&#xff1a…

私域和微商有什么区别?

私域和微商到底有什么区别呢&#xff1f;其实这两个东西有着本质性区别。 私域&#xff1a; 通过原有商业或者新媒体方式获取粉丝或顾客&#xff0c;然后用微信等社交工具&#xff0c;多方位展现&#xff0c;人格专业。 最终目标是让粉丝或顾客成为品牌或IP的朋友&#xff0…

【嵌入式】About USB Powering

https://www.embedded.com/usb-type-c-and-power-delivery-101-power-delivery-protocol/https://www.embedded.com/usb-type-c-and-power-delivery-101-power-delivery-protocol/ Type-C接口有多强&#xff1f;PD协议又是什么&#xff1f;-电子发烧友网由于Type-C接口自身的强…

STM32入门教程-2023版【3-2】详细讲解实现LED流水灯

关注 点赞 不错过精彩内容 大家好&#xff0c;我是硬核王同学&#xff0c;最近在做免费的嵌入式知识分享&#xff0c;帮助对嵌入式感兴趣的同学学习嵌入式、做项目、找工作! 三、LED流水灯 依据电路图连接电路 复制LED闪烁的工程&#xff0c;改个名字叫3-2 LED流水灯 修改…

Android 内容生成pdf文件

1.引入itext7 implementation com.itextpdf:itext7-core:7.1.13上面比较大&#xff0c;可以直接下载需要集成的jar包 implementation files(libs\\layout-7.1.13.jar) implementation files(libs\\kernel-7.1.13.jar) implementation files(libs\\io-7.1.13.jar) implementatio…

亚马逊站内广告位置在哪设置?怎么设置广告位置?-站斧浏览器

亚马逊站内广告位置在哪设置&#xff1f; 亚马逊提供了多种广告类型&#xff0c;包括&#xff1a; Sponsored Products&#xff08;赞助产品&#xff09;&#xff1a;在搜索结果和商品详情页中展示。 Sponsored Brands&#xff08;赞助品牌&#xff09;&#xff1a;在搜索结…