快速排序的三种分区方法(整理)
快排的三种分区Partition方法
之前在课程上对于快速排序的认知还不够深入,虽然知道大概是每一次都把小于主元以及大于主元的元素分别排在主元的两侧,之后不断的递归缩小范围达到整体有序,但是甚至到正式学习之前都没有办法徒手写出快速排序。这里稍微整理一下。
蓝桥杯备战资料《算法之美》 Chapter3——查找与排序(下)
这里一共提供了三种的进行分区的方法,就是把小于主元的元素以及大于主元的元素进行分区。
1. 单向扫描
主元(X)+左指针(p1)+右指针(p2)
从左往右,若p1所指元素 <= X,则p1右移;
若p1所指元素 > X,则p1与p2的元素交换,p2左移,p1不动。
边界:当p1 > p2 时,p2左边的元素均 <= X,把X和p2所指元素交换。
/*把 arr 数组的 begin —— end 区间内进行分区*/
int partition(int *arr, int begin, int end){int mid = arr[begin]; // mid是主元int scan = begin+1; // scan为左指针int bigger = end; // bigger为右指针while(scan <= bigger){ // 当左右指针交错时退出循环if(arr[scan] <= mid){scan++; // 如果小于等于mid,则左指针++}else{swap(arr[scan], arr[bigger]); // 否则左右指针内容交换bigger--; // 右指针--}}swap(arr[begin], arr[bigger]); // 最后把主元与右指针的内容交换return bigger;
}void quickSort(int *arr, int begin, int end){if(end > begin){int pos = partition(arr, begin, end);quickSort(arr, begin, pos-1);quickSort(arr, pos+1, end);}
}
2. 双向扫描
主元(X)+左指针(p1)+右指针(p2)
先从左往右,p1移到第一个 > X 的元素;
再从右往左,p2移到第一个 <= X 的元素;
p1和p2的元素进行交换,重复以上过程直至p1与p2交错,进行交换。
/*把 arr 数组的 begin —— end 区间内进行分区*/
int partition(int *arr, int begin, int end){int mid = arr[begin]; // mid是主元int left = begin+1; // left是左指针int right = end; // right是右指针while(left <= right){ // 当左右指针交错时推出循环while(left <= right && arr[left] <= mid) left++; // 一直转移到第一个大于主元的元素while(left <= right && arr[right] > mid)right--; // 一直转移到第一个小于等于主元的元素if(left < right){ // 如果满足交换条件则交换左右元素swap(arr[left], arr[right]);}}swap(arr[begin], arr[right]); // 最后把主元与右指针的元素交换return right;
}void quickSort(int *arr, int begin, int end){if(end > begin){int pos = partition(arr, begin, end);quickSort(arr, begin, pos-1);quickSort(arr, pos+1, end);}
}
3. 三分法
主元(X)+左指针(p1)+右指针(p2)+“等于”指针(e)
从左往右,若p1所指元素 < X,则p1与e的元素进行交换,均右移;
若p1所指元素 = X,则p1右移;
若p1所指元素 > X,则p1与p2的元素交换,p2左移,p1不动。
边界:当p1 > p2时,e左移,X与e的元素交换。
(保证分区后是如下的形式)
/*把 arr 数组的 begin —— end 区间内进行分区
* 其中pos1用来保存“等于”区间的左边界,pos2用来保存“等于”区间的右边界*/
void partition(int *arr, int begin, int end, int &pos1, int &pos2){int mid = arr[begin]; // mid是主元int left = begin+1; // left是左指针int equal = left; // equal是“等于”指针int right = end; // right是右指针while(left <= right){ // 当左右指针交错时退出循环if(arr[left] == mid){ left++; // 若等于主元,则左指针++}else if(arr[left] < mid){ // 若小于主元swap(arr[equal], arr[left]); // 将“等于”指针与左指针的元素交换equal++; // “等于”指针++left++; // 左指针++}else{ // 若大于主元swap(arr[left], arr[right]); // 将左指针与右指针的元素交换right--; // 右指针--}}swap(arr[begin], arr[--equal]); // 最后将主元与“等于”指针的前一个元素交换pos1 = equal; // pos1为“等于”区间的左边界pos2 = right; // pos2为“等于”区间的右边界
}void quickSort(int *arr, int begin, int end){if(end > begin){int pos1;int pos2;partition(arr, begin, end, pos1, pos2);quickSort(arr, begin, pos1-1);quickSort(arr, pos2+1, end);}
}
快速排序的三种分区方法(整理)相关推荐
- 快速排序的三种实现以及应用场景
好了,废话不多说,直接上干货. 1.快速排序的概念: 快速排序(Quicksort)是对冒泡排序的一种改进. 快速排序由C. A. R. Horno在1962年提出.它的基本思想是:通过一趟排序将要排 ...
- 快速排序的三种实现方法
文章目录 1.快速排序的思想 2.基本实现 2.1第一种排序 2.2第二种排序 2.3第三种排序(挖坑法) 2.4代码测试 3.代码优化 4.快速排序小结 1.快速排序的思想 快速排序的过程可以分为以 ...
- 快速排序的三种方式以及快排的优化
一.快速排序的基本思想 关于快速排序,它的基本思想就是选取一个基准,一趟排序确定两个区间,一个区间全部比基准值小,另一个区间全部比基准值大,接着再选取一个基准值来进行排序,以此类推,最后得到一个有序的 ...
- 【算法】基于hoare快速排序的三种思想和非递归,基准值选取优化【快速排序的深度剖析-超级详细的注释和解释】你真的完全学会快速排序了吗?
文章目录 前言 什么是快速排序 快速排序的递归实现 快速排序的非递归实现 单趟排序详解 hoare思想 挖坑法 前后指针法 快速排序的优化 三数取中 小区间优化 快速排序整体代码 尾声 前言 先赞后看 ...
- 【c语言】快速排序的三种实现以及优化细节
目录 前言 一.hoare版本 1.思想 2.代码 二.挖坑版本 1.思想 2.代码 三.前后指针版本 1.思想 2.代码 四.分治思想: 五.两种优化 1.三数取中 2.小区间优化 六.非递归实现快 ...
- 快速排序(三种方法实现)
文章目录 1. 快速排序 <1>hoare法(左右指针法) <2>挖坑法 <3>前后指针法 <4>快速排序优化 <5>非递归实现 2.特性 ...
- C语言实现快速排序(三种)
第一种: #include<stdio.h>void Swap(int*a,int*b) {int tmp=*a;*a=*b;*b=tmp; }int PartSort1(int* a, ...
- VC++复制构造函数使用的三种情况—整理范磊VC++
1 上面不执行复制构造函数,17行将10000赋值给a:首先是进行类型转换转化为类(等价18行),然后调用构造函数创建一个临时对象, 并将该临时对象赋给a. 2. 对func函数: 接收的实参是主函数 ...
- 关于快速排序的三种划分元素的方法
思路和伪代码如下:需要的小伙伴们自己实现 /***** 分治思想:划分子问题再合并* 快排的重点是划分,归并的重点是合并* 快速排序:1,分解,解决,合并* 一遍单向扫描法:* 定主元,两个指针,一个 ...
最新文章
- 跨语言平台的RSA加密、解密、签名、验证算法的实现
- php安全配置总结,php安全配置详细说明(1/2)_PHP教程
- 最长公共子序列(C语言)
- 4个关于中台最常见的误区,用最通俗的话给你一次解释清楚
- [deviceone开发]-大家比较关注的应用内部升级
- 第5课 混合编程和芯片手册阅读
- java开发简历专业技能怎么写,附赠复习资料
- Object-C 介绍
- 项目部整套管理制度范本,50项都全了
- 【分享】使用快递鸟接入圆通电子面单详解
- 鼠标键盘的使用:用左ALT+左SHIFT+NUM LOCK即可启动或关闭键盘的鼠标键
- 应聘客户端主程需做哪些准备
- linux 中什么是进程号,Linux中脚本进程号由什么决定?
- 全球首个CTLA-4抑制剂逸沃在中国上市;全球首个原发性轻链型淀粉样变治疗药物兆珂速在华获批 | 医药健闻...
- 配置OpenLDAP使用TLS通信
- 输入一串只有由1-9对应数字的拼音输出对应的数字如输入为yiersan输出为:123
- npm run build 打包报错primordials is not defined的解决方法
- Python中str和repr的区别
- 文件上传与下载----上传
- Flask 上传自定义头像