在处理排序问题中,效率最高的当属快排,然而当待排序数据中存在大量重复元素时,快速排序无法发挥其优势,我们往往采用三路快排。
为了能更好的理解下面的代码,附上排序过程图,如下:
程序如下:
package com.haobi;
import java.util.Scanner;
/*
* 三路快排
*
* 针对的问题:对于快速排序,如果排序的数组中有很多重复的数,由于快速排序的判定问题,会导致这些重复数移到一边从而大幅增加算法的运算时间。
* 解决的方法:三路排序,分层 > = <,将数据分为3块,分别为>、=、<,分别在<和>中递归调用排序方法
*/
public class QuickSort3 {
public static void main(String[] args) {
//输入待排序的数字,以空格间隔
Scanner sc = new Scanner(System.in);
String string = sc.nextLine();
//将数字存入字符数组
String[] str = string.split(" ");
//字符数组转为int数组
int[] a = new int[str.length];
for(int i=0;i<str.length;i++) {
a[i] = Integer.parseInt(str[i]);
}
QuickSort3.sort(a, 0, a.length-1);
for(int i=0;i<str.length;i++) {
System.out.print(a[i] + " ");
}
sc.close();
}
/*
* 三路排序
*
* 数据划分结果如下:
* (start,ss)(key及与其相等的数)(ee,end)
*/
public static void sort(int[] a, int start, int end) {
if(start > end) {
return;
}
//ss表示<key部分的上界
int ss = start;
//ee表示>key部分的下界
int ee = end;
//i表示=key的上界
int i = start;
//取数组第一个元素作为key
int key = a[start];
//从=key的上界开始直到>key部分的下界ee,当二者相等时表示已经排好序
int temp = 0;
while(i <= ee) {
//如果当前数组元素值小于key,
if(a[i] < key) {
temp = a[i];
a[i] = a[ss];
a[ss] = temp;
i++;
ss++;
}else if(a[i] > key) {
//如果当前数组元素大于key,
temp = a[i];
a[i] = a[ee];
a[ee] = temp;
ee--;
}else {
//如果当前数组元素等于key,留在中间的部分
//i表示=key的上界
i++;
}
}
}
}