快速排序

这里我们直接开始讲相对的最优解 带随机数的三路快排 好了,中间还有很多版本的快排,但是都有一些问题导致在某种极端情况下造成耗费时间极多。

  • 基础快排:在序列本身有序的情况下复杂度为O(n²)
  • 带随机数的快排:在序列本身有序的情况下复杂度为O(nlogn),但是在序列全部元素相同情况下复杂度为O(n²)
  • 带随机数的双路快排:比前者更快一些为O(n),因为前后同时向中间遍历,但是在序列全部元素相同情况下的复杂度问题仍旧未解决
  • 带随机数的三路快排: 解决上述各种问题且时间复杂度最快O(n)

工作原理:

将数组分为三个部分,小于V的,等于V的,大于V的。

  1. 首先在数组中选取任意一个下标和最左边的下标互换(选取一个随机下标的目的是,将快排结果最后V左边或右边没有东西的极端情况概率降到最小甚至约等于0,如果出现这种情况将会导致复杂度为n²,这里我们不再深入讨论)

  2. 确定需要的变量:因此我们要有2个下标 Lt,Rt 将数组分割成3部分。还需要一个下标 i 指向当前的元素 e 。除此之外,用 l 和 r 确定数组的首尾。

  3. 分配当前元素 e 去哪个区域 这里我们又分为3种情况:

    1. e < V 将e和Lt+1处(也就是 ==V 的第一个元素)的位置交换,然后Lt++
    2. e == V 将e直接纳入该区域(也就是不做处理)然后 i++ 即可
    3. e > V 将e和Rt - 1处(也就是 >V 的前一个元素)的位置交换,然后Rt--

    无论是哪个情况,无非就是将其和Lt和Rt附近的元素交换位置即可。

  1. 那么当全部都排序完毕时,也就是鼠标指的那个点处,i 和 Rt 重合时,退出循环

  1. 因为按顺序应该是 小于V ,V,==V,>V ,所以只要将V和 <V 处的最后一个元素交换位置即可

6.最后反复递归调用 <V 区间以及 >V 的区间,从而让两边的区间也都有序。

实现一下吧:

package com.sort;

import java.util.Random;

/**
* @Author: 翰林猿
* @Description: 三路快排
**/
public class Quick {
public Quick() {
} public static <T extends Comparable<T>> void quicksort(T[] arr) {
Random random = new Random();
quicksort3ways(arr, 0, arr.length - 1, random);
} private static <T extends Comparable<T>> void quicksort3ways(T[] arr, int l, int r, Random random) {
if (l >= r)
return;
int randomInt = l + random.nextInt(r + 1 - l); //生成一个不超过数组长度的随机数
swap(arr, randomInt, l); //把他和首元素交换位置 //定义需要的变量
int Lt = l; //放在数组最左边
int Rt = r + 1; //到时候先-1再交换
int i = l + 1; //最左边的下一个开始遍历
while (i < Rt) {
if (arr[i].compareTo(arr[l]) < 0) {
Lt++; //因为应该交换Lt+1处,所以可以直接先++再交换
swap(arr, Lt, i);
i++;
} else if (arr[i].compareTo(arr[l]) == 0) {
i++;
} else if (arr[i].compareTo(arr[l]) > 0) {
Rt--; //因为应该交换Rt-1处,所以可以直接先--再交换
swap(arr, Rt, i);
}
}
swap(arr, l, Lt); //将V摆到小于V和等于V中间
quicksort3ways(arr, l, Lt - 1, random); //反复递归调用 <V 区间以及 >V 的区间,让这两区间也都有序
quicksort3ways(arr, Rt, r, random);
} public static <E> void swap(E[] arr, int j, int beforej) {
E t = arr[j];
arr[j] = arr[beforej];
arr[beforej] = t;
} public static void main(String[] args) {
Integer[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 10, 9};
Quick.quicksort(arr);
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " "); //1,2,3,4,5,6,7,8,9,10
}
}
}

三路快排Java版(图文并茂思路分析)的更多相关文章

  1. 快速排序 java实现 (原理-优化) 三路快排

    一.基本的快速排序 在数组中选取一个元素为基点,然后想办法把这个基点元素移动到它在排好序后的最终位置,使得新数组中在这个基点之前的元素都小于这个基点,而之后的元素都大于这个基点,然后再对前后两部分数组 ...

  2. LeetCode 75. Sort Colors (python一次遍历,模拟三路快排)

    LeetCode 75. Sort Colors (python一次遍历,模拟三路快排) 题目分析: 本题需要实现数字只包含0,1,2的排序,并且要求一次遍历. 由于只用把数字隔离开,很容易想到快排的 ...

  3. 普林斯顿大学算法课 Algorithm Part I Week 3 重复元素排序 - 三路快排 Duplicate Keys

    很多时候排序是为了对数据进行归类,这种排序重复值特别多 通过年龄统计人口 删除邮件列表里的重复邮件 通过大学对求职者进行排序 若使用普通的快排对重复数据进行排序,会造成N^2复杂度,但是归并排序和三路 ...

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

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

  5. LeetCode 75. Sort Colors (颜色分类):三路快排

    Given an array with n objects colored red, white or blue, sort them in-place so that objects of the ...

  6. leetcode 75 Sort Colors 计数排序,三路快排

    解法一:计数排序:统计0,1,2 的个数 时间复杂度:O(n) 空间复杂度:O(k)    k为元素的取值范围, 此题为O(1) class Solution { public: void sortC ...

  7. 快排+java实现

    import java.util.Arrays; public class QuickSort { //三数取中法.取出不大不小的那个位置 public static int getPivotPos( ...

  8. 快速排序及三向切分快排——java实现

    快速排序也是一种分治算法.主要思想是选取一个切分点,将大于切分点的元素都放置到数组右侧,小于切分点的元素都放置到数组左侧:然后递归,再对切分点左侧和右侧分别排序. 归并排序时递归在前,归并在后,快速排 ...

  9. 快排java实现

    package sort; public class QuickSort { public static final int cutoff = 3; /** * insertion sort * * ...

  10. 快排java代码

    定一个基准位,递归左右两边排序. public void fun(){ int arr[] = {2,3,4,5,6,7,822,3,4,5,8,6,5,4,2,1}; //System.out.pr ...

随机推荐

  1. Flask框架使用蓝图划分目录、g对象、使用数据库连接池链接数据库

    目录 一.使用蓝图划分项目目录 1.蓝图的介绍 2.蓝图的使用 二.介绍flask框架的g对象 1. g对象是什么? 2. 使用代码再次解释g对象 三.使用数据库连接池链接数据库 1. 引入数据库连接 ...

  2. InnoDB 是如何解决幻读的

    前言 大部分人在日常的业务开发中,其实很少去关注数据库的事务相关问题,基本上都是 CURD 一把梭.正好最近在看 MySQL 的相关基础知识,其中对于幻读问题之前一直没有理解深刻,今天就来聊聊「Inn ...

  3. Helm 安装 Kubernetes 监控套件

    Helm 安装 Grafana Prometheus Altermanager 套件 安装helm # 安装helm工具 curl -fsSL -o get_helm.sh https://raw.g ...

  4. 学习docker看此文足以

    什么是 Docker Docker 最初是 dotCloud 公司创始人  在法国期间发起的一个公司内部项目,它是基于 dotCloud 公司多年云服务技术的一次革新,并于 ,主要项目代码在  上进行 ...

  5. w11修改ie保护模式方法

    IE安全设置下有4个区域 对应的设置在不同的注册表中.[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Set ...

  6. pandas之分类操作

    通常情况下,数据集中会存在许多同一类别的信息,比如相同国家.相同行政编码.相同性别等,当这些相同类别的数据多次出现时,就会给数据处理增添许多麻烦,导致数据集变得臃肿,不能直观.清晰地展示数据. 针对上 ...

  7. vim使用教程(最简单最全面的教程)

    本教程是vimtutor的原版内容.这是我读过最简单最全面的vim教程. 偶仅仅是优秀内容的搬运工,放在此处便于查阅,方便学习,版权归原作者所有. 注意:每一节的命令操作将会更改本文.推荐您复制本文的 ...

  8. .Net Core后端架构实战【2-实现动态路由与Dynamic API】

    摘要:基于.NET Core 7.0WebApi后端架构实战[2-实现动态路由与Dynamic API]  2023/02/22, ASP.NET Core 7.0, VS2022 引言 使用过ABP ...

  9. AndroidBanner - ViewPager 03

    AndroidBanner - ViewPager 03 上一篇文章,描述了如何实现自动轮播的,以及手指触摸的时候停止轮播,抬起继续轮播,其实还遗留了一些问题: 当banner不可见的时候,也需要停止 ...

  10. 数据分析06-五个pandas可视化项目

    数据分析-06 数据分析-06 pandas可视化 基本绘图 Series数据可视化 DataFrame数据可视化 高级绘图 代码总结 pandas可视化 基本绘图 pandas高级绘图 pandas ...