[数据结构]———交换排序

目录

1.交换排序

第一个定义了一个名为Swap的函数

 第二个三数取中

2.冒泡排序

代码解析

冒泡排序的特性总结:

3.快速排序

1. hoare版本

2. 挖坑法 

 代码解析

 3. 前后指针版本

 代码解析


1.交换排序


基本思想:所谓交换,就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置,交换排序的特点是:将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动。

首先我们先介绍并创建两个函数,后面要用

第一个定义了一个名为Swap的函数

实现了交换两个整数指针所指向的值

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

 第二个三数取中

定义了一个名为GetMidi的函数用于确定三个位置beginmidiend在数组a中的中间值索引,确定并返回中间值的索引

int GetMidi(int* a, int begin, int end)
{
	int midi = (begin + end) / 2;
	// begin midi end 三个数选中位数
	if (a[begin] < a[midi])
	{
		if (a[midi] < a[end])
			return midi;
		else if (a[begin] > a[end])
			return begin;
		else
			return end;
	}
	else // a[begin] > a[midi]
	{
		if (a[midi] > a[end])
			return midi;
		else if (a[begin] < a[end])
			return begin;
		else
			return end;
	}
}


2.冒泡排序

代码解析

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

冒泡排序的特性总结:


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

3.快速排序


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

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

// 假设按照升序对array数组中[left, right)区间中的元素进行排序
void QuickSort(int array[], int left, int right)
{
if(right - left <= 1)
return;
// 按照基准值对array数组的 [left, right)区间中的元素进行划分
int div = partion(array, left, right);
// 划分成功后以div为边界形成了左右两部分 [left, div) 和 [div+1, right)
// 递归排[left, div)
QuickSort(array, left, div);
// 递归排[div+1, right)
QuickSort(array, div+1, right);
}

上述为快速排序递归实现的主框架,发现与二叉树前序遍历规则非常像,同学们在写递归框架时可想想二叉树前序遍历规则即可快速写出来,后序只需分析如何按照基准值来对区间中数据进行划分的方式即可。
将区间按照基准值划分为左右两半部分的常见方式有:


1. hoare版本

在快速排序算法中,需要在找到左边比关键值大的元素和右边比关键值小的元素之后才进行元素交换,以确保左边的元素都比关键值小,右边的元素都比关键值大。但是在代码中目前的交换步骤存在问题,因为在while循环结束之后直接进行了一次元素交换,而应该是在找到左右指针位置后再进行交换。

int QuickSort1(int* a, int begin, int end)
{
	int midi = GetMidi(a, begin, end);
	Swap(&a[midi], &a[begin]);

	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]);

	return left;
}

2. 挖坑法 

 代码解析

  1. 挖坑法
    • 使用挖坑法的思想,即每次在处理完左右指针位置的元素后,将最初选择的“坑”填入正确的位置。
  2. 函数逻辑
    • 首先在数组中选择基准值(pivot)并与起始位置的元素交换,这里选择的基准值为a[begin]
    • 使用两个指针beginend分别指向数组的起始和末尾,开始移动指针以找到需要交换的元素。
    • begin小于end时,进行以下操作:
      • 从右侧开始,找到第一个比基准值小的元素,将其填入“坑”中,同时更新“坑”的位置和end指针的位置。
      • 从左侧开始,找到第一个比基准值大的元素,将其填入之前右侧留下的“坑”中,同时更新“坑”的位置和begin指针的位置。
    • 最后,将基准值填入最后的“坑”中,返回该“坑”的位置,用于分割左右子数组。
  3. 返回值
    • 函数返回的是基准值在排序后的位置,用于在递归调用中分割左右子数组。
//2.挖坑法
int QuickSort2(int* a, int begin, int end)
{
	int midi = GetMidi(a, begin, end);
	Swap(&a[midi], &a[begin]);

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

 

 3. 前后指针版本

 代码解析

将数组分成两个子数组,左边的子数组中的元素都小于等于中间元素,右边的子数组中的元素都大于等于中间元素,并返回中间元素的索引

int QuickSort3(int* a, int begin, int end)
{
	int midi = GetMidi(a, begin, end);
	Swap(&a[midi], &a[begin]);
	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;
}

 

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

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

相关文章

MyBatis-plus笔记——条件构造器和常用接口

wapper介绍 Wapper&#xff1a;条件构造抽象类 AbstractWapper&#xff1a;用于查询条件封装&#xff0c;生成 sql 的 where 条件 QueryWrapper&#xff1a;查询条件封装UpdateWrapper&#xff1a;Update 条件封装AbstractLambdaWrapper&#xff1a;使用Lambda语法 LambdaQuery…

五一假期Llama 3之魔改不完全攻略(Part 2)

2024年4月18日&#xff0c;Meta AI 正式宣布推出 Llama 3&#xff0c;这标志着开源大型语言模型&#xff08;LLM&#xff09;领域的又一重大进步。如同一颗重磅炸弹&#xff0c; Llama 3 以其卓越的性能和广泛的应用前景&#xff0c;预示着 AI 技术的新时代。 目前开源的是Lla…

Agent AI智能体:机器学习与自我优化的奇妙之旅

文章目录 &#x1f4d1;前言一、Agent AI智能体的基本概念二、Agent AI智能体的技术进步2.1 机器学习技术2.2 自适应技术2.3 分布式计算与云计算 三、Agent AI智能体的知识积累3.1 知识图谱3.2 迁移学习 四、Agent AI智能体的挑战与机遇4.1 挑战4.2 机遇 小结 &#x1f4d1;前言…

ASP.NET网络商店设计与实现

摘 要 本文首先系统地研究了开发电子商务网站的背景和意义&#xff0c;分析了当今B2C电子商务交易的网站特点和共性&#xff0c;从而得出设计本网站的思路和方法。接着介绍了实现系统开发的ASP.NET和IIS5.0环境&#xff0c;数据库用ACCESS实现。同时简要介绍了以上工具的功能…

手拉手springboot整合kafka

前期准备安装kafka 启动Kafka本地环境需Java 8以上 Kafka是一种高吞吐量的分布式发布订阅消息系统&#xff0c;它可以处理消费者在网站中的所有动作流数据。 Kafka启动方式有Zookeeper和Kraft&#xff0c;两种方式只能选择其中一种启动&#xff0c;不能同时使用。 Kafka下载…

状态模式

文章目录 1.UML类图2.状态基类3.状态实现类3.状态机管理类使用示例 1.UML类图 2.状态基类 public abstract class State {public string? Name { get; set; }public StateMachine? StateMachine {get; set;}public abstract void Exit();public abstract void Enter(); }3.…

Devops部署maven项目

这里讲下应用k8s集群devops持续集成部署maven项目的流程。 failed to verify certificate: x509: certificate signed by unknown authority 今天在执行kubectl get nodes的时候报的证书验证问题&#xff0c;看了一圈首次搭建k8s的都是高频出现的问题。 couldn’t get curren…

输入N,从1~N中挑出若干对数字,比如(a,b),(c,d)

题目: 输入N,从1~N中挑出若干对数字,比如(a,b),(c,d) 规定这个数对的value为两数之和,比如(a,b)的value为ab 现在从1~N中挑出若干个数对,他们满足: 每个数字只能被挑出一次 每个数对的value都不相等 每个数对的value都小于等于N 求:对于给定的N,能挑出这样的数对的最大个数max …

2024年Q1葡萄酒行业线上电商(京东天猫淘宝)销售排行榜

五一聚餐不可缺少饮品——葡萄酒。鲸参谋监测的线上电商平台&#xff08;某东&#xff09;Q1季度葡萄酒行业销售数据已揭晓&#xff01; 从鲸参谋的数据中&#xff0c;我们可以明显看到今年Q1季度在线上电商平台&#xff08;某东&#xff09;葡萄酒行业的销售情况呈现出积极的…

【C++】STL使用详解

文章目录 前言1. string类1.1 string类对象的常见构造1.2 string类对象的容量操作1.3 string类对象的访问及遍历操作1.4 string类对象的修改操作1.5 string类非成员函数 2. vector2.1 vector的介绍2.2 vector的使用2.3 vector的迭代器2.4 vector空间容量操作2.5 vector增删查改…

笨蛋学C++之 C++连接数据库

笨蛋学C 之 VS2019使用C连接数据库 创建数据库SQL语句VS2019选择空项目&#xff0c;点击下一步创建输入项目名称&#xff0c;点击创建创建成功点击新建项创建源文件因为mysql是64位&#xff0c;此时的c项目是86位&#xff0c;所以这里需要将项目修改为x64位点击项目 -> 0501…

基于Python的人脸识别系统设计与实现(论文+源码)_kaic

基于Python的人脸识别系统设计与实现 摘 要 随着人工智能的发展,人脸识别系统在我们的生活中越来越被广泛应用。人脸识别系统是指能够从数字图像或视频源中识别人的技术。人脸识别系统可以通过多种方法工作&#xff0c;但是&#xff0c;它们通常是通过将给定图像中的面部特征与…

基于Vue Router和element-ui的LayOut

一、展示 二、代码 app.vue <template><div id"app"><el-container style"border: 1px solid #eee; height: 100vh"><el-aside v-bind:width"asideWidth" style"background-color: rgb(48, 65, 86);"><…

基于ROS从零开始构建自主移动机器人:仿真和硬件

书籍&#xff1a;Build Autonomous Mobile Robot from Scratch using ROS&#xff1a;Simulation and Hardware 作者&#xff1a;Rajesh Subramanian 出版&#xff1a;Apress 书籍下载-《基于ROS从零开始构建自主移动机器人&#xff1a;仿真和硬件》您将开始理解自主机器人发…

ip地址与硬件地址的区别是什么

在数字世界的浩瀚海洋中&#xff0c;每一台联网的设备都需要一个独特的标识来确保信息的准确传输。这些标识&#xff0c;我们通常称之为IP地址和硬件地址。虽然它们都是用来识别网络设备的&#xff0c;但各自扮演的角色和所处的层次却大相径庭。虎观代理小二将带您深入了解IP地…

karpathy make more -- 4

1 Introduction 这个部分要完成一个网络的模块化&#xff0c;然后实现一个新的网络结构。 2 使用torch的模块化功能 2.1 模块化 将输入的字符长度变成8&#xff0c;并将之前的代码模块化 # Near copy paste of the layers we have developed in Part 3# -----------------…

爬虫学习:基本网络请求库的使用

目录 一、urllib网络库 1.urlopen()方法 2.request方法 二、requests网络请求库 1.主要方法 2.requests.get()和requests.post() 一、urllib网络库 1.urlopen()方法 语法格式&#xff1a; urlopen(url,data,timeout,cafile,capath,context) # url:地址 # data:要提交的数据…

[华为OD]C卷 机场航班调度 ,XX市机场停放了多架飞机,每架飞机都有自己的航班号100

题目&#xff1a; XX市机场停放了多架飞机&#xff0c;每架飞机都有自己的航班号CA3385, CZ6678, SC6508 等&#xff0c;航班号的前2个大写字母&#xff08;或数字&#xff09;代表航空公司的缩写&#xff0c;后面4个数字代表航班信息。 但是XX市机场只有一条起飞用跑道&am…

uniapp源码+计划任务 台股平台源码 新股申购 分类后台控制

台股平台源码集成了新股申购与折扣申购功能&#xff0c;结合了计划任务和UniApp源码&#xff0c;为用户提供了一个全面的股票交易解决方案。 经过初步测试&#xff0c;系统可正常运行。测试时没有配置计划任务和WebSocket 。有兴趣的自行研究。 本系统基于PHP 7.3版本开发&am…

【记录】Springboot项目集成docker实现一键部署

公司管理平台完成后&#xff0c;为了方便其他不懂开发的同事部署和测试&#xff0c;集成docker进行一键部署&#xff0c;也为后面自动化部署做准备。本文做个简单记录。 1、安装docker yum install https://download.docker.com/linux/fedora/30/x86_64/stable/Packages/cont…
最新文章