优点
三向字符串快速排序只将数组切分为三部分,因此当相应的高位优先的字符串排序产生的非空切分较多时,它需要移动的数据量就会变大,因为它需要进行一系列的三向切分才能取得多向切分的效果。但是,高位优先的字符串排序可能会创建大量(空)子数组,而三向字符串快速排序的切分问题只有三个。因此三向字符串快速排序能够很好处理等值键、有较长公共前缀的键,取值范围较小和键和小数组——所有高位优先的字符串排序算法不善长的情况。
代码
package algorithm.string;
import algorithm.SortUtil;
/**
* 描述:三向字符串快速排序
* Created by zjw on 2021/8/29 15:16
*/
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 sort(String[] a, int lo, int hi, int d) {
if (hi <= lo) 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);
}
private static void exch(Comparable[] a, int i, int j) {
Comparable t = a[i];
a[i] = a[j];
a[j] = t;
}
}
各字符排序算法的性能特点
在将基于大小的R的字母表的N个字符串排序过程中调用charAt()方法次数的增长数量级(平均长度为w,最大长度为W)
算法 | 是否稳定 | 原地排序 | 运行时间 | 额外空间 | 优势领域 |
---|---|---|---|---|---|
字符串的插入排序 | 是 | 是 | N到N^2之间 | 1 | 小数组或是已经有序的数组 |
快速排序 | 否 | 是 | Nlog^2N | logN | 通用排序算法,特别适合用于空间不足的情况 |
归并排序 | 是 | 否 | Nlog^2N | N | 稳定的通用排序算法 |
三向快速排序 | 否 | 是 | N到NlogN之间 | logN | 大量重复键 |
低位优先的字符串排序 | 是 | 否 | NW | N | 较短的定长字符串 |
高位优先的字符串排序 | 是 | 否 | N到Nw之间 | N+WR | 随机字符串 |
三向字符串快速排序 | 否 | 是 | N到Nw之间 | W+logN | 通用排序算法,特别适合用于含有较长公共前缀的字符串 |