【数据结构】排序之交换排序(冒泡 | 快排)

交换目录

  • 1. 前言
  • 2. 交换排序
  • 3. 冒泡排序
    • 3.1 分析
    • 3.2 代码实现
  • 4. 快速排序
    • 4.1 hoare版本
      • 4.1.1 分析
      • 4.1.2 hoare版本代码
    • 4.2 挖坑法
      • 4.2.1 分析
      • 4.2.2 挖坑法代码实现
    • 4.3 前后指针版本
      • 4.3.1 分析
      • 4.3.2 前后指针版本代码实现

1. 前言

在之前的博客中介绍了插入排序,有需要的可以点这个链接: link,这次来介绍交换排序,包括冒泡和快排。
话不多说,正文开始。

2. 交换排序

基本思想:所谓交换,就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置。

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

交换排序这里介绍冒泡排序和快速排序,来一起看看。

3. 冒泡排序

在这里插入图片描述
动图形象的展示了冒泡排序的过程。

冒泡排序的特性总结:

  1. 冒泡排序是一种非常容易理解的排序
  2. 时间复杂度:O(N^2)
  3. 空间复杂度:O(1)
  4. 稳定性:稳定

3.1 分析

交换排序肯定离不开交换,就先写一个Swap。

void Swap(int* p1, int* p2)
{
	int tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}

同样的方法,先实现单趟排序,如果前一个大于后一个就交换,把最大的放在了最后。
得注意把控区间的位置,如果if中的代码是a[i+1]>a[i],那么上面循环的区间就是从0到n-1。
在这里插入图片描述
第一趟的位置在n-1,那么第j趟就是n-j。
所以对于总的来排,就在外面套一个循环,也就是:
在这里插入图片描述
来看看使用结果
在这里插入图片描述
如果说没有给定的数据已经排好序了,就不用经行交换了,就加一个标志bool exchange = false,如果交换了就变为true。
在这里插入图片描述

3.2 代码实现

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;
	}

}

4. 快速排序

快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法。

其基本思想为:任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止。

快速排序有三种实现方法,下面来介绍。

4.1 hoare版本

hoare版本是怎么实现的?
来看看动图:
在这里插入图片描述
可以看到这里,先选取了一个关键的值key,
在这里插入图片描述

然后右边边开始走,可以发现,当右边找到第一个比key小的值,就停下来。然后走左边,左边找到第一个比key大的值,然后左右两边交换;交换完,又继续。
在这里插入图片描述
当左右两边相遇就结束,然后将key与这个位置交换。
在这里插入图片描述
为什么要相遇位置比key的值小?
因为是从右边先走,相遇就有两种情况:

  1. R遇到L,R没有找到比key小的值,就一直走,直到遇见L,相遇位置是L,比key小。
  2. L遇到R,R先走,找到小于key的值就停下,L找大,一直找,没有找到,但是遇见R就停下来,相遇位置就是R找到小的位置,也比key要小。

4.1.1 分析

用keyi来记录交换值的下标。

同样先看单趟排序,在上面已经分析了。
首先右边先走,找小,那么它的代码是
在这里插入图片描述
左边找大。
在这里插入图片描述
但是走到结尾会发生错误,可能会错位,出现right<left的情况,所以在循环里面多加一个判断。
在这里插入图片描述
循环出来后就交换。
要让keyi到它最终的位置,就得用while ( left < right)来走,当走完后,交换key和left。任何继续排下一个数。
这里的keyi将区间分为三部分:[begin,keyi-1],keyi,[keyi+1,end]。
如果左边有序,右边有序,那么整体就有序。
在这里插入图片描述
用递归实现,当这个区间只有一个值或者没有值时候,结束。否则就调用左区间和右区间。
在这里插入图片描述

实现结果:在这里插入图片描述

4.1.2 hoare版本代码

void QuickSort(int* a, int begin, int end)
{
	if (begin >= end)
		return;
		int left = begin, right = end;
		int keyi = begin;
		while ( left < right)
		{
			// 右边找小
			while (left < right && a[right] >= a[keyi])
			{
				--right;
			}

			// 左边找大
			while (left < right && a[left] <= a[keyi])
			{
				++left;
			}
			
			Swap(&a[left], &a[right]);
		}

		Swap(&a[left], &a[keyi]);
		keyi = left;

		// [begin, keyi-1] keyi [keyi+1, end]
		QuickSort(a, begin, keyi - 1);
		QuickSort(a, keyi + 1, end);
	
}

4.2 挖坑法

看动图展示一下:
在这里插入图片描述
把左边位置的值先挖出来,用key先保存起来。形成了第一个坑位。
在这里插入图片描述
然后右边先走,找到比key要小的值,然后就把这个值,取出来放到这个坑中。在这里插入图片描述
然后形成了新的坑。
在这里插入图片描述
然后左边找大,找到大以后,将它扔到坑中。
在这里插入图片描述
直到它们两个相遇就终止了,然后把key填上。
在这里插入图片描述

4.2.1 分析

挖坑法没有hoare版的复杂,先找到右边找到小放在坑里,左边找到大的放坑里,在相遇时候把key放进去就行。
为了方便递归,重新写递归部分在,将坑位置的值传进去就行。
在这里插入图片描述
举个例子实现一下:
在这里插入图片描述

4.2.2 挖坑法代码实现

int PartSort2(int* a, int begin, int end)
{
	
	int key = a[begin];
	int hole = begin;
	while (begin < end)
	{
		// 右边找小,填到左边的坑
		while (begin < end && a[end] >= key)
		{
			--end;
		}

		a[hole] = a[end];
		hole = end;

		// 左边找大,填到右边的坑
		while (begin < end && a[begin] <= key)
		{
			++begin;
		}

		a[hole] = a[begin];
		hole = begin;
	}

	a[hole] = key;
	return hole;	
}

void QuickSort(int* a, int begin, int end)
{
	if (begin >= end)
		return;

	int keyi = PartSort2(a, begin, end);
	QuickSort(a, begin, keyi - 1);
	QuickSort(a, keyi + 1, end);
}

4.3 前后指针版本

在这里插入图片描述
cur遇到比key大的值,就++cur;
cur遇到比key小的值,就++prev,交换prev和cur位置的值
在这里插入图片描述
cur先走

在这里插入图片描述
当cur遇到比key小的值,在这里插入图片描述
先加加prev,再与cur交换。
在这里插入图片描述
然后cur继续往后走,又遇见比key小的
在这里插入图片描述
然后先加加prev,再与cur交换。
在这里插入图片描述
cur继续往后找小
在这里插入图片描述
cur比end大,就结束,然后将key与prev交换。
在这里插入图片描述

4.3.1 分析

先定义一下cur和prev,让int cur = prev + 1int prev = begin
当cur比key的值小时就继续走,否则就++prev,然后prev与cur交换。
就直接写一个循环就行,将加加放在条件里面。
在这里插入图片描述
当cur出去后,再将key与prev交换。

这里也是先写好单趟,然后调用就行。
在这里插入图片描述

举个例子看看:
在这里插入图片描述

4.3.2 前后指针版本代码实现

int PartSort3(int* a, int begin, int end)
{
	int keyi = begin;

	int prev = begin;
	int cur = prev + 1;
	while (cur <= end)
	{
		if (a[cur] < a[keyi] && ++prev != cur)
			Swap(&a[prev], &a[cur]);

		++cur;
	}

	Swap(&a[prev], &a[keyi]);
	keyi = prev;
	return keyi;
}

void QuickSort(int* a, int begin, int end)
{
	if (begin >= end)
		return;

	int keyi = PartSort3(a, begin, end);
	QuickSort(a, begin, keyi - 1);
	QuickSort(a, keyi + 1, end);

有问题请指出,大家一起进步吧!

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

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

相关文章

Windows搭建RTSP视频流服务(EasyDarWin服务器版)

文章目录 引言1、安装FFmpeg2、安装EasyDarWin3、实现本地\虚拟摄像头推流服务4、使用VLC或PotPlayer可视化播放器播放视频5、RTSP / RTMP系列文章 引言 RTSP和RTMP视频流的区别 RTSP &#xff08;Real-Time Streaming Protocol&#xff09;实时流媒体协议。 RTSP定义流格式&am…

Spring高手之路-Spring AOP

目录 什么是AOP Spring AOP有如下概念 补充&#xff1a; AOP是如何实现的 Spring AOP 是通过代理模式实现的。 Spring AOP默认使用标准的JDK动态代理进行AOP代理。 什么是AOP AOP(Aspect-Oriented Programming)&#xff0c;即面向切面编程&#xff0c;用人话说就是把公共的…

【小沐学Python】Python实现免费天气预报获取(OpenWeatherMap)

文章目录 1、简介1.1 工具简介1.2 费用1.3 注册1.4 申请key 2、接口说明2.1 One Call 3.02.2 Current Weather and Forecasts collection2.2.1 API 调用2.2.2 API 参数 2.3 Historical Weather collection2.4 Weather Maps collection2.5 Other weather APIs 3、接口测试3.1 例…

菜鸟网络Java实习一面面经

自我介绍&#xff0c;做过的项目 巴拉巴拉 你项目中用到redis&#xff0c;可以介绍一下为什么使用它吗&#xff1f; 基于内存操作&#xff0c;内存读写速度快。 支持多种数据类型&#xff0c;包括String、Hash、List、Set、ZSet等。 支持持久化。Redis支持RDB和AOF两种持久…

【Latex错误:】Package fontspec: The font “SIMLI“ cannot be found. LaTex [行 37,列1]

【Latex错误&#xff1a;】Package fontspec: The font "SIMLI" cannot be found. LaTex [行 37&#xff0c;列1] 解决方案 错误详情如下图所示&#xff1a; 最近使用latex写毕业论文&#xff0c;效率是快&#xff0c;但是出些一些错误就难得搞了&#xff0c;上面的…

python+django游戏分享论坛网站49c2c

本系统主要包括管理员和用户两个角色组成&#xff1b;主要包括首页、个人中心、用户管理、游戏类型管理、游戏文章管理、交流论坛、系统管理等功能的管理系统。 系统权限按管理员和用户两类涉及用户划分。 &#xff08;1&#xff09;管理员功能需求 管理员登陆后&#xff0c;主…

桶排序 BucketSort

桶排序 桶排序是将数组分散到有限的桶中&#xff0c;然后每个桶再分别排序&#xff0c;而每个桶的排序又可以使用其他排序方式进行排序&#xff0c;可以是桶排序也可以是其他排序。一句话就是: 划分多个范围相同的区间&#xff0c;每个子区间自排序最后合并。 桶的大小可以随…

计量经济学|学习笔记以及学习感悟

初级计量经济学着重于介绍基本的统计工具和经济模型&#xff0c;以帮助理解经济数据和经济现象之间的关系。它包括回归分析、假设检验和预测方法等内容。中级计量经济学则深入研究这些方法的理论基础和实际应用&#xff0c;包括更复杂的模型和技术&#xff0c;如面板数据分析、…

jwt 介绍

目录 1&#xff0c;jwt 的出现问题 2&#xff0c;jwt 介绍3&#xff0c;jwt 令牌的组成3.1&#xff0c;header3.2&#xff0c;payload3.3&#xff0c;signature 4&#xff0c;验证5&#xff0c;总结 身份验证相关内容&#xff1a; 浏览器 cookie 的原理&#xff08;详&#xff…

微服务实战系列之Dubbo(下)

前言 眼看着2023即将走远&#xff0c;心里想着似乎还有啥&#xff0c;需要再跟各位盆友叨叨。这不说曹操&#xff0c;曹操就来了。趁着上一篇Dubbo博文的余温尚在&#xff0c;博主兴匆匆地“赶制”了Dubbo的下集&#xff0c;以飨读者。 上一篇博主依然从Dubbo的内核出发&#…

Linux基础知识学习3

vim编辑器 其分为四种模式 1.普通(命令)模式 2.编辑模式 3.底栏模式 4.可视化模式 vim编辑器被称为编辑器之神&#xff0c;而Emacs更是神之编辑器 普通模式&#xff1a; 1.光标移动 ^ 移动到行首 w 跳到下一个单词的开头…

软件开发新手用哪个IDE比较好?软件开发最好的IDE都在这!

目录 IDES 的优点 最佳编程 IDE 列表 Java 开发的流行集成开发环境 JetBrains 的 IntelliJ IDEA NetBeans 适用于 C/ C、C# 编程语言的最佳 IDE Visual Studio 和 Visual Studio 代码 Eclipse PHP 开发的最佳 IDE PHPStorm Sublime Text Atom JavaScript 的顶级 I…

Windows10系统的音频不可用,使用疑难解答后提示【 一个或多个音频服务未运行】

一、问题描述 打开电脑&#xff0c;发现电脑右下角的音频图标显示为X&#xff08;即不可用&#xff0c;无法播放声音&#xff09;&#xff0c;使用音频自带的【声音问题疑难解答】&#xff08;选中音频图标&#xff0c;点击鼠标右键&#xff0c;然后选择“声音问题疑难解答(T)”…

procise纯PL流程点灯记录

procise纯PL流程点灯记录 一、概述 此篇记录使用procise工具构造JFMQL15T 纯PL工程&#xff0c;显示PL_LED闪烁&#xff1b; 硬件说明如下&#xff1a; 时钟引脚 Pl_CLK: U2 ,IO_L14P_T2_SRCC_34 PL_LED1 : E2, IO_L17P_T2_AD5P_35 PL_LED2: D6, IO_L2N_T0_AD8N_35 PL_LED3 :…

网易有道词典不能截屏翻译,不能联网解决办法

对应版本&#xff1a; win10系统&#xff0c;联想拯救者笔记本&#xff0c;网易有道词典8.10.2.0。 网易有道词典免费下载链接&#xff1a;https://download.csdn.net/download/qq_42755734/88684985 修改代理&#xff1a; youdao.com 0 取消勾选---不更新 效果&#xff1a…

CentOS 7 lvm 裸盘的扩容和缩容减盘 —— 筑梦之路

背景介绍 之前写过比较多的关于lvm的文章&#xff1a; CentOS 7 lvm 更换坏盘操作步骤小记 —— 筑梦之路_centos更换硬盘操作-CSDN博客 xfs ext4 结合lvm 扩容、缩容 —— 筑梦之路_ext4扩盘-CSDN博客 LVM逻辑卷元数据丢失恢复案例 —— 筑梦之路_pve lvm数据恢复-CSDN博客…

【MMdetection】MMdetection从入门到进阶

基础环境安装 步骤 0. 从官方网站下载并安装 Miniconda。 步骤 1. 创建并激活一个 conda 环境。 conda create --name openmmlab python3.8 -y conda activate openmmlab步骤 2. 基于 PyTorch 官方说明安装 PyTorch。 pip install torch2.0.1 torchvision0.15.2 torchaudio…

SpringBoot+拦截器(Interceptor)

记录一下SpringBoot的拦截器(Interceptor)使用 拦截器(Interceptor)是AOP面向切面编程的思想来实现的&#xff0c;对于只写代码的来说&#xff0c;具体如何实现不需要多关心&#xff0c;只需要关心如何去使用&#xff0c;会用在那些地方。 当http请求进入Springboot应用程序后…

UE蓝图 RPG动作游戏(一) day15

角色状态制作 制作角色动画混合空间 创建一个动混合空间 添加动作在混合空间 动画蓝图 创建一个动画蓝图 先使用混合空间进行移动&#xff0c;后续优化后再使用状态机 编写垂直水平速度逻辑初始化&#xff0c;获取到此动画的角色组件 获取Horizontal与Vertical的速度逻辑 …

股票价格预测 | Python实现Autoformer, FEDformer和PatchTST等模型用于股价预测

文章目录 效果一览文章概述环境描述源码设计效果一览 文章概述 Autoformer、FEDformer和PatchTST是一些用于时间序列预测,包括股价预测的模型。它们都是在Transformer模型的基础上进行了改进和扩展,以更好地适应时间序列数据的特点。 Autoformer:Autoformer是一种自适应Tran…