数据结构——快速排序

基本思想:


快速排序是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版本

 

 

 

 

代码实现: 

void Swap(int* p1, int* p2)
{int temp = 0;temp = *p1;*p1 = *p2;*p2 = temp;
}
//hoare
//[left,right]
int PartSort(int* a, int left, int right)
{int keyi = left;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[keyi], &a[left]);return left;
}
void QuickSort(int* a, int begin, int end)
{if (begin >= end){return;}int keyi = PartSort(a, begin, end);QuickSort(a, begin, keyi - 1);QuickSort(a, keyi + 1, end);
}

这时候有人会问了:“为什么left的起点是keyi的位置?” 

这时候我们就得考虑我们的极端场景了。

假如我们的key是0,left的起点在key的后面

 

 

那么我们的right始终找不到比key小的,最后和left相遇了。

 那么最终排出来的顺序是错误的,1怎么可能比0小?

注意事项: 

2.挖坑法 

Hoare大佬的方法很好,奠定了我们快排的基础思想,但是,里面的坑实在是很多,稍有不慎算法就容易出错,后人因此提出了疑问并且继续优化了快速排序的代码,例如挖坑法。

首先将我们的key的值存放起来,然后讲key值所在的位置挖空。

挖坑法的单趟排序跟Hoare版的可能大差不差,但是挖坑法会相比于Hoare版本更好理解。 

代码实现:

//挖坑法
// [left, right]
int PartSort(int* a, int left, int right)
{int key = a[left];int hole = left;while (left < right){// 右边找小while (left < right && a[right] >= key){right--;}a[hole] = a[right];hole = right;// 左边找大while (left < right && a[left] <= key){left++;}a[hole] = a[left];hole = left;}a[hole] = key;return hole;
}
void QuickSort(int* a, int begin, int end)
{if (begin >= end){return;}int keyi = PartSort(a, begin, end);QuickSort(a, begin, keyi - 1);QuickSort(a, keyi + 1, end);
}

 

3.前后针法

 

 

代码实现: 

// 前后指针法
// [left, right]
int PartSort(int* a, int left, int right)
{int prev = left;int cur = left + 1;int keyi = left;while (cur <= right){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 = PartSort(a, begin, end);QuickSort(a, begin, keyi - 1);QuickSort(a, keyi + 1, end);
}

快速排序的特性总结:


1. 快速排序整体的综合性能和使用场景都是比较好的,所以才敢叫快速排序
2. 时间复杂度:O(N*logN)

 

3. 空间复杂度:O(logN)
4. 稳定性:不稳定

PS:大部分语言自带的库函数sort都是以快速排序为底层,快速排序虽然好但是在某些极端场景下不如插入排序,所以还是得分析需求再使用合理的排序,以免增加时间复杂度和空间复杂度。

PS:看到这里了,码字不易,给个一键三连鼓励一下吧!有不足或者错误之处欢迎在评论区指出!  

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

无人机+远程控制:卫星通信技术详解

无人机与远程控制技术的结合&#xff0c;为现代科技应用带来了广阔的前景。其中&#xff0c;卫星通信技术作为无人机远程控制的关键技术之一&#xff0c;发挥着至关重要的作用。以下是无人机远程控制中卫星通信技术的详细解析&#xff1a; 一、卫星通信技术的概述 卫星通信技术…

设施农业(大棚种植)远程监控系统设计 STM32+51单片机 含pcb 上下位机源码 原理图

目录 摘要 1. 引言 2. 系统方案 3. 系统硬件设计 4. 系统软件设计 5. 系统创新 6. 评测与结论 7、实物图 8、原理图 ​9、程序 10、资料内容 资料下载地址&#xff1a;设施农业(大棚种植)远程监控系统设计 STM3251单片机 含pcb 上下位机源码 原理图 论文 摘要 …

交互验证和人机识别对抗升级,AIGC如何应用在验证安全?保证用户体验才是王道

交互验证和人机识别对抗再升级&#xff0c;滑动拼图、文字点选、语义空间和人工智能的对抗&#xff0c;俗话说&#xff0c;道高一尺&#xff0c;魔高一丈&#xff0c; 图形验证可以挑战人工智能吗&#xff1f; AIGC如何应用在身份验证业务 &#xff1f; 1 交互验证被破解现状 …

Oracle SQL优化案例-查询Null值走索引

网友发来一个SQL&#xff0c;说他们公司的一个SQL要优化帮忙看一下&#xff0c;执行计划如下&#xff1a; -------------------------------------SELECT * FROM (SELECT * FROM TXS C WHERE C.A ISNULL OR C.A ORDER BY ID_TXS DESC) WHERE ROWNUM<100​---------------…

【全开源】Java知识付费教育付费资源付费平台公众号小程序源码

特色功能&#xff1a; 多样化的内容呈现&#xff1a;资源付费平台小程序支持图文、音视频、直播等多种形式的内容呈现&#xff0c;为用户提供了丰富的学习体验。直播课程&#xff1a;专家或讲师可以通过小程序进行在线授课&#xff0c;与用户实时互动&#xff0c;增强了学习的…

设计模式-结构型-桥接模式-Bridge

矩阵类 public class Matrix {private String fileName;public Matrix(String fileName) {this.fileName fileName;}public String getFileName() {return fileName;} } 图片抽象类 public abstract class Image {protected ImageImp imp;public void setImp(ImageImp imp)…

如何使用Tushare+ Backtrader进行股票量化策略回测

数量技术宅团队在CSDN学院推出了量化投资系列课程 欢迎有兴趣系统学习量化投资的同学&#xff0c;点击下方链接报名&#xff1a; 量化投资速成营&#xff08;入门课程&#xff09; Python股票量化投资 Python期货量化投资 Python数字货币量化投资 C语言CTP期货交易系统开…

IT服务台的优势

我们谈谈IT服务台的一些好处&#xff0c;以更好地了解其重要性。IT 服务台为所有利益相关者&#xff08;技术人员和最终用户&#xff09;提供服务带来了效率。例如&#xff0c;三层 IT 服务台可以在第 0 层拥有自助服务门户&#xff0c;在第 1、2 和 3 层拥有技术人员&#xff…

SpringAMQP Work Queue 工作队列

消息模型: 代码模拟: 相较于之前的基础队列&#xff0c;该队列新增了消费者 不再是一个&#xff0c;所以我们通过代码模拟出两个consumer消费者。在原来的消费者类里写两个方法 其中消费者1效率高 消费者2效率低 RabbitListener(queues "simple.queue")public voi…

二维数组 和 变长数组

在上一期的内容中&#xff0c;为诸君讲解到了一维数组&#xff0c;在一维数组的基础上&#xff0c;C语言中还有着多维数组&#xff0c;其中&#xff0c;比较典型且运用较为广泛的就是我们今天的主角——二维数组 一 . 二维数组的概念 我们把单个或者多个元素组成的数组定义为一…

React 第三十一章 前端框架的分类

现代前端框架&#xff0c;有一个非常重要的特点&#xff0c;那就是基于状态的声明式渲染。如果要概括的话&#xff0c;可以使用一个公式&#xff1a; UI f&#xff08;state&#xff09; state&#xff1a;当前视图的一个状态f&#xff1a;框架内部的一个运行机制UI&#xff1…

LNMP环境部署WordPress——使用源码包安装方式部署环境

目录 一.前提准备 二.源码安装Mysql 1.MySQL类型 2.MySQL 版本说明 3.MySQL 安装方式 3.1 yum 安装 3.2 编译安装 3.3 二进制安装 3.4 rpm 安装 4. 编译安装MySQL5.7 4.1 清理安装环境 4.2 创建mysql用户 4.3 从官网下载tar包 4.4 安装编译工具 4.5 解压 4.6 …