1. 程式人生 > >字串之————三向字串快速排序(Quick3string)

字串之————三向字串快速排序(Quick3string)

上一篇介紹了字串的兩種經典排序方法(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 } 

&n