三路快排Java版(图文并茂思路分析)
快速排序
这里我们直接开始讲相对的最优解 带随机数的三路快排 好了,中间还有很多版本的快排,但是都有一些问题导致在某种极端情况下造成耗费时间极多。
- 基础快排:在序列本身有序的情况下复杂度为O(n²)
- 带随机数的快排:在序列本身有序的情况下复杂度为O(nlogn),但是在序列全部元素相同情况下复杂度为O(n²)
- 带随机数的双路快排:比前者更快一些为O(n),因为前后同时向中间遍历,但是在序列全部元素相同情况下的复杂度问题仍旧未解决
- 带随机数的三路快排: 解决上述各种问题且时间复杂度最快O(n)
工作原理:
将数组分为三个部分,小于V的,等于V的,大于V的。
首先在数组中选取任意一个下标和最左边的下标互换(选取一个随机下标的目的是,将快排结果最后V左边或右边没有东西的极端情况概率降到最小甚至约等于0,如果出现这种情况将会导致复杂度为n²,这里我们不再深入讨论)
确定需要的变量:因此我们要有2个下标 Lt,Rt 将数组分割成3部分。还需要一个下标 i 指向当前的元素 e 。除此之外,用 l 和 r 确定数组的首尾。
分配当前元素 e 去哪个区域 这里我们又分为3种情况:
- e < V 将e和Lt+1处(也就是 ==V 的第一个元素)的位置交换,然后Lt++
- e == V 将e直接纳入该区域(也就是不做处理)然后 i++ 即可
- e > V 将e和Rt - 1处(也就是 >V 的前一个元素)的位置交换,然后Rt--
无论是哪个情况,无非就是将其和Lt和Rt附近的元素交换位置即可。

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

- 因为按顺序应该是 小于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版(图文并茂思路分析)的更多相关文章
- 快速排序 java实现 (原理-优化) 三路快排
一.基本的快速排序 在数组中选取一个元素为基点,然后想办法把这个基点元素移动到它在排好序后的最终位置,使得新数组中在这个基点之前的元素都小于这个基点,而之后的元素都大于这个基点,然后再对前后两部分数组 ...
- LeetCode 75. Sort Colors (python一次遍历,模拟三路快排)
LeetCode 75. Sort Colors (python一次遍历,模拟三路快排) 题目分析: 本题需要实现数字只包含0,1,2的排序,并且要求一次遍历. 由于只用把数字隔离开,很容易想到快排的 ...
- 普林斯顿大学算法课 Algorithm Part I Week 3 重复元素排序 - 三路快排 Duplicate Keys
很多时候排序是为了对数据进行归类,这种排序重复值特别多 通过年龄统计人口 删除邮件列表里的重复邮件 通过大学对求职者进行排序 若使用普通的快排对重复数据进行排序,会造成N^2复杂度,但是归并排序和三路 ...
- 快速排序—三路快排 vs 双基准
快速排序被公认为是本世纪最重要的算法之一,这已经不是什么新闻了.对很多语言来说是实际系统排序,包括在Java中的Arrays.sort. 那么快速排序有什么新进展呢? 好吧,就像我刚才提到的那样(Ja ...
- LeetCode 75. Sort Colors (颜色分类):三路快排
Given an array with n objects colored red, white or blue, sort them in-place so that objects of the ...
- leetcode 75 Sort Colors 计数排序,三路快排
解法一:计数排序:统计0,1,2 的个数 时间复杂度:O(n) 空间复杂度:O(k) k为元素的取值范围, 此题为O(1) class Solution { public: void sortC ...
- 快排+java实现
import java.util.Arrays; public class QuickSort { //三数取中法.取出不大不小的那个位置 public static int getPivotPos( ...
- 快速排序及三向切分快排——java实现
快速排序也是一种分治算法.主要思想是选取一个切分点,将大于切分点的元素都放置到数组右侧,小于切分点的元素都放置到数组左侧:然后递归,再对切分点左侧和右侧分别排序. 归并排序时递归在前,归并在后,快速排 ...
- 快排java实现
package sort; public class QuickSort { public static final int cutoff = 3; /** * insertion sort * * ...
- 快排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 ...
随机推荐
- @property、关联关系、继承、多继承
1.@property使用来修饰属性的,将属性私有化改为公有化,但是可以设置属性条件 格式: class Person: def __init__(self,name,age): self.name ...
- 如何使用sms-activate解决短信验证码问题
目录 前言 第一步:注册sms-activate 第二步:找到我们需要的服务 第三步:使用服务 前言 最近有许多小伙伴私信我,由于他们的工作需要让我安利一款接码工具供他们使用,于是我在调研各大接码平台 ...
- .NET 8新预览版本使用 Blazor 组件进行服务器端呈现
简介 此预览版添加了对使用 Blazor 组件进行服务器端呈现的初始支持.这是 Blazor 统一工作的开始,旨在使 Blazor 组件能够满足客户端和服务器端的所有 Web UI 需求.这是该功能的 ...
- .NET无侵入自动化探针原理和主流实现
前言 最近,我在微信公众号和博客园分享了一篇关于.NET微服务系统迁移至.NET 6.0的故事的文章,引起了许多读者的关注.其中,许多人对基于 OpenTelemetry .NET 的观测指标和无侵入 ...
- flex:1的情况下,overflow:auto没有生效的问题
flex:1的元素的父元素必须保证高度或者宽度有具体的数值:如果父元素的高度或者宽度也是flex:1自适应的,最好在父元素上也设置overflow:auto,这样子元素的overflow:auto生效 ...
- Ffmpeg 视频压缩的几个关键参数
Ffmpeg的视频操作官网文档:https://ffmpeg.org/ffmpeg-filters.html#Video-Filters 视频压缩用到的参数主要为以下几个: 文件路径:-i 输入文件的 ...
- [Pytorch框架] 2.5 循环神经网络
文章目录 2.5 循环神经网络 2.5.1 RNN简介 RNN的起因 为什么需要RNN RNN都能做什么 2.5.2 RNN的网络结构及原理 RNN LSTM GRU 2.5.3 循环网络的向后传播( ...
- 《C和指针》第一章
1 第一章 C标准库中几个常用的IO函数 int puts(void *str): 从str中提取字符直到遇到第一个'\0'为止,将这些字符串加上'\n'后发送给stdout. int main(vo ...
- [[SCOI2008]城堡] 解题报告
[SCOI2008]城堡 最大值最小,显然二分答案,但考虑二分后如何 check. \(n\) 个点 \(n\) 条边,显然这是一个基环树森林.对于基环树,常用的套路是拆环为链,枚举删去哪条边.但这题 ...
- CF1037G A Game on Strings Sol
有趣题. 首先"分成若干个互不相干的子串"是子游戏的定义,可以用 SG 函数处理. 然而接下来试着打了半个多小时的表,没有找到任何规律. 但是发现 SG 函数的状态转移是很简单的. ...