上一篇介绍了字符串的两种经典排序方法(LSD MSD): https://www.cnblogs.com/Unicron/p/11531111.html
在三向字符串快速排序中我们只需要改进一下快速排序的代码就能实现它,它特别适用于较长的含有公共前缀的字符串,并且不需要任何额外空间。代码比较简单,主要是理解它的思想。
一、核心思想
利用的分治的思想,通过中间字符串每次将字符串数组划分为三个小组。
再递归地对小组进行同样的处理,直到走到字符串末尾,最后形成的字符串数组自然有序。
二、具体做法:
1、用一个字符作为中间字符(本篇文章中默认选择字符串的第一个字符),比它大的移到字符串数组末尾,比它小的移到它前面。
这样遍历玩一遍后会形成三个小组,里面的字符串开头字母分别为,小于中间字符,等于中间字符,大于中间字符。
(需要注意的是,这里字符串的移动借助exch()方法,直接在字符串数组上进行字符串位置交换,而不需要借助额外的数组)
2、对分类的三个字符串数组逐一进行步骤1直到字符串中的字符全部遍历。最后形成的字符串自然有序。
三、实例演示
按照上面的步骤,我们来来对一个实例进行完整处理:
四、与LSD、MSD的对比
LSD中没有分组的概念,单纯从右到左对每个字符排序。
MSD加入了分组的概念,但对于每个分组也是从头到尾,由于每次排序都要创建辅助数组,在数组较长时将会用到很大的空间。
quick3string与两者不同的是不用额外申请空间,且对于存在大量相同前缀的字符串数组,它也能很好得处理。
五、完整代码
1 public class Quick3string {
2 private static int charAt(String s,int d){
3 if(d<s.length()){
4 return s.charAt(d);
5 }else{
6 return -1;
7 }
8 }
9
10 private static void exch(String [] s,int a,int b){
11 String temp=s[a];
12 s[a]=s[b];
13 s[b]=temp;
14 }
15
16 public static void sort(String[] a){
17 sort(a,0,a.length-1,0);
18 }
19
20 public static void sort(String[] a,int lo,int hi,int d){
21 if(hi<=lo){
22 return;
23 }
24 int lt=lo,gt=hi;
25 int v=charAt(a[lo],d);
26 int i=lo+1;
27 while(i<=hi){
28 int t=charAt(a[i],d);
29 if (t<v){
30 exch(a,lt++,i++);
31 }
32 else if (t>v){
33 exch(a,gt--,i);
34 }else {
35 i++;
36 }
37 }
38 sort(a,lo,lt-1,d);
39 if (v>=0){
40 sort(a,lt,gt,d+1);
41 }
42 sort(a,gt+1,hi,d);
43 }
44
45 }
知识兔