package com.prince.algorithm;
/**
* shell排序的思想是使数组中任意间隔为h的元素都是有序的,是在插入排序的基础
* 上进行的改进,一开始h很大,使得元素可以移动到很远的位置,成为局部有序。
* 然后h递减最终为1,成为了传统意义上的插入排序,区别是已经存在了很多局部有序
* 的小数组。
* 排序之初,各个子数组都很短,排序之后子数组都是部分有序的,因此很适合插入排序
* @author Administrator
*
*/
public class ShellSort {
public static void sort(Comparable[] a) {
//将a[]按升序排列
int N = a.length;
int h = 1;
//为了让h从[1,N/3)递减
while(h<N/3) h=3*h+1; //1,4,13,40,121,364..之中
while(h>=1) {
//将数组变为h有序
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 = 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) {
//在单行中打印数组
for(Comparable temp:a) {
System.out.println(temp);
}
}
public static boolean isSorted(Comparable[] a){
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) {
String[] a = {"aa","ab","dd","ad","abc"};
sort(a);
assert isSorted(a);
show(a);
}
}