算法描述
- 普通MSD算法每层递归会创建count[R+2],其中大部分都是空数组.而三项切分字符串快排,根据键的首字母v,切分成首字符小于v,等于v,大于v三部分,仅在首字符等于v的子数组中对下一个字符再次三向切分,其余两部分继续对首字符三向切分
实现
public class Quick3string {
private static int charAt(String s, int d){
if (d < s.length()) return s.charAt(d);
else return -1;
}
public static void sort(String[] a){
sort(a, 0, a.length-1, 0);
}
private static void exch(String[] a, int v, int w){
String temp = a[v];
a[v] = a[w];
a[w] = temp;
}
private static void sort(String[] a, int lo, int hi, int d){
if (lo >= hi) return;
int lt = lo, gt = hi;
int v = charAt(a[lo], d);//枢轴
int i = lo + 1;
while (i <= gt){
int t = charAt(a[i], d);
if (t > v) exch(a, lt++, i++);
else if (t < v) exch(a, i, gt--);
else i++;
}
sort(a, lo, lt-1, d);
if (v > 0) sort(a, lt, gt, d+1);//空子数组,不进行递归
sort(a, gt+1, hi, d);
}
}
示例
算法分析
- 当字符串很长但长度相同,且前面大部分字符相同时
- 标准快排:~w2NlnN
- 三向切分: wN+2NlnN
证明:三向切分中发现相同开头字母需要花wN,而对剩下部分的比较需2NlnN次比较