三向切分的快速排序算法:有大量重复元素的快速排序

在之前的《快速排序及改进》中,已经对快速排序做了改进;但是在实际的工作环境中,经常会遇到含有大量重复元素的数组,也经常会对这样的数组排序,对这样的数组排序,快速排序性能还可以,但是可以有更大的性能改进,将快速排序的的时间复杂度有对数级提高到线性级别。
[b]三向切分的快速排序是对快速排序算法改进,特别适用于有大量重复元素的数组的排序,其时间复杂度介于N - NlogN之间,最好的时间复杂度接近于O(N),在没有重复元素的情况下有最坏的时间复杂度,空间复杂度为lgN。[/b]
[b]三向切分的快速排序算法在包括重复元素很多的情况下,要比归并排序和其他排序方法有更好的性能。[/b]
三向切分的快速排序的过程是这样的:从左到右遍历数组一次,维护一个指针lt使得a[lo ... lt - 1]中的元素都小于v,一个指针gt使得a[gt + 1 ... hi]中的元素都大于v,一个指针使得a[lt...i - 1]中的元素都等于v,a[i ... gt]中的元素都还不确定,如下图所示:
[img]http://dl.iteye.com/upload/attachment/0084/1756/a0738e90-7bfb-30f1-9521-981c2114b641.jpg[/img]
一开始i = lo,使用Comparable接口对a[i]进行三向比较处理:
1)、a[i]小于v,将a[lt]和a[i]交换,然后将lt和i加一;
2)、a[i]大于v,将a[gt]和a[i]交换,然后将gt减一;
3)、a[i]等于v,然后将i加一;
除非和切分元素相等,其他元素都会被交换。全部代码如下:

/**
* 三向切分的快速排序算法:有大量重复元素的快速排序
* @author jacky
*
*/
public class Quick3waySort extends SortBase{

public static void sort(Comparable[] a){
//为获得接近于最好的排序性能(最好的时间复杂度),首先将原数组“洗牌"
shuffle(a);
//开始排序
sort(a,0,a.length - 1);
}

/**
* 三向切分的快速排序实现
* @param a
* @param lo
* @param hi
*/
private static void sort(Comparable[] a,int lo,int hi){
if(hi <= lo) return;
int lt = lo;
int i = lo + 1;
int gt = hi;
Comparable v = a[lo];
int cmp = 0;
while(i <= gt){
cmp = a[i].compareTo(v);
if(cmp < 0){
exch(a,lt++,i++);
}else if(cmp > 0){
exch(a,i,gt--);
}else{
i++;
}
}//现在a[lo ... lt - 1] < v = a[lt ... gt] < a[gt + 1 ... hi]成立
sort(a,lo,lt - 1);
sort(a,gt + 1,hi);
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值