插入排序的基本思想:每一趟将一个待排序元素,按其排序码大小插入到前面已经排好序的一组元素的适当位置上,直到所有待排序元素元素全部插入为止。在这里,这里介绍两种具体的插入排序算法:直接插入排序,希尔排序。
1、直接插入排序
直接插入排序的思想:当插入第i(i>=1)个元素时,前面的arr[0],…,arr[i-1]等i-1个 元素已经有序。这时,将第i个元素与前i-1个元素arr[i-1],…,arr[0]依次比较,找到插入位置即将arr[i]插入。插入位置的查找是顺序查找,从已经排好序列的最后一个数开始向前遍历,如果插入数小于当前数,就将当前数向后移动一位。。其实现如下:
public class InserSort {
public static int[] insertSort(int[] arr){
if(arr!=null&&arr.length>1){ //待排序数组不为空且长度大于1
for(int i=1;i<arr.length;i++){ //插入的次数
int temp=arr[i];//待插入元素
int j=i-1;//已经排好序的序列个数
while(j>=0&&temp<arr[j]){//序列从后向前遍历,将大于待插入数的元素向后移一位
arr[j+1]=arr[j];//元素向后移动一位
j--;
}
arr[j+1]=temp;
}
}
return arr;
}
}
2、希尔排序
希尔排序实质上是采用分组插入的方式,首先取一个整数gap<n作为间隔,将待排序序列分为间隔为gap的gap个子序列并对每一个子序列进行直接插入排序。然后,缩小间隔gap,重复上述操作,直至gap缩小为1,此时所有元素位于同一个序列且有序。由于刚开始时,gap较大,每个子序列元素较少,排序速度较快;待到排序后期,gap变小,每个子序列元素较多,但整个序列基本有序,所以排序速度仍较快。

图片来源于网络
public class ShellSort {
public static int[] shellSort(int[] target){
if(target != null && target.length != 1){
int gap = target.length;
while(gap > 1){ // 不断缩小gap直至为1
gap = gap/2; //gap个子数组
for (int i = 0 + gap; i < target.length; i++){ // 对每个子序列进行直接插入排序
if(target[i] < target[i-gap]){
int j = i - gap; //j为有序序列最后一位数
int temp = target[i]; // 待插入值
while(j >= 0 && target[j] > temp)// 从后向前遍历
{
target[j + gap] = target[j]; // 元素向后移动gap位
j = j - gap;
}
target[j + gap] = temp; // 将待插入值插入合适的位置
}
}
}
}
return target;
}
}