【数据结构】——排序篇(上)

news2024/11/19 16:26:31

前言:前面我们已经学过了许许多多的排序方法,如冒泡排序,选择排序,堆排序等等,那么我们就来将排序的方法总结一下。

在这里插入图片描述

我们的排序方法包括以下几种,而快速排序和归并排序我们后面进行详细的讲解。
在这里插入图片描述

直接插入排序:

void InsertSort(int* a, int n)
{
	// [0, end] end+1
	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;
	}
}

直接插入排序顾名思义把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列 。
我们用一个变量来保存我们插入数据的原数组中的后一个数据,我们排的是降序,那么我们的后一个数据比前一个数据大的话,我们的后一个数据tmp就被前一个覆盖,直到end<0或者我们的后一个数据比前一个小我们就跳出循环,我们保存的数据就等于我们跳出循环的这个数。

希尔排序:

void ShellSort(int* a, int n)
{
	int gap = n;

	// gap > 1时是预排序,目的让他接近有序
	// gap == 1是直接插入排序,目的是让他有序
	while (gap > 1)
	{
		//gap = gap / 2;
		gap = gap / 3 + 1;

		for (int i = 0; i < n - 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时,所有记录在统一组内排好序。
在这里插入图片描述
我们利用希尔排序法可以将数组分成gap组,gap是我们没组两个树之间的间隔, 如果我们的gap是3时,我们就分成了三组,当gap等于0时,我们的红色这组就进行插入排序,当gap为1时,我们蓝色这组就进行插入排序,当gap为2时,我们绿色这组就进行插入排序,这样我们将完成了第一趟排序。我们要完成整个排序的话,我们就得在嵌套一层循环,我们的gap大于1时就进行预排序,我们的gap为1时就是最后一趟排序,我们的gap无论是几,只要最后gap的值为1我们就完成了排序。

选择排序:

void Swap(int* p1, int* p2)
{
	int tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}
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[mini])
			{
				mini = i;
			}

			if (a[i] > a[maxi])
			{
				maxi = i;
			}
		}

		Swap(&a[begin], &a[mini]);
		if (maxi == begin)
		{
			maxi = mini;
		}
		Swap(&a[end], &a[maxi]);

		++begin;
		--end;
	}
}

我们这里用两个变量来保存小数和大数的下标,我们的后面循环里的数如果比下标为0的数小的话,小数据mini的下标就是我们比第一个数据小的数据i的坐标,我们排序排的是升序,我们的第一个数就是应该是下标为mini的数据,所以我们将就下标为mini的数据与第一个数据交换,们的后面循环里的数如果比下标为0的数大的话就是存放大数据,下标为maxi,我们就用最后一个数据和下标为maxi的数据交换。如果我们最后循环退出的时候我们的maxi还等于begin,那么我们的下标为begin的数据就是最小的。

堆排序:

void Swap(int* p1, int* p2)
{
	int tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}
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]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break;
		}
	}
}

// 升序
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;
	}
}

我们要排升序,所以我们需要建立一个大堆,大堆的特点是子节点大于根节点,我们通过不断将根节点和最后一个节点交换,进行向下调整,我们的数据大的节点就会沉在底下,而小的节点就会浮在上面,最后我们通过遍历就能够输出升序的数据。

冒泡排序:

void Swap(int* p1, int* p2)
{
	int tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}
void BubbleSort(int* a, int n)
{
	for (int j = 0; j < n; j++)
	{
		bool exchange = false;
		for (int i = 1; i < n - j; i++)
		{
			if (a[i - 1] > a[i])
			{
				Swap(&a[i - 1], &a[i]);
				exchange = true;
			}
		}

		if (exchange == false)
			break;
	}

冒泡排序我们很早之前就已经了解过了,我这里就不多赘述了,如果有疑问的话就看我之前的文章
https://blog.csdn.net/Lehjy/article/details/132266676,相信以你的聪明才智一定可以完美的解决。

最后感谢大家一如既往的支持!谢谢大家!

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

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

相关文章

【SpringBoot】解析Springboot事件机制,事件发布和监听

解析Springboot事件机制&#xff0c;事件发布和监听 一、Spring的事件是什么二、使用步骤2.1 依赖处理2.2 定义事件实体类2.3 定义事件监听类2.4 事件发布 三、异步调用3.1 启用异步调用3.2 监听器方法上添加 Async 注解 一、Spring的事件是什么 Spring的事件监听&#xff08;…

Android 从assets读取文件装载成Bitmap,Kotlin

Android 从assets读取文件装载成Bitmap&#xff0c;Kotlin /*** fileName assets里面图片文件名*/fun readBitmapFromAssets(ctx: Context, fileName: String): Bitmap? {val assetManager: AssetManager ctx.assetsvar bitmap: Bitmap? nulltry {val inputStream assetMa…

自行编写一个简单的shell!

本文旨在编写一个简单的shell外壳程序&#xff01;功能类似于shell的一些基本操作&#xff01;虽然不能全部实现shell的一些功能&#xff01;但是通过此文章&#xff0c;自己写一个简单的shell程序也是不成问题&#xff01;并且通过此文章&#xff0c;可以让读者对linux中一些环…

实现一个简单的外卖系统

在这个技术飞速发展的时代&#xff0c;外卖系统已经成为人们生活中的一部分。通过一些简单的技术代码&#xff0c;我们可以搭建一个基本的外卖系统&#xff0c;让用户方便地选择、下单和支付。本文将使用Python和Flask框架为基础&#xff0c;演示一个简单的外卖系统的实现。 …

基于ssm海鲜自助餐厅系统论文

摘 要 网络技术和计算机技术发展至今&#xff0c;已经拥有了深厚的理论基础&#xff0c;并在现实中进行了充分运用&#xff0c;尤其是基于计算机运行的软件更是受到各界的关注。加上现在人们已经步入信息时代&#xff0c;所以对于信息的宣传和管理就很关键。因此海鲜餐厅信息的…

C/C++之输入输出

文章目录 一.C语言的输入输出1.printfi. 输出整数ii. 浮点数iii.字符 & 字符串 2.scanfi.整数ii.浮点数iii. 字符 & 字符串 3.特殊用法i. * 的应用ii. %n 的应用iii. %[] 的应用 二.C中的输入输出1.couti. 缓冲区&#xff08;buffer&#xff09;ii. cout之格式化输出 2…

鸿蒙开发组件之Text

一、文本组件Text加载主要有两种方式&#xff1a; 1、直接写的文本 Text(你好&#xff0c;世界) 2、从本地资源读取的文本 Text($r(app.string.xxxx)) 二、文本国际化 其中&#xff0c;文本设置可以支持国际化。可以通过对本地文本读取支持国际化。在需要设置国际化的文本…

在AWS Lambda上部署EC2编译的FFmpeg工具——自定义层的方案

大纲 1 确定Lambda运行时环境1.1 Lambda系统、镜像、内核版本1.2 运行时1.2.1 Python1.2.2 Java 2 环境准备2.1 创建EC2实例 3 编译FFmpeg3.1 连接EC2 4 编译5 上传S3存储桶5.1 创建S3桶5.2 创建IAM策略5.3 创建IAM角色5.4 EC2关联角色5.5 修改桶策略5.6 打包并上传 6 创建Lamb…

【vue3】尚硅谷vue3学习笔记

Vue3快速上手 1.Vue3简介 2020年9月18日&#xff0c;Vue.js发布3.0版本&#xff0c;代号&#xff1a;One Piece&#xff08;海贼王&#xff09;耗时2年多、2600次提交、30个RFC、600次PR、99位贡献者github上的tags地址&#xff1a;https://github.com/vuejs/vue-next/release…

记录 | ubuntu监控cpu频率、温度等

ubuntu监控cpu频率、温度等 采用 i7z 进行监控&#xff0c;先安装&#xff1a; sudo apt install i7z -ysudo i7z

vue3 自己写一个月的日历

效果图 代码 <template><div class"monthPage"><div class"calendar" v-loading"loading"><!-- 星期 --><div class"weekBox"><div v-for"(item, index) in dayArr" :key"index&q…

5G+AI开花结果,助力智慧安检落地

“请带包的乘客过机安检&#xff01;”&#xff0c;深圳地铁、腾讯共同打造的5GAI智慧安检辅助系统亮相福田枢纽站&#xff0c;进一步解放了人力&#xff0c;提高安检效率&#xff0c;为交通安全保驾护航&#xff0c;让智慧出行成为现实。 传统的安检设备均为人工肉眼辨识&…

【Vue+Python】—— 基于Vue与Python的图书管理系统

文章目录 &#x1f356; 前言&#x1f3b6;一、项目描述✨二、项目展示&#x1f3c6;三、撒花 &#x1f356; 前言 【VuePython】—— 基于Vue与Python的图书管理系统 &#x1f3b6;一、项目描述 描述&#xff1a; 本项目为《基于Vue与Python的图书管理系统》&#xff0c;项目…

Java第21章网络通信

网络程序设计基础 网络程序设计编写的是与其他计算机进行通信的程序。Java 已经将网络程序所需要的元素封 装成不同的类&#xff0c;用户只要创建这些类的对象&#xff0c;使用相应的方法&#xff0c;即使不具备有关的网络支持&#xff0c;也可 以编写出高质量的网络…

手把手带你创建HAL版本MDK工程模板

手把手带你创建HAL版本MDK工程模板 如何快速开发 STM32 项目&#xff1f;我们总不能每次开发一个项目就搭建一次工程&#xff0c;这样效率太低了。 通常我们会使用一个模板工程&#xff0c;需要开发新项目的时候拿出来添加一些对应的模块及业务代码&#xff0c;一个项目就开发…

BearPi Std 板从入门到放弃 - 先天篇(1)(阶段 : 智慧城市 - 智慧路灯)

简介 对前面几篇整合, 做个小小汇总试验, 使用BearPi E53_SC1扩展板主芯片: STM32L431RCT6串口: Usart1扩展板与主板连接: I2C : I2C1 (光照强度传感器&#xff1a;BH1750)LED: PB9步骤 创建项目 参考 BearPi Std 板从入门到放弃 - 引气入体篇&#xff08;1&#xff09;(由零创…

LabelImg的使用及注意事项

LabelImg是一款开源的图像标注工具&#xff0c;它主要用于标注目标检测、语义分割和图像分类等深度学习中需要的数据集。通过使用LabelImg&#xff0c;用户可以快速、准确地为图片中的目标添加标注信息&#xff0c;从而建立数据集。 使用步骤&#xff1a; 下载LabelImg&#x…

word中,文本框如何跨页?

我们经常使用word编辑一些文档&#xff0c;文档中往往会有一些比较大的文本框&#xff0c;需要跨多页&#xff0c;我们可以使用本文章中的方法&#xff0c;将文本框连接在一起&#xff0c;是的内容自动跨页。 在文字中插入两个文本框如下图&#xff1a; 将内容放到第一个文本框…

基于SpringBoot的大学活动平台

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目背景介绍&#xff1a; 随着互联网技术的不断…

Kotlin:内置函数let、also、with、run、apply

前言 在Kotlin中&#xff0c;有一些用于扩展 & 方便开发者编码的内置函数&#xff0c;能大大提高开发者的开发效率。今天&#xff0c;我将主要讲解的是&#xff1a; let函数also函数with函数run函数apply函数 基础知识&#xff1a;接口回调中Lambda使用 在Kotlin中可使用…