文章目录

  • 一、荷兰国旗问题
    • 1、啥是荷兰国旗问题
    • 2、荷兰国旗问题的抽象
    • 3、解决的思路
    • 4、详细的参考代码
  • 二、快速排序
    • 1、啥是快排(排序流程)
    • 2、抽象后的快排流程
    • 3、详细的参考代码

大家好,我是周一。

最近几篇算法,我们都是聊的归并排序,归并排序也说的差不多了,今天讲讲快速排序。

一、荷兰国旗问题

1、啥是荷兰国旗问题

荷兰国旗是由红白蓝3种颜色的条纹拼接而成,如下图所示:


假设这样的条纹有多条,且各种颜色的数量不一,并且随机组成了一个新的图形,新的图形可能如下图所示,但不仅仅只有这一种情况:

需求是:把这些条纹按照颜色排好,红色的在上半部分,白色的在中间部分,蓝色的在下半部分,我们把这类问题称作荷兰国旗问题。

2、荷兰国旗问题的抽象

我们把荷兰国旗问题抽象成数组的形式是下面这样的:

给定一个整数数组和一个值M(存在于原数组中),要求把数组中小于M的元素放到数组的左边,等于M的元素放到数组的中间,大于M的元素放到数组的右边,最终返回一个整数数组,只有两个值,0位置是等于M的数组部分的左下标值、1位置是等于M的数组部分的右下标值。

进一步抽象为更加通用的形式是下面这样的:

给定数组arr,将[l, r]范围内的数(当然默认是 [ 0 - arr.length - 1 ]),小于arr[r](这里直接取数组最右边的值进行比较)放到数组左边,等于arr[r]放到数组中间,大于arr[r]放到数组右边。最后返回等于arr[r]的左, 右下标值。

3、解决的思路

定义一个小于区,一个大于区;遍历数组,挨个和arr[r]比较,

(1)小于arr[r],与小于区的后一个位置交换,当前位置后移;

(2)等于arr[r],当前位置直接后移;

(3)大于arr[r],与大于区的前一个位置交换,当前位置不动(交换到此位置的数还没比较过,所以不动)。

遍历完后,arr[r]和大于区的最左侧位置交换。

最后返回,此时小于区的后一个位置,大于区的位置,即是最后的等于arr[r]的左, 右下标值。

4、详细的参考代码

    /*** 荷兰国旗问题* <p>* 把数组arr中,[l, r]范围内的数,小于arr[r]放到数组最左边,等于arr[r]放到数组中间,大于arr[r]放到数组最右边** @return 返回等于arr[r]的左, 右下标值*/public static int[] netherlandsFlag(int[] arr, int l, int r) {if (l > r) {return new int[]{-1, -1};}if (l == r) {return new int[]{l, r};}// 小于arr[r]的右边界,从L的左边一位开始int less = l - 1;// 大于arr[r]的左边界,从r开始,即当前右边界里已经有arr[r]int more = r;// 当前正在比较的下标int index = l;// 不能与 大于arr[r]的左边界 撞上while (index < more) {if (arr[index] < arr[r]) {// 小于时,将当前位置的数和小于arr[r]的右边界的下一个位置交换// 当前位置后移一位swap(arr, index++, ++less);} else if (arr[index] == arr[r]) {// 等于时,当前位置后移一位即可index++;} else {// 大于时,当前位置的数和大于arr[r]的左边界的前一个位置交换// 当前位置不动swap(arr, index, --more);}}// 将arr[r]位置的数和大于arr[r]的左边界的数交换// 此时整个数组就按照 小于、等于、大于arr[r] 分成了左中右三块swap(arr, more, r);// 最后整个数组中,等于arr[r]的左右边界分别是less + 1, morereturn new int[]{less + 1, more};}

二、快速排序

1、啥是快排(排序流程)

首先设定一个分界值,通过该分界值将数组分成左中右三部分。

(1)将小于分界值的数据集中到数组的左边,等于分界值的数据集中到数组的中间,大于分界值的数据集中到数组右边。

(2)然后,左边和右边的数据可以独立排序。对于左侧的数据,又可以取一个分界值,将该部分数据分成左中右三部分,同样在左边放较小值,中间放等于值,右边放较大值。右边数据也做同样的处理。

(3)重复上述过程,可以看出,这是一个递归过程。通过递归将左侧部分排好序后,再递归排好右侧部分的顺序。当左、右两个部分各数据排序完成后,整个数组的排序也就完成了。

当看完了快排的流程,是不是发现快排的核心方法就是荷兰国旗问题,所以知道为啥本文一开始就介绍荷兰国旗问题了吧

2、抽象后的快排流程

(1)随机将数组中的某个数放到比较位置上(即最右侧位置)

(2)调用荷兰国旗方法,(此时等于区的数即在最后排好序的位置上),拿到等于区的左右下标

(3)小于区和大于区再各自递归调用(1)(2)步即可将小于区和大于区排好序。

3、详细的参考代码

    /*** 随机快排*/public static void quickSortRandom(int[] arr) {if (arr == null || arr.length < 2) {return;}processRandom(arr, 0, arr.length - 1);}private static void processRandom(int[] arr, int l, int r) {if (l >= r) {return;}// 随机将数组中的某个数放到比较位置上(即数组最右边位置)// 这一步是保证快排时间复杂度是O(N*logN)的关键,不然,快排的时间复杂度是O(N^2)swap(arr, l + (int) ((r - l + 1) * Math.random()), r);// 将数组划分为 小于、等于、大于arr[r] 的左中右三块int[] equalArea = netherlandsFlag(arr, l, r);// 此时等于区域的值已经处于最后排序结果的位置了// 递归将左半部分的排好序processRandom(arr, l, equalArea[0] - 1);// 递归将右半部分的排好序processRandom(arr, equalArea[1] + 1, r);}public static void swap(int[] arr, int i, int j) {int tmp = arr[i];arr[i] = arr[j];arr[j] = tmp;}

荷兰国旗问题以及快速排序相关推荐

  1. 荷兰国旗问题(改造快速排序)

    本总结是是个人为防止遗忘而作,不得转载和商用. 题目 问题:现有红.白.蓝三个不同颜色的小球,乱序排列在一起,请重新排列这些小球,使得红白蓝三色的同颜色的球在一起. PS:之所以叫荷兰国旗问题,是因为 ...

  2. leetcode 75. Sort Colors | 75. 颜色分类(荷兰国旗问题,快速排序)

    题目 https://leetcode.com/problems/sort-colors/ 题解 快速排序3.0(随机快排+荷兰国旗技巧优化) 在arr[L-R]范围上,进行快速排序的过程: 1)在这 ...

  3. python单链表实现荷兰国旗问题_快速排序深入之荷兰国旗问题

    一.序言 在使用partition-exchange排序算法时,如快速排序算法(即使选择了一个好的关键元素pivot values),我们往往面临一个很尴尬的境地--当排序对象中有很多重复的元素,pa ...

  4. 各种排序算法以及扩展(选择排序,冒泡排序,插入排序,归并排序,最小和问题,堆排序,荷兰国旗问题,快速排序)

    文章目录 基础算法一二课 选择排序 冒泡排序 插入排序 判断数据是否在数组中 找满足>=value的最左位置 ^ 异或符号的多用 一.进行交换 二.数组中有一种数出现了奇数次,其他数都出现了偶数 ...

  5. 荷兰国旗问题和快速排序

    荷兰国旗问题有两种情况:1)给定一个数x,<= x的整体放在左边,>x的整体放在右边2)给定一个数x,< x的整体放在左边,= x的整体放在中间,> x的整体放在右边规定不需要 ...

  6. 快速排序以及荷兰国旗问题

    荷兰国旗 要点:指针在移动时, 1.如果指针对应的值小于给定值,左标记和指针均向右移 2-如果指针对应的值等于给定值,指针右移 3-如果指针对应的值大于给定值,右标志位左移 package Test; ...

  7. 快速排序(由荷兰国旗问题到快排)

    文章目录 一.荷兰国旗问题 荷兰国旗解题思路 荷兰国旗代码 二.荷兰国旗到快排 时间复杂度分析 稳定性分析 一.荷兰国旗问题 在了解快排之前,我们首先了解荷兰国旗问题 给定一个数组arr,和一个整数n ...

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

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

  9. 荷兰国旗问题(分三块)

    在说 "荷兰国旗" 问题之前,首先来看一个引例. 给定一个数组arr,和一个数num,请把小于等于num的数放在数组的左边,大于num的数放在数组的右边.要求额外空间复杂度O(1) ...

  10. 荷兰国旗排序的几种解法

    荷兰国旗排序的几种解法 leetcode 排序 算法 分治 Given an array with n objects colored red, white or blue, sort them so ...

最新文章

  1. php分页采集数据,php实现分页调取数据库记录
  2. 解决mysql无法启动,错误1067
  3. [nRF51822] 13、浅谈nRF51822和NRF24LE1/NRF24LU1/NRF24L01经典2.4G模块无线通信配置与流程...
  4. mysql索引讲解最好
  5. 【Nginx】上传文件的大小限制
  6. C语言二维数组作为函数的参数
  7. Centos7机器配置Google Authenticator动态密钥进行ssh二次验证图文详解
  8. 外卖小程序源码+后台_外卖cps外卖优惠券 赚钱小程序源码
  9. Oracle分区表及分区索引
  10. 如何用AE导出程序员可以复用的Json代码
  11. Traffic Control
  12. 微生物组学研究手段概览2——宏基因组和宏转录组
  13. 无法写入最后一个_影驰擎 GA-E 16TB SSD评测:3.96TB持续稳定写入,你想要的大容量来了...
  14. 法兰克oitf操作_FANUC 系列操作面板各按键
  15. hsqldb mysql 语法_[spring batch]建表语句(hsqldb改mysql)
  16. 怎么把window系统下的文件传到Ubuntu里去呢?
  17. 8-5 以下面四个在读写器作用范围内的电子标签为例说明二进制树型搜索算法选择电子标签的迭代过程。
  18. Zbrush基础《二》
  19. linux添加ax88772b驱动,佳能 USB 2.0 to Fast Ethernet AX88772B 驱动程序下载-更新佳能软件(以太网控制器)...
  20. Blender图解教程:马里奥食人花三部曲(二)骨骼绑定和动画(网格丢失的问题已解决 附模型下载)

热门文章

  1. 路径规划算法1.3抽样算法——PRM与RRT算法
  2. 总结:Oracle 递归查询
  3. Fragstats软件使用及其景观生态学意义
  4. html背景怎么变成透明的,怎样把图片背景变成透明
  5. Word的样式库在 选项卡中_2分钟学会在Word中制作田字格 米字格 书法练字再也不用买本子了...
  6. OpenDrive格式高精度地图详细解析及其使用(1.栅格地图、OpenDrive坐标系以及参考线介绍)
  7. vue弹出alert_vue.extend实现alert模态框弹窗步骤详解
  8. 降水小波分析matlab程序,小波分析MATLAB程序
  9. 单例模式-序列号生成器
  10. 【Rust日报】 2019-05-22:Mozilla图像团队发布WebRender MVP