希爾排序(Shell Sort)是插入排序]的一種。也稱縮小增量排序,是直接插入排序算法的一種更高效的改進(jìn)版本顺饮。希爾排序是非穩(wěn)定排序算法。
希爾排序是把記錄按下標(biāo)的一定增量分組誊册,對(duì)每組使用直接插入排序算法排序领突;隨著增量逐漸減少,每組包含的關(guān)鍵詞越來越多案怯,當(dāng)增量減至1時(shí)君旦,整個(gè)文件恰被分成一組,算法便終止嘲碱。
先取一個(gè)小于n的整數(shù)d1作為第一個(gè)增量金砍,把文件的全部記錄分組。所有距離為d1的倍數(shù)的記錄放在同一個(gè)組中麦锯。先在各組內(nèi)進(jìn)行直接插入排序恕稠;然后,取第二個(gè)增量d2<d1重復(fù)上述的分組和排序扶欣,直至所取的增量=1鹅巍,即所有記錄放在同一組中進(jìn)行直接插入排序?yàn)橹埂?/p>
該方法實(shí)質(zhì)上是一種分組插入方法
比較相隔較遠(yuǎn)距離(稱為增量的數(shù),使得數(shù)移動(dòng)時(shí)能跨過多個(gè)元素料祠,則進(jìn)行一次比較就可能消除多個(gè)元素交換骆捧。
其算法的Java代碼如下:
import java.util.Scanner;
public class ShellSort {
//希爾排序算法
public static void sort(Comparable[] a){
//將a[]按升序排列
int N = a.length;
int h = 1;
while(h < N/3){
h = 3*h+1;//1,4,13,40,121,364,1093,...
}
while(h > 1){
//將數(shù)組變?yōu)閔有序
for(int i=h; i<N; i++){
//將a[i]插入到a[i-h],a[i-2*h],a[i-3*h]...之中
for(int j=i; j>=h && less(a[j],a[j-h]); j-=h ){
exch(a,j,j-h);
}
}
h /= 3;
}
}
private static boolean less(Comparable v,Comparable w){
return v.compareTo(w) < 0;
}
private static void exch(Comparable[] a,int i,int j){
Comparable t = a[i];
a[i] = a[j];
a[j] = t;
}
private static void show(Comparable[] a){
//在單行打印數(shù)組
for(int i=0; i<a.length; i++){
System.out.print(a[i] + " ");
}
}
public static boolean isSorted(Comparable[] a){
//測(cè)試數(shù)組是否有序
for(int i=1; i<a.length; i++){
if(less(a[i],a[i-1])){
return false;
}
}
return true;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
//從標(biāo)準(zhǔn)輸入讀取字符串,將它們排序并輸出
Scanner scan = new Scanner(System.in);
String str = scan.nextLine();
Comparable[] a = new Comparable[str.length()];
for(int i=0; i<str.length(); i++){
a[i] = str.charAt(i);
}
sort(a);
assert isSorted(a);
show(a);
}
}