很多时候排序是为了对数据进行归类,比如对城市进行排序,对员工的职业进行排序。这种排序的特点就是重复的值特别多。
如果使用普通的快排对这些数据进行排序,会造成N^2复杂度,但是归并排序和三路快排就没有这样的问题。
三路快排的基本思想就是,在对数据进行分区的时候分成左中右三个部分,中间都是相同的值,左侧小于中间,右侧大于中间。
三路快排的复杂度比普通快排小,主要取决于数据中重复数据的数量。重复数据越多,三路快排的复杂度就越接近于N。
public class Quick3 {
public static void sort(Comparable[] a) {
Shuffle.shuffle(a);
sort(a, 0, a.length);
}
public static void sort(Comparable[] a, int lo, int hi) {
// 如果数组长度为0,直接返回
if(lo >= hi) {
return;
}
// 将第一个元素作为分区依据
Comparable mid = a[lo];
// 对数组进行扫描,分区
int lt = lo;
int gt = hi-1;
int i = lo;
while(true) {
// 指针发生了交叉,退出循环
if(i > gt) { // 注意,这里不是i >= gt,i=gt的时候仍然需要排序
break;
}
int cmp = a[i].compareTo(mid); // 注意,这里不要用SortUtil.less
if(cmp < 0) {
SortUtil.exch(a,lt,i);
lt++;
i++;
} else if(cmp > 0) {
SortUtil.exch(a,gt,i);
gt--;
} else {
// 跳过等值的情况。这就是为什么三路快排适合排序等值多的数组
i++;
}
}
// 迭代排序
sort(a,lo,lt);
sort(a,gt+1,hi);
}
}普林斯顿公开课 算法3-3:三路快排,布布扣,bubuko.com
原文:http://blog.csdn.net/caipeichao2/article/details/28898873