插入排序的基本思想是:对一个数组,从第二个元素起,每次将一个元素插入到前面已经排序的序列中。常见的插入排序法有:直接插入排序,二分法插入排序和希尔排序。
这里简要介绍下希尔排序。希尔排序基本思想是分组的直接插入排序。分组的元素个数(叫增量)这里采用减半增量,即第一趟排序每组个数为数组长度一半,第二次减半,直到最后为1.注意每组元素间隔增量的是一组。为便于理解,可以认为将全部元素排成行列式(类似于MATLAB里的reshape函数),然后同列的排序,完成后再恢复,完成一趟排序。示例如下:(这里增量用delta表示)
原数组: 38 55 65 97 27 76 27 13 19
第一趟delta=4,变为行列式: 38 55 65 97 按列排序后变为: 19 55 27 13
27 76 27 13 27 76 65 97
19 38
第二趟delta=2,变为行列式: 38 55 按列排序后变为: 19 13
65 97 27 55
27 76 27 76
27 13 38 97
19 65
第三趟delta=1;此时就是一次直接插入排序,对 19 13 27 55 27 76 38 97 65 直接插入排序得到:13 19 27 27 38 55 65 76 97。排序结束。
下面是直接插入排序和希尔排序的Java代码,代码有一些辅助函数
import java.util.Random;
public class insertSort {
public static int[] RandomInt(int size,int bound)
{
int[] array=new int[size];
Random rm=new Random();
for(int i=0;i<size;i++)
array[i]=rm.nextInt(bound);
return array;
}
static void print(int[] a)
{
for(int ele:a)
System.out.print(ele+" ");
System.out.println();
}
public static void sort(int[] array)
{
for(int i=1;i<array.length;i++)
{
int tmp=array[i],j;
for( j=i-1;j>=0 && array[j]>tmp;j--)
array[j+1]=array[j];
array[j+1]=tmp;
System.out.println("第"+i+"趟 temp="+tmp+"\t");
print(array);
}
}
static void shellSort(int[] array)
{
for(int delta=array.length/2;delta>0;delta/=2)
{
for(int i=delta;i<array.length;i++)
{
int tmp=array[i],j;
for( j=i-delta;j>=0 && tmp<array[j];j-=delta)
array[j+delta]=array[j];
array[j+delta]=tmp;
}
System.out.println("delta:"+delta);
print(array);
}
}
public static void main(String[] args)
{
int[] array=insertSort.RandomInt(7, 30);
//int[] array={38,55,65,97,27,76,27,13,19};
System.out.println("原始数组:");
insertSort.print(array);
insertSort.shellSort(array);
}
}