排序算法-快速排序

1.快速排序(递归)

快速排序是 Hoare 1962 年提出的一种二叉树结构的交换排序方法,其基本思想为: 任取待排序元素序列中 的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右 子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止
void QuickSort(int* a, int begin, int end)
{
	if (begin >= end)
		return;

	int keyi = PartSort3(a, begin, end);
	//[begin,keyi-1]keyi[keyi+1,end]
	QuickSort(a, begin, keyi - 1);
	QuickSort(a, keyi + 1, end);
}
上述为快速排序递归实现的主框架,发现与二叉树前序遍历规则非常像,同学们在写递归框架时可想想二叉 树前序遍历规则即可快速写出来,后序只需分析如何按照基准值来对区间中数据进行划分的方式即可。
将区间按照基准值划分为左右两半部分的常见方式有:
1. hoare 版本
2. 挖坑法
3. 前后指针版本
我来给大家讲解一下前后指针版本,因为这个代码简洁,但是不太好理解。
首先创建一个变量keyi保存left的值keyi=left,然后创建后指针prev开始也是在left位置prev=left,前指针cur在prev前一个位置cur=prev+1,,然后写一个while循环,结束条件是cur>right,意味着cur越界了,进入循环首先判断一下a[cur]和a[keyi]的大小,如果a[cur]大则再判断++prev是否等于cur,如果等于则不用交换,cur++,如果两个条件都满足则交换a[prev]和a[cur],因为prev已经++,所以直接交换即可。循环结束之后再交换a[key]和a[prev].
cur的作用就是和prev拉开距离,然后将大于a[keyi]的值放到右边的部分,最后交换a[keyi]和a[prev],就完成了部分排序。
int PartSort(int* a, int left, int right)
{
	int keyi = left;
	int prev = left, cur = prev + 1;
	while (cur <= right)
	{
		if (a[cur] < a[keyi] && (++prev) != cur)
		{
			Swap(&a[prev], &a[cur]);
		}
		cur++;
	}
	Swap(&a[prev], &a[keyi]);
	return prev;
}
void QuickSort(int* a, int begin, int end)
{
	if (begin >= end)
		return;

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

2.快速排序优化

2.1三数取中

三数取中是取大小位于中间的值放到最左边,这样可以防止快排中最坏的情况出现O(n*2),也就是要排序的这一组数据接近有序或者就是有序的情况,那么使用了三数取中后这种最坏的情况就变成了最好的情况.

//三数取中
int GetMidi(int* a, int left, int right)
{
	int midi = (left + right) / 2;
	if (a[left] < a[midi])
	{
		if (a[midi] < a[right])
		{
			return midi;
		}
		else if (a[right] < a[left])
		{
			return left;
		}
		else
		{
			return right;
		}
	}
	else//a[left]>a[midi]
	{
		if (a[left] < a[right])
		{
			return left;
		}
		else if (a[midi] > a[right])
		{
			return midi;
		}
		else
		{
			return right;
		}
	}
}

2.2小区间优化 

当区间较小时可以使用插入排序来进行优化,因为插入排序最坏的情况就是要插入的数都比前面的数小,插入排序在小区间里面比较不错的一种排序算法,在快速排序里面使用插入排序可以提高很多的效率。

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

	if ((end - begin + 1) > 10)
	{
		int keyi = PartSort3(a, begin, end);
		//[begin,keyi-1]keyi[keyi+1,end]
		QuickSort(a, begin, keyi - 1);
		QuickSort(a, keyi + 1, end);
	}
	else
	{
		InsertSort(a+begin, end - begin + 1);
	}
}

 3.快速排序(非递归)

非递归的快速排序可以借助一个栈来实现,先入右边的值,再入左边的值,然后每次取值都是先取栈顶,也就是左边的值,然后再进行部分排序,直到返回的keyi-1=left,就代表着左边排序完成,右边返回的keyi+1=right,代表右边的部分排序完成。

void QuickSortNonR(int* a, int begin, int end)
{
	ST st;
	STInit(&st);
	STPush(&st, end);
	STPush(&st, begin);
	while (!STEmpty(&st))
	{
		int left = STTop(&st);
		STPop(&st);

		int right = STTop(&st);
		STPop(&st);

		int keyi = PartSort3(a, left, right);
		if (keyi + 1 < right)
		{
			STPush(&st, right);
			STPush(&st, keyi+1);
		}
		if (keyi - 1 > left)
		{
			STPush(&st, keyi-1);
			STPush(&st, left);
		}
	}
	STDestroy(&st);
}

今天的分享到这里就结束了,感谢大家的阅读! 

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

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

相关文章

Armv8/Armv9从入门到精通-课程介绍

通知&#xff0c;Arm二期&#xff0c;咱们也有大合集PDF了&#xff0c;共计1587页&#xff0c;还未完成&#xff0c;后续持续更新和优化中。为了方便大家阅读、探讨、做笔记&#xff0c;特意整了此合集PPT&#xff0c;为了增加标签目录&#xff0c;还特意开了福兮阅读器会员。 …

OkHttp: 拦截器和事件监听器

文章目录 1. 拦截器1. 拦截器链2. 实际案例1. 注册为应用拦截器2. 注册为网络拦截器 3. 如何选择用哪种拦截器1. 应用拦截器2. 网络层拦截器3. 重写请求4. 重写响应 4. 可用性 2. 事件监听器1. 请求的生命周期2. EventListener使用案例3. EventListener.Factory4. 调用失败的请…

【产品经理】产品专业化提升路径

产品专业化就是上山寻路&#xff0c;梳理一套作为产品经理的工作方法。本文作者从设计方法、三基座、专业强化、优秀产品拆解、零代码这五个方面&#xff0c;对产品经理的产品专业化进行了总结归纳&#xff0c;一起来看一下吧。 产品专业化就是上山寻路&#xff0c;梳理一套作为…

8 Buildroot 根文件系统构建

一、根文件系统简介 根文件系统一般也叫做 rootfs&#xff0c;这个是属于 Linux 内核的一部分。 根文件系统首先是一种文件系统&#xff0c;该文件系统不仅具有普通文件系统的存储数据文件的功能&#xff0c;但是相对于普通的文件系统&#xff0c;它的特殊之处在于&#xff0c;…

十六 动手学深度学习v2计算机视觉 ——样式迁移

文章目录 基于CNN的样式迁移 基于CNN的样式迁移 我们通过前向传播&#xff08;实线箭头方向&#xff09;计算风格迁移的损失函数&#xff0c;并通过反向传播&#xff08;虚线箭头方向&#xff09;迭代模型参数&#xff0c;即不断更新合成图像。 风格迁移常用的损失函数由3部分组…

源码角度简单介绍LinkedList

LinkedList是一种常见的数据结构&#xff0c;但是大多数开发者并不了解其底层实现原理&#xff0c;以至于存在很多误解&#xff0c;在这篇文章中&#xff0c;将带大家一块深入剖析LinkedList的源码&#xff0c;并为你揭露它们背后的真相。首先想几个问题&#xff0c;例如&#…

科技提升安全,基于YOLOv7【tiny/yolov7/yolov7x】开发构建商超扶梯场景下行人安全行为姿态检测识别系统

在商超等人流量较为密集的场景下经常会报道出现一些行人在扶梯上摔倒、受伤等问题&#xff0c;随着AI技术的快速发展与不断普及&#xff0c;越来越多的商超、地铁等场景开始加装专用的安全检测预警系统&#xff0c;核心工作原理即使AI模型与摄像头图像视频流的实时计算&#xf…

头歌——HBase 开发:使用Java操作HBase

第1关&#xff1a;创建表 题目 任务描述 本关任务&#xff1a;使用Java代码在HBase中创建表。 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a;1.如何使用Java连接HBase数据库&#xff0c;2.如何使用Java代码在HBase中创建表。 如何使用Java连接HBase数据库…

网神 SecGate3600 authManageSet.cgi信息泄露漏洞复现

漏洞概述 网神SecGate 3600 authManageSet.cgi 接口存在敏感信息泄露漏洞&#xff0c;未授权得攻击者可以通过此漏洞获取控制台管理员用户名密码等凭据&#xff0c;可登录控制整个后台&#xff0c;使系统处于极不安全的状态 复现环境 FOFA&#xff1a;body"sec_gate_im…

python冒泡排序

冒泡排序思想 大家可以把我们所有的需要排列的数字想象成一个水中的气泡&#xff0c;大的数字想象成大气泡&#xff0c;小的数字想象成小气泡。 其实冒泡排序就是比较相邻的两个数字的大小&#xff0c;然后大的数字排在小的数字的后面&#xff0c;我们依次比较&#xff0c;第一…

“百里挑一”AI原生应用亮相,百度智能云千帆AI加速器首个Demo Day来了!

作者简介&#xff1a; 辭七七&#xff0c;目前大二&#xff0c;正在学习C/C&#xff0c;Java&#xff0c;Python等 作者主页&#xff1a; 七七的个人主页 文章收录专栏&#xff1a; 七七的闲谈 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01;&#x1f496;&#x1f…

Android : BottomNavigation底部导航_简单应用

示例图&#xff1a; 1.先创建底部导航需要的图片 res → New → Vector Asset 创建三个矢量图 图片1 baseline_home.xml <vector android:height"24dp" android:tint"#000000"android:viewportHeight"24" android:viewportWidth"24…

MySQL BinLog 数据还原恢复

博文目录 文章目录 查看状态查看 binlog 开关及存储路径查看 binlog 配置 如 存储格式 binlog_format查看当前还存在的日志查看当前正在使用的日志 切换日志确定日志确定日志文件日志格式改写日志简要说明确定日志位置以事件为单位查看日志分析日志 还原数据 查看状态 查看 b…

循环神经网络-1

目录 1 数据集构建 1.1 数据集的构建函数 1.2 加载数据并进行数据划分 1.3 构造Dataset类 2 模型构建 2.1 嵌入层 2.2 SRN层 2.3 线性层 2.4 模型汇总 3 模型训练 3.1 训练指定长度的数字预测模型 3.2 多组训练 3.3 损失曲线展示 4 模型评价 总结 参考文献 循环神经网络&…

记录一下如何使用python生成二维码 并简单练习命令行参数供初学者参考

主代码main.py 后面是演示效果图&#xff1a; import argparse import sysimport qrcode import os qr qrcode.QRCode(version1,error_correctionqrcode.constants.ERROR_CORRECT_L,box_size10,border4, ) fileList[] fileName[]parserargparse.ArgumentParser(description生…

Uncaught ReferenceError: jQuery is not defined解决方法

当我在写java的Maven项目时&#xff0c;出现了这样的一个报错信息&#xff1a; 我一直找代码&#xff0c;抓包&#xff0c;调试&#xff0c;比对代码 jQuery未定义就是指JS的导包没有导进来&#xff01;&#xff01;&#xff01;&#xff01; 导进来就运行正常啦

Docker部署Nacos集群并用nginx反向代理负载均衡

首先找到Nacos官网给的Github仓库&#xff0c;里面有docker compose可以快速启动Nacos集群。 文章目录 一. 脚本概况二. 自定义修改1. example/cluster-hostname.yaml2. example/.env3. env/mysql.env4. env/nacos-hostname.env 三、运行四、nginx反向代理&#xff0c;负载均衡…

二、SpringFramework 介绍

2.1 Spring 和 SpringFramework概念 https://spring.io/projects 广义的 Spring&#xff1a;Spring 技术栈&#xff08;全家桶&#xff09; 广义上的 Spring 泛指以 Spring Framework 为基础的 Spring 技术栈。 经过十多年的发展&#xff0c;Spring 已经不再是一个单纯的应…

OpenHarmony 如何去除系统锁屏应用

前言 OpenHarmony源码版本&#xff1a;4.0release / 3.2 release 开发板&#xff1a;DAYU / rk3568 一、3.2版本去除锁屏应用 在源码根目录下&#xff1a;productdefine/common/inherit/rich.json 中删除screenlock_mgr组件的编译配置&#xff0c;在rich.json文件中搜索th…

保姆级:Windows Server 2012上安装.NET Framework 3.5

目录 一.问题所在无法在安装SQL server2008&#xff08;2012&#xff09; 1.无法安装一下功能 .NET Framework 3.5 二.解决措施 1、打开服务器管理器 2、添加角色和功能 3、选择安装功能 4、指定备用源路径 5、配置本地文件路径 一.问题所在无法在安装SQL server2008&…