排序算法之——三路快排分析
引言
在快速排序分析中我们探讨了经典快排的实现,且进行了一些小优化。
但是若序列中包含大量重复的元素,这种情况下,快排的性能就不那么理想了。
下面开始学习三路快排的思想吧。
思路
将数组分为三部分,分别对应于小于、等于和大于哨兵元素v
的子序列。
切分方法为从左到右遍历(扫描)数组一次,维护一个指针lt
使得a[left..lt-1]
中的元素都小于v
,一个指针gt
使得
a[gt+1..right]
中的元素都大于v
,一个指针i
使得a[lt..i-1]
中的元素都等于v
,而a[i..gt]
中的元素是还未扫描的。
一开始令i = left + 1
,对a[i]
与v
进行比较,根据比较情况作出不同的处理:
a[i]
小于v
,将a[lt]
和a[i]
交换,将lt
和i
加1;a[i]
大于v
,将a[gt]
和a[i]
交换,将gt
减1;a[i]
等于v
,将i
加1
以上操作会不断缩小gt - i
的值,直到i > gt
扫描结束。这时就成了上图切分后的情况。
假定元素数据如上图。
先让这三个指针就位。我们选取的哨兵元素v
为6。
a[i]=3
小于6,交换a[lt]
和a[i]
:6和3,lt
和i
指针后移。
a[i]=8
大于6,交换a[gt]
和a[i]
:7和8,gt
指针前移。
a[i]=7
大于6,交换a[gt]
和a[i]
:1和7,gt
指针前移。
a[i]=1
小于6,交换a[lt]
和a[i]
:6和1,lt
和i
指针后移。
a[i]=2
小于6,交换a[lt]
和a[i]
:6和2,lt
和i
指针后移。
a[i]=1
小于6,交换a[lt]
和a[i]
:6和1,lt
和i
指针后移。
a[i]=6
等于6,i
指针后移。直到a[i]=5
,交换6和5,lt
和i
指针后移。
i
继续后移,然后不满足i <= gt
的条件啦,跳出循环~
数组就被分为三部分,分别对应于小于、等于和大约哨兵元素v
的子序列。
一次切分就完毕了,接下来只要对小于和大于v
的部分进行同样的切分即可。
代码
private static <E extends Comparable<? super E>> void quick3Way(E[] a) {shuffle(a);quick3Way(a, 0, a.length - 1);
}/*** @param a* @param left* @param right* @param <E>*/
private static <E extends Comparable<? super E>> void quick3Way(E[] a, int left, int right) {if (right <= left) {return;}int lt = left, i = left + 1, gt = right;E v = a[left];//当 i > gt时跳出循环while (i <= gt) {int cmp = a[i].compareTo(v);//这里有个坑,注意和普通快排算法不一样,a[left]的元素是会发生变化的,因此需要用临时变量v缓存起来if (cmp < 0) {//a[i]小于v,将a[lt]和a[i]交换,将lt和i加1;swap(a, lt++, i++);} else if (cmp > 0) {//a[i]大于v,将a[gt]和a[i]交换,将gt减1;swap(a, gt--, i);} else {//a[i]等于v,将i加1i++;}}quick3Way(a, left, lt - 1);quick3Way(a, gt + 1, right);
}
排序算法之——三路快排分析相关推荐
- 经典排序算法 - 冒泡和快排总结
排序有很多种方法,但人们首先总会想起冒泡和快排,现在总结一下这两种经典算法. 1. 冒泡 public void bubbleSort(int[] a){ for (int i = 0; i < ...
- 三路快排算法加强版(三路快排的再次改进)
:不要忘记初心哈 :) 理论依据 快排算法的缺陷及其逐一改进 三路快排尽可能三等份划分区间 通过待排元素的区间长度划分? 通过待排元素的最值之差划分? 直接使用待排元素的最大值划分? 实验数据 大范围 ...
- LeetCode--75.颜色分类(三路快排,计数排序)
颜色分类(C) 1. 题目描述 2. 题目解析 3. C语言实现 3.1 三路快排法 3.2 计数排序法 1. 题目描述 难度:中等 2. 题目解析 这道题需要注意一下几点: 原地进行排序,不可以另外 ...
- LeetCode 75. Sort Colors (python一次遍历,模拟三路快排)
LeetCode 75. Sort Colors (python一次遍历,模拟三路快排) 题目分析: 本题需要实现数字只包含0,1,2的排序,并且要求一次遍历. 由于只用把数字隔离开,很容易想到快排的 ...
- 快速排序—三路快排 vs 双基准
快速排序被公认为是本世纪最重要的算法之一,这已经不是什么新闻了.对很多语言来说是实际系统排序,包括在Java中的Arrays.sort. 那么快速排序有什么新进展呢? 好吧,就像我刚才提到的那样(Ja ...
- 209-希尔排序算法的思想和性能分析
1.希尔排序算法的思想和性能分析 希尔排序可以认为是插入排序的一个优化,升级. 如果数据序列从大的方向,从全局看,已经是趋于有序的,那么插入排序是所有排序算法中效率最高的. 希尔排序就是从插入排序的这 ...
- 归并排序、快速排序、二路快排、三路快排python实现
源代码: https://github.com/lzneu/Algrithm_python O(n*logn)级别的排序: |-归并排序 分成log(n)个层级 每个层级进行O(n)排序 ...
- 快速排序 详解(快速排序 双路快排 三路快排)
注:内容,图片来自于慕课网liuyubobobo老师的课程. 官方代码链接:https://github.com/liuyubobobo/Play-with-Algorithms 快速排序 快速排序 ...
- java三路快排,java二路快排很慢
老师,以下是我二路快排的java代码 public class quickSortTwoway { public quickSortTwoway() {}; public static void qu ...
- 数据结构之排序【归并排序和快排的顶级优化和快排的三种原理的实现及分析】 内含动态演示图
文章目录 引言: 1.归并排序(MergeSort) 2.快速排序的优化(顶级优化) 3.快速排序的三种思路的代码实现及分析 4.归并排序和快排第3原理的测试 引言: 刚刚去回顾了一下递归实现的几个小 ...
最新文章
- 创建可微物理引擎Nimble,开源SOTA人体骨骼模型,斯坦福腿疾博士生用AI「助跑」人生...
- Qt Creator和VS2010中添加槽信号_差异与详解
- ITK:在图像上叠加标签图
- 小猪佩奇python_一段代码画出小猪佩奇社会人 Python
- 关于某些 Visual Studio Code 扩展程序无法在浏览器中运行的原因
- “只有DBA才能导入由其他DBA导出的文件”各种解决办法
- 打印ASCII码(信息学奥赛一本通-T1020)
- 虚拟化五、KVM虚拟化技术2
- centos 关机命令_Linux anacron命令用法详解
- 数据库 webSQL使用方法
- SAP ABAP 查询接口参数数据结构的报表
- php ssl证书安装,PHPWAMP如何开启SSL,Apache下如何安装ssl证书?配置ssl证书很简单...
- TEXMACS在ubuntu下的使用
- 电音制作收割者宿主软件-Cockos REAPER v6.15 x86 x64 WiN
- 软件测试思想者 - 初识抑郁症
- Java后端开发需要掌握什么
- Basic grammar of Python day2
- u盘中毒数据怎么才能恢复
- 我把3个镜头手机拍的照片发微信群,哥们说,现在手机摄像头越来越多,我有一个扫码就够了...
- SpringBoot集成Liquibase