【数据结构】插入排序,希尔排序,选择排序,堆排序,冒泡排序

news2024/11/27 22:31:27

1.插入排序

思路:插入排序将一个数插入一个有序的数组里面,将这个数和数组元素挨着比较,直到他插入到合适的位置。
动画演示:
在这里插入图片描述

步骤:1.定义一个变量tmp保存要插入的数据
2.在循环中用tmp和有序数组中的元素比较(比方说要和a[end]比较,如果tmp<a[end]的话,就将a[end]右移动到a[end+1],如果tmp>a[end]的话就直接结束循环,因为已经找到了自己的位置,就是a[end+1].
3.当循环结束则表明已经找到了tmp的位置,下标为end+1,将tmp赋值给a[end+1]即可。
代码实现

void InsertSort(int* a, int n)
{
	
	
	for (int i = 0; i < n-1; i++)
	{
		int end = i;
		int tmp = a[end + 1];

		while (end >=0)
		{
			if (tmp < a[end])
			{
				a[end + 1] = a[end];
				end--;

			}
			else
			{
				break;
			}





		}
		a[end + 1] = tmp;







	}












}

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

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

2.希尔排序

希尔排序( 缩小增量排序 )
希尔排序法又称缩小增量法。希尔排序法的基本思想是:先选定一个整数,把待排序文件中所有记录分成个组,所有距离为的记录分在同一组内,并对每一组内的记录进行排序。然后,取,重复上述分组和排序的工作。当到达=1时,所有记录在统一组内排好序。相当于分组的插入排序。

步骤:
1.将要排列的数据分为几组
2.每一组内进行插入排序。
3.缩小组数,当组数为1时,相当于直接插入排序。
在这里插入图片描述

void ShellSort(int* a, int n)
{


	int gap = 3;

			for (int i = 0; i < n - gap; i += gap)
			{
				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;










			}
		
	












}

上面代码为单组的排序,只有一组。

void ShellSort(int* a, int n)
{


	int gap = 3;

	for (int j = 0; j < gap; j++)
	{
		for (int i = j; i < n - gap; i += gap)
		{
			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;










		}
	}
		
	












}

加了循环,将每组都排好序,但是整体没有有序。当gap!=1时,属于预排序。每次循环减小gap的值。说明分组在变,然后在每一组里面继续排序,当gap等于1时,相当于插入排序。

void ShellSort(int* a, int n)
{


	int gap = 3;

	while (gap >= 1)
	{
		gap /= 2;
		for (int j = 0; j < gap; j++)
		{
			for (int i = j; i < n - gap; i += gap)
			{
				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;










			}
		}
	}
		













}

上面这种是一组排,会多套一层循环。如果使用下面的代码是一组没排完,就进行排下一组,一组中先把前两个元素排好,在排第二组的前两个元素,当排完每一组的前两个元素,又回到第一组,排第一组的前三个元素,排好前三个元素,接着排第二组的前三个元素,依次类推。

时间复杂度平均:O(N^1.3)
空间复杂度:O(1)

3.选择排序

基本思想:
每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的
数据元素排完 。
步骤:1.定义两个变量maxi,mini分别记录要排序数据的最大值和最小值的下标。初始将·maxi,mini等于起始下标。
2.循环遍历要排序的数据,更新下标,如果有数据大于a[maxi],maxi更新为当前的i;如果有数据小于a[mini],mini更新为当前的i;
3.交换此时最小值和第一个数据的位置,最大值和最后一个数据的位置,已经保证了两个数据到他该有的位置。起始位置下标++,结束位置下标–;
4.然后就要排除已经排好的两个元素,现在maxi与mini起始下标就为第二个元素下标了。
5.循环条件起始位置下标小于结束位置下标。

动画演示:
在这里插入图片描述
代码实现:

void SelectSort(int* a, int n)
{
	int begin = 0;
	int end = n - 1;
	while (begin < end)
	{
		int maxi = begin;
		int mini = 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--;












	}
	








}

如果你要排序的数据里面最大的数据不是第一个的话,上面的代码你会觉得是正确的,如果第一个数据是最大的,排序就不对了,到底是为什么呢?我们可以调试调试
在这里插入图片描述
修改代码为:

void SelectSort(int* a, int n)
{
	int begin = 0;
	int end = n - 1;
	while (begin < end)
	{
		int maxi = begin;
		int mini = 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]);
		if (maxi == begin)
		{
			maxi = mini;
		}
		swap(&a[end], &a[maxi]);
		begin++;
		end--;












	}
	









}

直接选择排序的特性总结:
时间复杂度:O(N^2)
空间复杂度:O(1)

4.堆排序

堆排序是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。它是通过堆来进行选择数据。需要注意的是排升序要建大堆,排降序建小堆。

void AdjustDwon(int* a, int n, int root)//向下调整建立大堆。
{
	int child = root * 2 + 1;
	while (child < n)
	{
		if (child+1<n &&a[child] < a[child + 1])
		{
			child = child + 1;
		}



		if (a[child] > a[root])
		{
			swap(&a[child], &a[root]);
			root = child;
			child = root * 2 + 1;



		}
		else
		{
			break;
		}








	}



}

在这里插入图片描述
上图为建立的大堆。

堆排序演示

5.冒泡排序

思路:
左边大于右边交换一趟排下来最大的在右边
在这里插入图片描述
代码实现:

void BubbleSort(int* a, int n)
{
	for (int i = 0; i < n-1; i++)
	{
		for (int j = 0; j < n - i-1; j++)
		{
			if (a[j + 1] < a[j])
			{
				swap(&a[j], &a[j + 1]);
			}


        }







	}





}

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

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

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

相关文章

SpringBoot Seata 死锁问题排查

现象描述&#xff1a;Spring Boot项目&#xff0c;启动的时候卡住了&#xff0c;一直卡在那里不动&#xff0c;没有报错&#xff0c;也没有日志输出 但是&#xff0c;奇怪的是&#xff0c;本地可以正常启动 好吧&#xff0c;姑且先不深究为什么本地可以启动而部署到服务器上就无…

软件压力测试的重要性与用途

在当今数字化的时代&#xff0c;软件已经成为几乎所有行业不可或缺的一部分。随着软件应用规模的增加和用户数量的上升&#xff0c;软件的性能变得尤为关键。为了确保软件在面对高并发和大负载时仍然能够保持稳定性和可靠性&#xff0c;软件压力测试变得至关重要。下面是软件压…

python 使用 AppiumService 类启动appium server

一、前置说明 在Appium的1.6.0版本中引入了AppiumService类&#xff0c;可以很方便的通过该类来管理Appium服务器的启动和停止。 二、操作步骤 import osfrom appium.webdriver.appium_service import AppiumService as OriginalServerfrom libs import pathclass AppiumSer…

Python入门第1篇

前言 很久之前就知道有python这个东西&#xff0c;当时也想的学学&#xff0c;不过一直没做行动派。 那时候就听说用python进行Excel数据分析处理、爬虫等很是厉害&#xff0c;但是始终没有与python的关系更进一步。 Python简介 用我自己的话说&#xff0c;python也是一门面…

【面试经典150 | 二叉树】对称二叉树

文章目录 写在前面Tag题目来源解题思路方法一&#xff1a;递归方法二&#xff1a;迭代 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并附带一些对于本题涉及到的…

c 语言 堆的解析(自我理解)!!!堆排序,建堆

1.堆是什么&#xff1f; 首先先看一个图片 小顶堆的意思就是顶 的元素最小&#xff0c;两个子节点的元素要大于父节点。大顶堆同理。 小顶堆就像是一个金字塔。第一层很小&#xff0c;然后后面是依次增大&#xff0c;就像社会人才金字塔图一样。 大顶堆就可以想做&#xff0…

cesium学习记录

有段时间自学了cesium&#xff0c;这里记录一下自学过程&#xff0c;希望在所需之时查阅~~ 1、cesium源码获取与Index页面介绍 官网网址 www.cesiumjs.org 源代码下载&#xff1a;Platform-Dowmloads 在index.html右击open with Live server开启本地服务 点击Documentation…

RESTful API,以及如何使用它构建 web 应用程序。

RESTful API是一种基于REST&#xff08;Representational State Transfer&#xff09;架构风格的API&#xff08;Application Programming Interface&#xff09;&#xff0c;它采用HTTP协议中的GET、POST、PUT、DELETE等方法&#xff0c;对资源进行操作。RESTful API的核心思想…

Python (四)读写word

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一份大厂面试资料《史上最全大厂面试题》&#xff0c;Springboot、微服务、算法、数据结构、Zookeeper、Mybatis、Dubbo、linux、Kafka、Elasticsearch、数据库等等 …

HarmonyOS Developer——鸿蒙【构建第一个JS应用(FA模型)】

创建JS工程 JS工程目录结构 构建第一个页面 构建第二个页面 实现页面间的跳转 使用真机运行应用 说明 为确保运行效果&#xff0c;本文以使用DevEco Studio 3.1 Release版本为例&#xff0c;点击此处获取下载链接。 创建JS工程 若首次打开DevEco Studio&#xff0c;请点击…

【漏洞复现】万户协同办公平台ezoffice wpsservlet接口存在任意文件上传漏洞 附POC

漏洞描述 万户ezOFFICE集团版协同平台以工作流程、知识管理、沟通交流和辅助办公四大核心应用 万户ezOFFICE协同管理平台是一个综合信息基础应用平台。 万户协同办公平台ezoffice wpsservlet接口存在任意文件上传漏洞。 免责声明 技术文章仅供参考,任何个人和组织使用网络应…

C语言入门课程之课后习题之折半查找法

目录 1解题思路&#xff1a; 2代码所示&#xff1a; 3运行代码&#xff1a; 4习题不难&#xff0c;多刷题&#xff0c;练思路&#xff0c;最重要的不是学会了一道题&#xff0c;而是掌握其编程思想&#xff1b; 1解题思路&#xff1a; 折半查找法&#xff08;half-interval…

机器人刚性碰撞任务的阻抗控制性能

问题描述 对于机器人刚性碰撞任务&#xff0c;阻抗控制可以有效地提高机器人的适应性和稳定性。 在刚性碰撞任务中&#xff0c;机器人在接触外部物体时需要快速适应并调整自身的运动轨迹和速度&#xff0c;以实现精确的操控和稳定的交互。阻抗控制可以通过调整机器人的阻抗参…

【数电笔记】54-或非门构成的基本RS触发器

目录 1. 电路组成 2. 逻辑功能 3. 特性表 4. 特性方程 5. 例题 6. 两种基本RS触发器的形式比较 笔记配套视频来源&#xff1a;B站&#xff1b;本系列笔记并未记录所有章节&#xff0c;只对个人认为重要章节做了笔记&#xff1b;标题前面的数字标号就是对应的视频章节&…

【【水 MicroBlaze 最后的介绍和使用】】

水 MicroBlaze 最后的介绍和使用 我对MicroBlaze 已经有了一个普遍的理解 了 现在我将看的两个 一个是 AXI4接口的 DDR读写实验 还有一个是 AXI DMA 环路实验 虽然是 水文 但是 也许能从中 得到一些收获 第一个是 AXI DDR 读写实验 Xilinx 从 Spartan-6 和 Virtex-6 系列开始…

元宇宙真的凉凉了吗?

AI和元宇宙作为引领技术和产业发展的两个并行元素正在加速融合&#xff0c;激发出行业强大的创新力。 这里重点讲一下元宇宙。它是建立在区块链之上的虚拟世界&#xff0c;去中心化平台让用户拥有所有权和自治权。通过沉浸式的体验&#xff0c;让虚拟更接近现实。 随着我国元宇…

学习Pinia

Pinia 1.介绍Pinia2.起步 安装3.看完文章学会pinia 1.介绍Pinia Pinia.js 有如下特点&#xff1a; 完整的 ts 的支持&#xff1b; 足够轻量&#xff0c;压缩后的体积只有1kb左右; 去除 mutations&#xff0c;只有 state&#xff0c;getters&#xff0c;actions&#xff1b; a…

苹果股价为何会在11月份突然暴涨?12月份还会继续上涨吗?

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 苹果股价受益于大盘而上涨 随着第四季度财报的公布&#xff0c;全球市值最高的公司苹果(AAPL)的股价在上个月出现了暴涨&#xff0c;并在11月份剩下的大部分时间里一直保持着与标普500指数一致的走势。 猛兽财经认为主要原…

学习IO的第三天

作业1 使用文件IO完成对图像的读写操作 #include <head.h>int main(int argc, const char *argv[]) {int fd -1;if((fdopen(argv[1],O_RDONLY)) -1){perror("open error");return -1;}int wd -1;if((wdopen(argv[2],O_WRONLY|O_CREAT|O_TRUNC,0664)) -1){…

luceda ipkiss教程 42:获取版图所有的电端口

通过判断版图端口的domain.name&#xff0c;可以知道端口是电端口还是光端口&#xff1a; 如&#xff1a; 可以通过如下代码获取两个电端口&#xff08;anode和cathode&#xff09;的信息&#xff1a; from si_fab import all as pdkdef get_electrical_ports(layout):ports …