【hoare基础版】快速排序算法(1)

目录

交换排序

QuickSort快速排序

Hoare整体思路

图解分析  ​

Hoare版本代码

总代码

时间复杂度


交换排序

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

QuickSort快速排序

快速排序:是Hoare于1962年提出的一种二叉树结构的交换排序方法。我们今天学习的就是基于Hoare思想的一种排序方式。

单趟基本思想(选取分界线位置keyi):

  • 任取待排序元素序列中的某元素(最左边/最右边的数)作为基准值a[keyi]
  • 按照该排序码将待排序集合分割成两子序列
  • 左子序列中所有元素均小于基准值
  • 右子序列中所有元素均大于基准值

整体基本思想:

  • 然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止。

简单来说,整体思路是比较简单的,单趟基本思路有3中方式去实现:

  • hoare版本1
  • 挖坑版本2
  • 前后指针版3
//有n个数----[0 , n-1]
//假设按照升序对array数组中[begin, end]区间中的元素进行排序
                                  0        n-1
void QuickSort(int array[], int begin, int end)
{
    //区间只有一个值/没有值(区间)返回
	if (begin >= end)
		return;

	// 按照keyi基准值对array数组的 [begin, end]区间中的元素进行划分
	// 有三种方式去找到keyi
    //PartSort1   PartSort2    PartSort3
    int keyi = PartSort1/2/3(array, begin, end);

	// 划分成功后以div为边界形成了左中右三部分
    //[begin, keyi-1] keyi [keyi+1, end)
 
    //keyi的位置的值 已经排好了
    
	// 递归排[begin, keyi-1]
	QuickSort(array, begin, keyi - 1);

	// 递归排[keyi+1, right]
	QuickSort(array, keyi + 1, end);
}

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

Hoare整体思路

单趟基本思想(选取分界线位置keyi):

  • 任取待排序元素序列中的某元素(最左边/最右边的数)作为基准值a[keyi]
  • 按照该排序码将待排序集合分割成两子序列
  • 左子序列中所有元素均小于基准值
  • 右子序列中所有元素均大于基准值
  • 目的:让keyi对应位置的值排到该排到的位置

    值的设置

  • 区间是[begin,end] (注意是下标)
  • 选取关键字的下标keyi a[keyi]=key

  • 设置两个下标用来值得比较:left right


    循环放值

  • left所对应的值小于<keyi所对应的值,符合要求,过掉

  • left所对应的值大于>keyi所对应的值,不符合要求,停下

  • right所对应的值大于>keyi所对应的值,符合要求,过掉

  • right所对应的值小于<keyi所对应的值,不符合要求,停下

  • 循环之后left right找到各自符合的值,交换即可

  • 把比a[keyi]小的值放到左边,比a[keyi]大的值放到右边


    相遇中线

  • left和right相遇,停止循环

  • 相遇的位置,即使中线位置

  • a[keyi]交换即可,则a[keyi]放到该放到的位置,a[keyi]已经排好了

整体基本思想:

  • 然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止。
  • 返回条件
  1. 递归到只有一个元素的区间
  2. 没有元素的区间。

重点突破:

  • left和right相遇的位置对应的数值总是比keyi所对应的值小
  • 相遇的三种情况分析
  • 选key值三种方式
  1. 直接选取最左边/右边
  2. 选取序列中的随机值key,和最左边/最右边的交换
  3. 三数取中法选key,和最左边/最右边的交换

易错点突破:

  • 比较起始位置从begin // begin+1 (顺序结构)
  • 相遇点的处理(错位)
  • 等于=的问题
  • 局部变量的问题

图解分析  

Hoare版本代码

                      //     0        n-1
int PartSort1(int* a, int begin, int end)//返回分割线
{
	int left = begin;
	int 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[right], &a[left]);
	}
	Swap(&a[left], &a[keyi]);
	keyi = left;
	return keyi;
	//分割 [begin,keyi-1] keyi [keyi+1,end]
}

总代码

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

void QuickSort(int* a, int begin,int end)
{
	if (begin >= end)//只有1个元素 没有区间
	{
		return;
	}
	int keyi = PartSort1(a, begin, end);
	QuickSort(a, begin, keyi - 1);
	QuickSort(a, keyi + 1, end);
}
                      //     0        n-1
int PartSort1(int* a, int begin, int end)//返回分割线
{
	int left = begin;
	int 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[right], &a[left]);
	}
	Swap(&a[left], &a[keyi]);
	keyi = left;
	return keyi;
	//分割 [begin,keyi-1] keyi [keyi+1,end]
}

时间复杂度

  • 最好情况:O(N*logN)
  • 最坏情况:O(N^2)
  • >>>>>>>>解决方法1:随机数选key
  • >>>>>>>>解决方法2:三数取中选key 

🙂感谢大家的阅读,若有错误和不足,欢迎指正。

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

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

相关文章

论文阅读:How Do Neural Networks See Depth in Single Images?

是由Technische Universiteit Delft(代尔夫特理工大学)发表于ICCV,2019。这篇文章的研究内容很有趣,没有关注如何提升深度网络的性能&#xff0c;而是关注单目深度估计的工作机理。 What they find&#xff1f; 所有的网络都忽略了物体的实际大小&#xff0c;而关注他们的垂直…

java调摄像头和人脸比对

我需要做一个功能&#xff0c;就是网站页面调用摄像头截图。现在由于要用java&#xff0c;就得研究用java怎么调用摄像头。顺带玩了一下人脸比对&#xff0c;资料有点少。 效果 采用javacv实现&#xff0c;先加Maven引用&#xff0c;后面把下载的包再独立引用不用Maven了 …

UI自动化测试篇 :webdriver+ant+jenkins自动化测试实践

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

OpenCV笔记2:鼠标事件实现绘制直线、矩阵、曲线

OpenCV 鼠标事件 创建窗口设置窗口大小鼠标事件监听 判断事件更新起始点和终点绘制线显示图片 打开背景图 """ 鼠标事件 down up move """ import cv2 import numpy as npWINNAME DRAWBOARD st_point (-1, -1) end_point (-1, -1)def draw…

【Unity】管道流动模拟Shader

【Unity】管道流动模拟Shader 抽象模拟管道介质流动的效果&#xff0c;使用顶点片元着色器。可以调整管线光泽&#xff0c;颜色&#xff0c;流动方向&#xff0c;透明度&#xff0c;流动体粗细&#xff0c;流动速度和横断面。 实现效果 Demo效果 Demo下载地址 管线光泽调整 …

proteus8.15图文安装教程

proteus8.15版本可以用STM32系列单片机来进行仿真设计&#xff0c;比7.8版本方便多了&#xff0c;有需要的朋友们可以在公众号后台回复 proteus8.15 获取软件包。 1、下载好软件包&#xff0c;解压如下&#xff0c;右键proteus8.15.sp1以管理员身份运行。 2、第一次安装&#x…

【蓝桥杯单片机入门记录】独立按键

目录 一、键盘、微动开关概述 二、按键工作原理 &#xff08;1&#xff09;按键构成 &#xff08;2&#xff09;&#xff08;蓝桥杯开发板&#xff09;独立按键电路图&#xff08;非实际&#xff0c;参考理解&#xff09; &#xff08;3&#xff09;独立按键工作原理 三、…

【J1939】一、概述,协议基础

文章目录 1. 背景2. 要点3. J1939帧细节3.1 协议数据单元(Protocol Data Unit,PDU)3.2 参数组编号(PGN)3.3 可疑参数编号(Suspect Parameter Number,SPN)参考1. 背景 J1939是一种用于商用车辆的通信协议,它定义了一套车辆电子控制单元之间进行数据通信的规范。J1939协议…

OpenAI 发布文生视频模型 Sora,普通人应该怎么做才能利益最大化?

原文链接&#xff1a; OpenAI 发布文生视频模型 Sora&#xff0c;普通人应该怎么做才能利益最大化&#xff1f; 自从 2022 年 11 月 30 日 ChatGPT 发布之后&#xff0c;每次 OpenAI 再发布新功能都跟过年一样&#xff0c;那叫一个热闹。 包括 GPT 4.0&#xff0c;GPT Store&…

滚雪球学Java(65):深入理解Java中的Map接口:实现原理剖析

咦咦咦&#xff0c;各位小可爱&#xff0c;我是你们的好伙伴——bug菌&#xff0c;今天又来给大家普及Java SE相关知识点了&#xff0c;别躲起来啊&#xff0c;听我讲干货还不快点赞&#xff0c;赞多了我就有动力讲得更嗨啦&#xff01;所以呀&#xff0c;养成先点赞后阅读的好…

2024年单服务器部署Mongodb三节点副本集自动化部署脚本

该脚本是为了方便自己学习和工作中部署服务器从而节省时间进行编写&#xff0c;目前能正常部署&#xff0c;创建集群&#xff0c;管理员用户&#xff0c;以及连接都没问题&#xff0c;但是没有开启验证&#xff0c;后续找时间补充。 完整的教程请参考一下我写的技术文章。 20…

十六进制数

1.做一个收电费程序&#xff0c;要求输入使用的电的度数&#xff08;整数&#xff09;以及电费单价&#xff08;实数&#xff09;&#xff0c;输出总的用电费用。 2.提示并输入一个小写字母数据&#xff0c;输出其对应的ASCII值&#xff0c;以及该小写字母对应的大写字母。 3.提…

软件测试工程师linux学习之系统层面相关命令总结

1 linux系统重启和关机的命令 重启命令&#xff1a;reboot 关机命令&#xff1a;shutdown 这两个命令一般很少用到&#xff0c;我们了解即可。 2 查看日志信息命令 什么是日志&#xff0c;日志就是一个一个普通的文本文件&#xff0c;文件里面记录的是软件运行过程中的信息…

市场复盘总结 20240221

仅用于记录当天的市场情况&#xff0c;用于统计交易策略的适用情况&#xff0c;以便程序回测 短线核心&#xff1a;不参与任何级别的调整&#xff0c;采用龙空龙模式 一支股票 10%的时候可以操作&#xff0c; 90%的时间适合空仓等待 二进三&#xff1a; 进级率中 33% 最常用…

搜维尔科技:用于运动科学的 OptiTrack,范围标记、步态捕捉!

OptiTrack 系统提供世界领先的测量精度和简单易用的工作流程&#xff0c;为研究人员和生物力学师的研究提供理想的 3D 跟踪数据。 对所有主要数字测力台、EMG 和模拟设备的本机即插即用支持为研究人员提供了在 Visual3D、MotionMonitor、MATLAB 和其他第三方生物力学软件包中进…

MySQL数据库基础(十二):子查询(三步走)

文章目录 子查询&#xff08;三步走&#xff09; 一、子查询&#xff08;嵌套查询&#xff09;的介绍 二、子查询的使用 三、总结 子查询&#xff08;三步走&#xff09; 一、子查询&#xff08;嵌套查询&#xff09;的介绍 在一个 select 语句中,嵌入了另外一个 select …

如何使用Coded UI Test对Webpage进行自动化测试

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

2024 年了,如何 0 基础开始学习 Vue ?

最近 5 个月&#xff0c;我都在忙着构建我的第一开源项目 HexoPress&#xff0c;这个项目是使用 Electron Vue 3 TypeScript 等技术实现的&#xff0c;一方面&#xff0c;我真的很需要一款合自己心意的博客编辑器&#xff0c;另一方面&#xff0c;我也是真心想学习 Electron …

App Inventor 2 Activity启动器技巧:如何查看并启动其他App

App包名和类名的查看 由 App Inventor 2 创建的应用要弄清包名和类名&#xff0c;可通过下载其应用程序的源代码&#xff0c;然后使用文件资源管理器或解压缩程序解压 .aia源文件&#xff08;文件的扩展名修改成.zip 或.rar&#xff0c;然后解压&#xff09;&#xff0c;在解压…

Redis面试题及核心知识点讲解

redis是单线程还是多线程&#xff1f; redis是单线程的&#xff0c;主要是指网络I/O线程。Redis的持久化&#xff0c;集群同步等操作&#xff0c;则由另外的线程来执行。 2 . redis是单线程&#xff0c;为什么处理这么快&#xff1f; Redis的大部分操作都是在内存中完成。单线…