:不要忘记初心哈 :)

  • 理论依据
    • 快排算法的缺陷及其逐一改进
    • 三路快排尽可能三等份划分区间
      • 通过待排元素的区间长度划分?
      • 通过待排元素的最值之差划分?
      • 直接使用待排元素的最大值划分?
  • 实验数据
    • 大范围随机,重复元素极少
      • 一千万数据
      • 一个亿数据
    • 小范围随机,大量重复元素
      • 一千万数据
      • 一个亿数据
    • 当待排序的元素完全重复时
      • 一千万数据
      • 一个亿数据
    • 当待排序的元素线性无重时
      • 一千万数据
    • 实验数据总结
    • 通过实验发现的一些规律
    • 关于实验数据疑惑的解答
  • 代码实现
  • 参考资料

理论依据

快排算法的缺陷及其逐一改进

关于快速排序,无论是单路还是双路亦或是三路快排,
有关其缺陷与优化办法,
我在之前的一篇文章里已经作出了详细解读.
具体链接如下:

快速排序(重温经典算法系列)

如何在 Partition操作时,尽可能地 —— 划分出
3等分的元素区间?
这边是三路快排的改进策略.

三路快排尽可能三等份划分区间

通过待排元素的区间长度划分?
思路1:
利用待排序的区间长度,实现三等分划分?
即:
(high - low)为当前待排序区间[low,high]的长度.
令之划分出三等分,然后再于中间部分随机选取 哨兵元素.
(int)((high - low)/3.0*1.0)
(int)((high - low)/3.0*2.0)可行度:(1——5评价)3 颗星

利弊分析

如此设计,仅会在元素值与其索引值存在某种关联时才会产生巨大的优化效果.
虽说完全有序的数据往往与数组索引值存在关联,
但是在处理其他完全随机或者元素随机范围不大的数据时,优化适得其反.
通过待排元素的最值之差划分?
思路1:
利用待排区间的最值元素之差,实现三等分划分?
即:
maxNum 和 minNum 分别存放当前待排序区间的最大和最小元素值,
令之划分出三等分,即
以 (maxNum - minNUm) 替代 (high - low),
然后再于中间部分随机选取 哨兵元素.可行度:(1——5评价)2 颗星

利弊分析

如此设计,
当区间元素范围较大时,多数情况下都会存在或多或少的优化效果.
可当区间元素范围较小时(此时待排序区间通常也相对较小),
优化操作并不明显甚至是适得其反,拖累程序性能.
快排到了中后期阶段,
待排序的区间往往会变得很小,其中的元素值也会大小不相上下,
这种情况下,
最值元素之差就变得很小了,此时优化操作变为拖累行为.
另外,
更不用说若给出的数据直接是范围极小、存在大量的重复元素的数组了,
如此情况下优化代码几乎没有用处,
加强版三路快排已经退化为三路快排,并且由于额外的设计开销导致算法性能大不如前.
更加地适得其反!!
严重拖累程序性能!!!
直接使用待排元素的最大值划分?
思路1:
直接利用待排区间的最大值元素,实现三等分划分?
即:
maxNum 和 minNum 分别存放当前待排序区间的最大和最小元素值,
但是 仅以 maxNum 替代 (high - low),
然后再于中间部分随机选取 哨兵元素.可行度:(1——5评价)5 颗星

利弊分析

经数据测试,这是一个普适版本的优化方式.
无论是元素完全随机的情况,
还是元素随机范围极小、存在大量重复元素的情况,
甚至是两两相等、元素完全重复的数据
亦或是元素直接等于其索引值、完全线性没有任何重复元素的情况,
或者是该情况元素先取反序之后再排序,
加强型三路快排都优胜与其他三种快排的设计.
这,
是我自己通过实验数据、反复操作尝试得到的优化结果.
暂无使得其性能下降的反例数据.

实验数据

大范围随机,重复元素极少

此种情况下有可能会存在少量的重复元素,不过
即使有往往也是极少的,
绝大多数情况下都不会多个重复的元素.
一千万数据

测试一:1千万数据,1亿范围随机

测试二:1千万数据,1千万范围随机

测试三:1千万数据,10万范围随机

一个亿数据

小范围随机,大量重复元素

此种情况下会存在大量的重复的元素.
由于此时单路快排的缺陷暴露无遗.
虽然三路快排擅长处理重复元素,但是性能还是不及改进后的加强型三路快排.
一千万数据

测试一:1千万数据,[10,20] 随机范围

测试二:1千万数据,[10,100] 随机范围

一个亿数据

测试一:1个亿数据,[10,20] 随机范围

测试二:1个亿数据,[10,100] 随机范围

测试三:1个亿数据,[10,1000] 随机范围

当待排序的元素完全重复时

此种情况下元素完全重复、全部相等.
由于此时单路快排退化为 O(N^2),无法参与数据测试.
理论上,处理完全重复的元素时,
改进后的加强型三路快排会退化为经典的三路快排,
并且优化操作会造成额外开销.
但是由于本设计细节的进一步改善之后,此两者算法的开销几乎相同,
甚至有时候加强型三路快排还略微快出那么一丢丢.
一千万数据

测试一:1千万数据,数值10

测试二:1千万数据,数值10000

测试三:1千万数据,数值1千万

一个亿数据

测试一:1个亿数据,数值10

测试一:1个亿数据,数值10万

测试三:1个亿数据,数值1千万

当待排序的元素线性无重时

此种情况下元素完全不重复、没有任何相等的两个元素.
此时经典的三路快排性能堪忧,因为其优化操作适得其反.
然而加强版三路快排却依旧是佼佼者.
一千万数据

测试一:1千万数据,各个元素取对应的下标索引值,完全线性递增、顺序

测试二:1千万数据,先完全线性递增,再进行少量元素位置交换,局部有序

测试三:1千万数据,对上述数组元素取反后再进行排序,完全递降、逆序

测试四:1千万数据,存在大量的局部逆序对的数据

实验数据总结

无论任何类型的数据,加强型三路快排算法,
永远是四种快排设计中的最优者.
这是由自己通过不断试验和测试数据,不断改进代码的设计方式得到的.
为此,真的很欣慰!!!

通过实验发现的一些规律

规律1:线性数据、无重复元素时,数据排列越混乱,快排运行处理的效率反而越高.
这是因为快排的哨兵值划分出的区间得以更加均匀和等长化。
规律2:经典算法设计的单路快排、双路快排和三路快排,在处理局部有序的数据时,
处理大量顺序对的数据要比处理逆序对的数据更快一些(排序结果为升序).
但是加强版三路快排却与之相反,处理由大到小的降序数据要比递增的块,这应该是
由自己的设计细节决定的,即前者能够更加准确地获取最大数值 MaxNum.
规律3:完全重复的数据,其数值大小并不会对任何一种快速排序产生影响;  普适.

关于实验数据疑惑的解答

关于同一级别大小和同一数值范围的实验数据,
不同次的测试的实验结果会存在一定的出入.
为何如此?
因为自己在设计快速排序时,标定点处(即哨兵值)是随机选取的.
每一轮快排处理的区间都会随机产生一个新的哨兵数值,
故而测试结果会有一定的差异.

代码实现

由于此次三路快排的优化方式,是自己首创的.
不宜公开,:)
万分抱歉,如果让你感到不适的话.
不过,可以前来与我交流.
知识,不吝赐教!!!
不过这里可以提供一篇文章,自己就是受到这篇文章的启发进而实现了对
3路快排算法的进一步代码优化.
不胜感激!!!

文章链接:一种三路划分快速排序的改进算法

参考资料

有关快排的基本设计问题,建议看我之前的文章:

快速排序(重温经典算法系列)

快排算法排序过程的图形化演示,请参考:
排序算法过程演示

交流方式
QQ —— 2636105163(南国烂柯者)

温馨提示:
转载请注明出处!!

文章最后更新时间:
2020年3月30日05:07:14
2020年4月2日19:47:56

三路快排算法加强版(三路快排的再次改进)相关推荐

  1. java快排算法解读,java 快排的思路与算法

    java 快排的思路与算法 有时候面试的时候的会问道Arrays.sort()是怎么实现的,我以前根本不知道是什么东西,最近点进去看了一下.直接吓傻, //看到这个时候还是比较淡定的,可怕的事情来了. ...

  2. 春招冲刺Day2 [高频算法题] -- 一网打尽快排

    一网打尽快排 1.初出茅庐 2.小试牛刀 3.炉火纯青(快排) 4.登峰造极(随机快排) 快速排序作为十大经典排序算法之一,在面试场中屡屡出现,不是要求手写快速排序,就是快速排序的变种,为了方便复习, ...

  3. python实现快排算法(quicksort)

    python实现快排算法(quicksort) 快速排序是对冒泡排序的一种改进.它的基本思想是:通过一次排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一不部分的所有数据都要小,然后 ...

  4. 快排算法的Java实现

    快排算法的Java实现 快排的核心是找到在无序数组中找到一个数,然后将比他小的数字放在他的左边,比他大的数字放在他的右边.然后递归的对左右两边进行继续排序,直到完成,下面看算法的实现: public ...

  5. C语言手写快排算法,两个值时也可以使用哦!

    最近刷leetcode经常碰到排序问题,大家都知道排序算法中快速排序是效率很高的算法,因此快排写法是必须要掌握的哦! 解题思路 利用快排对数组进行排序. 快排:冒泡排序的改良. 快排目标:将数组从大到 ...

  6. 快排算法的针对重复键值的优化

    上一节讲了快排算法在序列基本有序的情况下的两种优化方法,这一节我们对新的测试用例进行测试,测试用例如下所示: int main() {//测试 - 待排序列的重复值很多int n = 400000;i ...

  7. 排序算法 | 快排、冒泡、堆排、归并、基数、递归、希尔、计数

    文章目录 写在前面 排序 1. 基数排序`稳定` 2. 归并排序`稳定`merge sort 3. 快速排序`不稳定`quick sort 4. 堆排序`不稳定`heap sort 大根堆 小根堆 5 ...

  8. 力扣刷题记录---快排算法

    AcWing 785. 快速排序 对快排算法思想就不描述了,针对快排递归过程中边界的取值做了总结: x为每次递归中,选取的基准数(枢轴) 如果x = q[i]或者x = q[l + r >> ...

  9. java实现快排算法

    前面我详细讲解了快排算法,现在我们用java来实现 直接上代码 package ttt;public class kuaisupaixu {public static int[] quickSort( ...

最新文章

  1. 求助大佬6——1种贪心
  2. python 2 3 读写中文文件 使用codecs最方便
  3. Apache Ant运行时Unable to locate tools.jar解决方法
  4. Ubuntu 16.04下减小/释放/清理VirtualBox虚拟硬盘文件的大小
  5. HDU 1426 Sudoku Killer
  6. Java虚拟机的功能
  7. mysql的jdbc版本_【jdbc】Mysql 8版本jdbc设置
  8. Demo能为游戏带来什么?
  9. linux shell 脚本个人规范总结
  10. magicAjax问题
  11. roku能不能安装软件_如何在Roku中使用Google Assistant
  12. 垃圾代码还能出圈?手把手教你写垃圾代码,从入门到精通!
  13. 二叉树层序遍历(广度优先搜索)基础概念与经典题目(Leetcode题解-Python语言)
  14. [css] 什么是脱离文档流?有什么办法可以让元素脱离标准的文档流?
  15. [密码学基础][每个信息安全博士生应该知道的52件事][Bristol Cryptography][第34篇]描述攻击离散对数问题的baby-step/Giant-step方法
  16. 匹配指定内容的div_HTML背景色教程–如何更改Div背景色,并通过代码示例进行了说明...
  17. 服务治理之Eureka--基本介绍
  18. 软件项目经理新手上路16 - 后记,一切才刚刚开始
  19. 引用原话,不等于原意
  20. C语言 通讯录管理系统(链表,手机号码分段存储,txt文件存取)

热门文章

  1. C语言字符串函数(3)strstr,strtok函数的详解
  2. 微信答题小程序开发,怎么制作用于考试的小程序,微信小程序军人条令考试,微信小程序里给员工学习考试
  3. 破局 | STO 会是P2P不良资产包化解难的救星吗?
  4. vue+typescript怎么写computed
  5. 安卓反编译就这么简单
  6. 基于ssh学生请假管理系统
  7. 金属膜电阻 碳膜电阻 水泥电阻 铝壳电阻比较
  8. 计算机应用外审到期未反应,计算机应用 审理中 超期
  9. 我的Electron个人学习笔记
  10. 为什么薄膜干涉的厚度要很小_薄膜厚度对薄膜干涉现象的影响及其物理意义