快速排序与荷兰国旗及Partition问题

需求:

1、Partition过程

给定一个数组arr,和一个整数num。请把小于等于num的数放在数组的左边,大于num的数放在数组的右边。

要求额外空间复杂度O(1),时间复杂度O(N)

2、荷兰国旗问题

给定一个数组arr,和一个整数num。请把小于num的数放在数组的左边,等于num的数放在中间,大于num的数放在数组的右边。

要求额外空间复杂度O(1),时间复杂度O(N)

3、快速排序

思路:

1、Partition过程:

在原数组左边设置一个边界(left - 1),当index指向的数值比给定的值num小或等于时,

将这个数与边界右边的数交换,然后边界右移,

当index指向的数值比num大时,index右移动,边界

2、荷兰国旗问题(NetherLandsFlag):

在原数组左边设置一个左边界(left - 1),右边设置一个右边界(right+1),当index指向的数值比给定的值num小时,

将这个数与左边界右边的第一个数交换,然后左边界右移,index左移,当index指向的数值比num大时,将这个数与右边界左边的第一个数交换,然后i右边界左移,index不动,当index指向的数值与num相等时,边界均不动,index左移.

3、快速排序1.0:

用arr[R]对该范围做partition,小于等于 arr[R]的数在左部分并且保证arr[R]最后来到左部分的最后一个位置,记为M; 大于 arr[R]的数在右部分(arr[M+1..R])

2)对arr[L..M-1]进行快速排序(递归)

3)对arr[M+1..R]进行快速排序(递归)

因为每一次partition都会搞定一个数的位置且不会再变动,所以排序能完成.

4、快速排序2.0:

在arr[L..R]范围上,进行快速排序的过程:

1)用arr[R]对该范围做NetherLandsFlag,小于 arr[R]的数在左部分,等于arr[R]的数中间大于arr[R]的数在右部分。假设等于arr[R]的数所在范围是[a,b]

2)对arr[L..a-1]进行快速排序(递归)

3)对arr[b+1..R]进行快速排序(递归)

因为每一次partition都会搞定一批数的位置且不会再变动,所以排序能完成

5、快速排序3.0(随机快排+荷兰国旗技巧优化):

在arr[L..R]范围上,进行快速排序的过程:

1)在这个范围上,随机选一个数记为num,

1)用num对该范围做NetherLandsFlag,小于num的数在左部分,等于num的数中间,大于num的数在右部分。假设== num的数所在范围是[a,b]

2)对arr[L..a-1]进行快速排序(递归)

3)对arr[b+1..R]进行快速排序(递归)

因为每一次partition都会搞定一批数的位置且不会再变动,所以排序能完成

代码实现:

1、Partition过程:

  1. //Partition
  2. public static int quickSortPartition(int [] arr,int left,int right){
  3. if (arr == null || arr.length < 2){
  4. return -1;
  5. }
  6. if (left > right) {
  7. return -1;
  8. }
  9. if (left == right) {
  10. return right;
  11. }
  12. int lessEqual = left - 1;
  13. int index = left;
  14. while(index < right){
  15. if (arr[index] <= arr[right]){
  16. swap(arr,index,++lessEqual);
  17. }
  18. index++;
  19. }
  20. swap(arr,right,++lessEqual);
  21. return lessEqual;
  22. }

2、荷兰国旗问题(NetherLandsFlag):

  1. public static int [] netherlandsFlag(int [] arr,int left,int right){
  2. if (left > right){
  3. return new int [] {-1,-1};
  4. }
  5. if (left == right){
  6. return new int [] {left,right};
  7. }
  8. int Value = arr[right];
  9. int lessEqual = left - 1;
  10. int moreEqual = right + 1;
  11. int index = left;
  12. while(index < moreEqual){
  13. if (arr[index] < Value){
  14. swap(arr,index,++lessEqual);
  15. }
  16. if (arr[index] > Value){
  17. swap(arr,index,--moreEqual);
  18. index--;
  19. }
  20. index++;
  21. }
  22. return new int [] {lessEqual,moreEqual};
  23. }

3、快速排序

  1. //quickSort1.0
  2. public static void quickSort01(int [] arr){
  3. if (arr == null || arr.length < 2){
  4. return;
  5. }
  6. process01(arr,0,arr.length-1);
  7. }
  8. public static void process01(int [] arr, int left ,int right){
  9. if (left >= right){
  10. return;
  11. }
  12. int mid = quickSortPartition(arr,left,right);
  13. process01(arr,left,mid-1);
  14. process01(arr,mid+1,right);
  15. }
  16. //quickSort2.0
  17. // 主要是会有两个边界,没有浪费每次对比的信息
  18. public static void quickSort02(int [] arr){
  19. if (arr == null || arr.length < 2){
  20. return;
  21. }
  22. process02(arr, 0 ,arr.length-1);
  23. }
  24. public static void process02(int [] arr, int left ,int right){
  25. if(left >= right){
  26. return;
  27. }
  28. int[] bound = netherlandsFlag(arr, left, right);
  29. process02(arr,left,bound[0]);
  30. process02(arr,bound[1],right);
  31. }
  32. //quickSort3.0
  33. public static void quickSort3(int[] arr) {
  34. if (arr == null || arr.length < 2) {
  35. return;
  36. }
  37. process3(arr, 0, arr.length - 1);
  38. }
  39. public static void process3(int[] arr, int L, int R) {
  40. if (L >= R) {
  41. return;
  42. }
  43. swap(arr, L + (int) (Math.random() * (R - L + 1)), R);
  44. int[] equalArea = netherlandsFlag(arr, L, R);
  45. process1(arr, L, equalArea[0] - 1);
  46. process1(arr, equalArea[1] + 1, R);
  47. }

快速排序与荷兰国旗及Partition问题的更多相关文章

  1. July收集荷兰国旗问题之三路partition

    这道题目和分成两块的partition的扩展.比如有一堆0 1 2 数字组成的数组,要分成 00 00  11 1 1  222 2这样的顺序的. 利用lumoto版的partition能够非常好的解 ...

  2. 荷兰国旗 Flag of the Kingdom of the Netherlands

    问题描述:现有n个红白蓝三种不同颜色的小球,乱序排列在一起,请通过两两交换任意两个球,使得从左至右的球依次为红球.白球.蓝球.这个问题之所以叫做荷兰国旗,是因为将红白蓝三色的小球弄成条状物,并有序排列 ...

  3. 荷兰国旗问题、快排以及BFPRT算法

    荷兰国旗问题 给定一个数组arr,和一个数num,请把小于num的数放数组的左边,等于num的数放在数组的中间,大于num的数放在数组的右边.要求额外空间复杂度O(1),时间复杂度O(N). 这个问题 ...

  4. java荷兰国旗问题

    荷兰国旗包含三种颜色:红.白.蓝. 有三种颜色的球,算法的目标是将这三种球按颜色顺序正确地排列.它其实是三向切分快速排序的一种变种,在三向切分快速排序中,每次切分都将数组分成三个区间:小于切分元素.等 ...

  5. ACM 荷兰国旗问题

    荷兰国旗问题 时间限制:3000 ms  |  内存限制:65535 KB 难度:1   描述 荷兰国旗有三横条块构成,自上到下的三条块颜色依次为红.白.蓝.现有若干由红.白.蓝三种颜色的条块序列,要 ...

  6. 算法笔记_051:荷兰国旗问题(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 现有n个红白蓝三种不同颜色的小球,乱序排列在一起,请通过两两交换任意两个球,使得从左至右的球依次为红球.白球.蓝球.这个问题之所以叫荷兰国旗,是因为 ...

  7. Coursera Algorithms week2 基础排序 练习测验: Dutch national flag 荷兰国旗问题算法

    第二周课程的Elementray Sorts部分练习测验Interview Questions的第3题荷兰国旗问题很有意思.题目的原文描述如下: Dutch national flag. Given ...

  8. NYOJ_268_荷兰国旗问题

    荷兰国旗问题 时间限制:3000 ms  |  内存限制:65535 KB 难度:1 描写叙述 荷兰国旗有三横条块构成,自上到下的三条块颜色依次为红.白.蓝.现有若干由红.白.蓝三种颜色的条块序列.要 ...

  9. Java实现荷兰国旗问题

    问题描述 现有n个红白蓝三种不同颜色的小球,乱序排列在一起,请通过两两交换任意两个球,使得从左至右的球依次为红球.白球.蓝球.这个问题之所以叫荷兰国旗,是因为将红白蓝三色的小球弄成条状物,并有序排列后 ...

随机推荐

  1. inotifywait命令如何监控文件变化?

    转载自:https://segmentfault.com/a/1190000038351925 文件监控可以配合rsync实现文件自动同步,例如监听某个目录,当文件变化时,使用rsync命令将变化的文 ...

  2. ADF 第七篇:控制流

    Azure Data Factory 系列博客: ADF 第一篇:Azure Data Factory介绍 ADF 第二篇:使用UI创建数据工厂 ADF 第三篇:Integration runtime ...

  3. 关于 Softmax 回归的反向传播求导数过程

    对于 \(Softmax\) 回归的正向传播非常简单,就是对于一个输入 \(X\) 对每一个输入标量 \(x_i\) 进行加权求和得到 \(Z\) 然后对其做概率归一化. Softmax 示意图 下面 ...

  4. 【老孟Flutter】2020年总结

    2020年是我经历的最不平凡的一年,这一年有遗憾.有收获,有感概,也有庆幸,庆幸自己还活着. 用一句话总结自己的2020,忙并收获着,累并快乐着. <Flutter 实战入门> <F ...

  5. 后台返回的json数据,前台需要修改对象的键值名,重新修改数据格式

    //例如,后台返回的数据为: var json = { data: [   {value: 103.95, name: "法拉利"}, {value: 103.2, name: & ...

  6. Atlas 2.1.0 实践(2)—— 安装Atlas

    在完成Atlas编译以后,就可以进行Atlas的安装了.Atlas的安装主要是安装Atlas的Server端,也就Atlas的管理页面,并确保Atlas与Kafka Hbase Solr等组件的集成. ...

  7. Qt学习笔记-界面设置入门

    首先我们看的是qt类表.相当于是一个族谱.这个文档可以在网上搜到. 首先第一个是QObjiect. 然后是QWidget => 相当于是windowsget缩写. 同理: QColorDialo ...

  8. Linux 网卡 bonding配置

    网卡 bonding配置 目录 网卡 bonding配置 一.bonding技术 bonding的七种工作模式 总结: 二.Centos7配置bonding 1.关闭和停止NetworkManager ...

  9. 关于HashSet

    HashSet存储数据原理: 当HashSet调用add方法时,有返回值,返回值是boolean类型,表示是否添加成功(如果对象不存在,则添加成功,否则添加失败) 但是,添加的过程并不是一个个去遍历去 ...

  10. 图解HTTP权威指南(四)| 代理

    作者简介 李先生(Lemon),高级运维工程师(自称),SRE专家(目标),梦想在35岁买一辆保时捷.喜欢钻研底层技术,认为底层基础才是王道.一切新技术都离不开操作系统(CPU.内存.磁盘).网络等. ...