快速排序

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

  • 基础快排:在序列本身有序的情况下复杂度为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. pysimplegui之元素常用属性

    常用元素参数 您将在几乎所有元素创建调用中看到的一些参数包括: key - 与 window[key].事件和返回值字典一起使用 工具提示tooltip - 将鼠标悬停在元素上,您将获得包含此文本的弹 ...

  2. [Linux]./configure | make | make install的工作过程与原理

    经常使用的Linux编译/安装命令,有必要了解一下原理了. step1 ./configure 配置与编译前检查 通常由软件开发商编写一个检测程序(configure或config)来检测用户的操作环 ...

  3. [J2EE]Spring MVC中访问静态资源[转]

    1 文献来源 SpringMVC访问静态资源的三种方式(转) - 博客园 SpringMVC访问静态资源的三种方式 + 提供解决方案的原作者 2 前言 2.1 访问不到静态资源起因 如果web.xml ...

  4. Spring Initailizr(项目初始化向导)

    本地创建 官网创建版 在Spring官网https://start.spring.io/ 中选择 此时这个项目以压缩包形式下载到本地文件中,然后解压,导入IDEA中 阿里start创建 如果国外的网址 ...

  5. 请求被中止: 未能创建 SSL/TLS 安全通道 解决方案

    最近项目改造https,有部分请求出现"请求被中止: 未能创建 SSL/TLS 安全通道". 原因应该是,接口方变更了安全协议,而客户端并未启用该协议. 解决办法自然就是:让客户端 ...

  6. .NET中使用Redis总结 —— 1.Redis搭建

    注:关于如何在windows,linux下配置redis,详见这篇文章:) 下载地址:http://redis.io/download Redis官方是不支持windows的,只是 Microsoft ...

  7. MySQL匿名空用户名处理

    问题描述:公司漏扫发现数据库内出现空用户名及密码,需要对这些用户进行整改 1.首先出现了疑问,这些空的用户名是怎么出现的,而且不附带密码. 2.可以手动这样创建这样的用户名和密码形式么. 3.如果能这 ...

  8. JS 实现关键字文本搜索 高亮显示

    示例:  利用字符串的 split 方法,通过搜索的关键字分割成数组  在利用数组的 join 方法拼接成字符串 我是利用mock的省份 1 <template> 2 <div cl ...

  9. 在Winform分页控件中集成保存用户列表显示字段及宽度调整设置

    在Winform的分页控件里面,我们提供了很多丰富的功能,如常规分页,中文转义.导出Excel.导出PDF等,基于DevExpress的样式的分页控件,我们在其上面做了不少封装,以便更好的使用,其中就 ...

  10. 2022-10-24:以下go语言代码输出什么?A:3 3;B:3 4;C:0 0;D:0 1。 package main func main() { m := make(map[int]int

    2022-10-24:以下go语言代码输出什么?A:3 3:B:3 4:C:0 0:D:0 1. package main func main() { m := make(map[int]int, 3 ...