快速排序可以说是20世纪最伟大的算法之一了。相信都有所耳闻,它的速度也正如它的名字那样,是一个非常快的算法了。当然它也后期经过了不断的改进和优化,才被公认为是一个值得信任的非常优秀的算法。

本文将结合快速排序的三方面进行比较和深入解析。

快速排序

public class QuickSort {// 递归使用快速排序,对arr[l...r]的范围进行排序public static void QuickSort(int[] arr,int l,int r){if(l>=r)return;int p = partition(arr,l,r);QuickSort(arr,l,p-1);QuickSort(arr,p+1,r);}// 将数组通过p分割成两部分// 对arr[l...r]部分进行partition操作// 返回p, 使得arr[l...p-1] < arr[p] ; arr[p+1...r] > arr[p]public static int partition(int[] arr, int l, int r) {swap(arr, l, (int) (Math.random() * (r - l + 1)) + l); // 随机快速排序int v = arr[l];int j = l;for(int i = j +1;i<=r;i++){if(arr[i] < v){j++;swap(arr,i,j);}}swap(arr,l,j);return j;}public static void swap(int[] arr,int i,int j) {int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}// 打印arr数组的所有内容public static void printArray(int[] arr) {for (int i = 0; i < arr.length; i++){System.out.print( arr[i] );System.out.print( ' ' );}System.out.println();return;}public static void main(String[] args){int[] arr = {4,3,12,12};QuickSort(arr,0,arr.length-1);printArray(arr);}
}

双路快速排序

若果数组中含有大量重复的元素,则partition很可能把数组划分成两个及其不平衡的两部分,时间复杂度退化成O(n²)。这时候应该把小于v和大于v放在数组两端

实际上把等于的部分分散到了数组两端


public class QuickSort2Ways {// 双路快速排序的partition// 返回p, 使得arr[l...p-1] < arr[p] ; arr[p+1...r] > arr[p]private static int partition(int[] arr, int l, int r) {// 随机在arr[l...r]的范围中, 选择一个数值作为标定点pivotswap(arr, l, (int) (Math.random() * (r - l + 1)) + l);int v = arr[l];// arr[l+1...i) <= v; arr(j...r] >= vint i = l + 1, j = r;while (true) {// 注意这里的边界, arr[i] < 0, 不能是arr[i] <= v// 思考一下为什么?while (i <= r && arr[i] < v)i++;// 注意这里的边界, arr[j] > v, 不能是arr[j] >= v// 思考一下为什么?while (j >= l + 1 && arr[j] > v)j--;// 对于上面的两个边界的设定, 有的同学在课程的问答区有很好的回答:)// 大家可以参考: http://coding.imooc.com/learn/questiondetail/4920.html// 答案:多了个等号的判断也会造成两棵子树不平衡if (i > j)break;swap(arr, i, j);i++;j--;}swap(arr, l, j);return j;}// 递归使用快速排序,对arr[l...r]的范围进行排序private static void QuickSort2Ways(int[] arr, int l, int r) {// 对于小规模数组, 使用插入排序// if( r - l <= 15 ){//    InsertionSort.sort(arr, l, r);//    return;// }int p = partition(arr, l, r);QuickSort(arr, l, p - 1);QuickSort(arr, p + 1, r);}private static void swap(int[] arr, int i, int j) {int t = arr[i];arr[i] = arr[j];arr[j] = t;}// 打印arr数组的所有内容public static void printArray(int[] arr) {for (int i = 0; i < arr.length; i++) {System.out.print(arr[i]);System.out.print(' ');}System.out.println();return;}// 测试 QuickSortpublic static void main(String[] args) {//双路快速排序算法也是一个O(nlogn)复杂度的算法// 可以在1秒之内轻松处理100万数量级的数据int[] arr = {4, 3, 12, 12};QuickSort2Ways(arr, 0, arr.length - 1);printArray(arr);}
}

三路快速排序

数组分成三个部分,大于v 等于v 小于v


public class QuickSort3Ways {// 递归使用快速排序,对arr[l...r]的范围进行排序private static void QuickSort3Ways(int[] arr, int l, int r){// 随机在arr[l...r]的范围中, 选择一个数值作为标定点pivotswap( arr, l, (int)(Math.random()*(r-l+1)) + l );int v = arr[l];int lt = l;     // arr[l+1...lt] < vint gt = r + 1; // arr[gt...r] > vint i = l+1;    // arr[lt+1...i) == vwhile( i < gt ){if( arr[i] < v){swap( arr, i, lt+1);i ++;lt ++;}else if( arr[i] > v ){swap( arr, i, gt-1);gt --;}else{ // arr[i] == vi ++;}}swap( arr, l, lt );QuickSort3Ways(arr, l, lt-1);QuickSort3Ways(arr, gt, r);}private static void swap(int[] arr, int i, int j) {int t = arr[i];arr[i] = arr[j];arr[j] = t;}// 打印arr数组的所有内容public static void printArray(int[] arr) {for (int i = 0; i < arr.length; i++) {System.out.print(arr[i]);System.out.print(' ');}System.out.println();return;}// 测试 QuickSortpublic static void main(String[] args) {// 三路快速排序算法也是一个O(nlogn)复杂度的算法// 可以在1秒之内轻松处理100万数量级的数据int[] arr = {4, 3, 12, 12};QuickSort3Ways(arr, 0, arr.length - 1);printArray(arr);}
}

深入理解快速排序(随机快排、双路快排、三路快排)相关推荐

  1. 三路快排算法加强版(三路快排的再次改进)

    :不要忘记初心哈 :) 理论依据 快排算法的缺陷及其逐一改进 三路快排尽可能三等份划分区间 通过待排元素的区间长度划分? 通过待排元素的最值之差划分? 直接使用待排元素的最大值划分? 实验数据 大范围 ...

  2. 快速排序 详解(快速排序 双路快排 三路快排)

    注:内容,图片来自于慕课网liuyubobobo老师的课程.  官方代码链接:https://github.com/liuyubobobo/Play-with-Algorithms 快速排序 快速排序 ...

  3. 快速排序—三路快排 vs 双基准

    快速排序被公认为是本世纪最重要的算法之一,这已经不是什么新闻了.对很多语言来说是实际系统排序,包括在Java中的Arrays.sort. 那么快速排序有什么新进展呢? 好吧,就像我刚才提到的那样(Ja ...

  4. 归并排序、快速排序、二路快排、三路快排python实现

    源代码: https://github.com/lzneu/Algrithm_python O(n*logn)级别的排序: |-归并排序     分成log(n)个层级 每个层级进行O(n)排序   ...

  5. 快速排序(详细图解 单路、双路、三路)

    一.快速排序 选取待排序数组的任意一个数据作为基准值,遍历数组中的元素.将小于基准值的元素放在基准值的左边,大于基准值的放在基准值的右边,将基准值放在中间,此时基准值到达了最终位置.然后对基准值左边的 ...

  6. 双路快速排序以及三路排序算法

    目录 双路快速排序 一.概念及其介绍 二.适用说明 三.过程图示 四.Java 实例代码 三路排序算法 一.概念及其介绍 二.适用说明 三.过程图示 四.Java 实例代码 双路快速排序 一.概念及其 ...

  7. c++双向列表释放_至为芯科技IP5356集成20W输出和双路TYPE-C快充输出,适用于充电宝/移动电源方案...

    至为芯科技IP5356集成20W输出和双路TYPE-C快充输出,适用于充电宝/移动电源方案 定制双C 口应用,IP5356 定制方案可支持MICRO-B 快充输入.TYPE-C 快充输入输出.TYPE ...

  8. 服务器排性能行榜,服务器CPU性能排行榜天梯图(双路/三路/四路)

    排名 多路处理器 CPU性能分 1 [四路] Intel Xeon Platinum 8180 @ 2.50GHz 44139 2 [双路] Intel Xeon Gold 6154 @ 3.00GH ...

  9. Mysql优化_ORDER BY和GROUP BY 的优化讲解(单路排序和双路排序)

    ORDER BY 子句尽量使用Index方式排序,避免使用FileSort方式排序,尽可能在索引列上外城排序操作,遵照索引键的最佳左前缀.如果不在索引列上,FileSort有两种算法,Mysql就要启 ...

最新文章

  1. 重做日志和控制文件的多路复用
  2. php源码中如何添加滚动公告,如何给WordPress网站添加滚动公告?
  3. CrazePony飞行器--相关资料网址
  4. 日历,日期类(copy)
  5. CNN(Convolutional Neural Networks)算法
  6. mysql40题_mysql40题
  7. Redis 的各项功能到底解决了哪些问题?
  8. 消息系统kafka原理解析
  9. 池化层:最大池化MaxPool、平均池化AvgPool、自适应池化AdaptiveMaxPool区别--基于pytorch框架
  10. phabricator mysql_Phabricator服务的搭建
  11. 计算机安全的加密技术,计算机安全加密技术研究(4篇)(共14695字).doc
  12. 电脑护眼设置_99%的人一直坚持着错误的护眼方式!
  13. asp.net + jQuery + LINQ 简单登录
  14. php 去除div标签,JavaScript_清除div下面的所有标签的方法,复制代码 代码如下: div id=s - phpStudy...
  15. android 万能视频播放器源码,Android万能视频播放器05-音视频同步
  16. 2.模仿小米通讯录的快速索引demo
  17. tensorflow的数据类型
  18. Java串口通信读写串口导致程序崩溃问题
  19. 【A40I-LVDS】
  20. PS设计网页下载使用960栅格系统设计简洁网页

热门文章

  1. Fedora 33 KED 版 配置记录
  2. 小时“数感”好,长大才能数学好
  3. fetch发送请求:Failed to fetch
  4. [附源码]SSM计算机毕业设计运动器材网上销售系统JAVA
  5. 【英语】最清晰最快速最大声之丹田发声
  6. linux会自动碎片整理,Linux为何这么屌,无需碎片整理
  7. LNMP平台服务简介、部署及应用
  8. 湖北汽车工业学院Linux期末复习
  9. 东莞四中2021年高考文科成绩查询,广东东莞2021年普通高中学业水平合格性考试成绩查询入口(已开通)...
  10. 正点原子stm32F407探索者 贪吃蛇