谢谢真实的归宿http://blog.youkuaiyun.com/hguisu/article/details/7776068
虽然以下代码是抄他的,但是我改成了java版本的,跟他并不一样。并且我有修复它里面一些bug。
插入排序(直接插入排序VS希尔排序)
public class SortTest {
public static long sum = 0;
static void print(int a[],int i){
System.out.print(i + ":");
for(int j= 0; j<8; j++){
System.out.print(a[j] + " ");
}
System.out.println();
}
static void insertSort(int a[], int n)
{
for(int i= 1; i<n; i++){
if(a[i] < a[i-1]){ //若第i个元素大于i-1元素,直接插入。小于的话,移动有序表后插入
int j= i-1;
int x = a[i]; //复制为哨兵,即存储待排序元素
a[i] = a[i-1]; //先后移一个元素
System.out.println();
System.out.println(++sum);
while(j>=0 && x < a[j]){ //查找在有序表的插入位置
a[j+1] = a[j];
System.out.println(++sum);
j--; //元素后移
}
a[j+1] = x; //插入到正确位置
}
print(a,i); //打印每趟排序的结果
}
}
/**
* 先按增量d(n/2,n为要排序数的个数进行希尔排序
*
*/
static void shellSort(int a[], int n){
int dk = n/2;
while( dk >= 1 ){
shellInsertSort(a, n, dk);
dk = dk/2;
}
}
/**
* 直接插入排序的一般形式
*
* @param a
* @param n
* @param dk 缩小增量,如果是直接插入排序,dk=1
*/
static void shellInsertSort(int a[], int n, int dk)
{
for(int i= dk; i<n; ++i){
if(a[i] < a[i-dk]){ //若第i个元素大于i-1元素,直接插入。小于的话,移动有序表后插入
int j = i-dk;
int x = a[i]; //复制为哨兵,即存储待排序元素
a[i] = a[i-dk]; //首先后移一个元素
System.out.println();
System.out.println(++sum);
while(j>=0 && x < a[j]){ //查找在有序表的插入位置
a[j+dk] = a[j];
System.out.println(++sum);
j -= dk; //元素后移
}
a[j+dk] = x; //插入到正确位置
}
print(a,i );
}
}
public static void main(String args[]){
int a[] = {49,38,65,97,76,13,27,49};
// insertSort(a,8);
shellSort(a,8);
//print(a,8);
}
}
可以看到以上结果中,直接插入排序移动元素20次,而希尔排序移动元素18次。
所以希尔排序果然更好一点。