插入排序算法分为 直接插入排序法与希尔排序算法。下面看看这两种算法的代码实现和复杂度对比。
1、直接插入排序法(Straight Insertion Sort)
直接插入排序的基本操作是在排序刚开始的时候,把第一个元素当做是排序的记录,当依次插入后面的元素的时候,就获得其插入的位置,然后形成一个新的有序表。
package com.sort.exe;
import org.junit.Test;
/**
* 过程:57 59 68 52进行排序:
* i=3:temp=52
* ①j=i-1=2:68>52,68往前移一位:57 59 68 68
* ②j--: 59>52,59往前移一位:57 59 59 68
* ③j--: 57>52,52往前移一位,57 57 59 68
* ④temp放在最后的位置:52 57 59 68
* @author WGS
*/
public class InsertSort2 {
@Test
public void insertSort(int[] arrs){
int i,j,temp=0;
for(i=1;i<arrs.length;i++){
temp=arrs[i];
//后面的数大于前面的数,就将大于temp的值整体后移一个单位
//即拿temp(要插入的值)与其后每个值比较,若小于那个值就插入在那个位置+1;不小于就插在最后
for(j=i-1;j>=0 && temp<arrs[j];j--){
arrs[j+1]=arrs[j];
}
//j变成-1的时候,即最后一位比较完毕,此时temp放在最后
arrs[j+1]=temp;
}
}
//测试用例
@Test
public void test(){
int[] a={57,68,59,52};
insertSort(a);
for(int i=0;i<a.length;i++){
System.out.print(a[i]+" ");
}
}
}
算法复杂度
O(n2) -最差
O(n) - 基本有序 & 记录少的情况下
2、希尔排序法(Shell Sort)
希尔排序采用跳跃分割策略,将数组分割成记录更小的子数组。
即:将相聚某个增量的记录组成一个子序列,对子序列进行插入排序可以保证其为基本有序。
算法实现如下:
public void shellSort(int[] arrs) {
int inc = arrs.length, i, j, temp;
do {
for (i = inc; i< arrs.length; i++) {
temp = arrs[i];
for (j = i - inc; j >= 0 && arrs[j] > temp; j-= inc) {
arrs[j + inc] = arrs[j];
}
arrs[j + inc] = temp;
}
} while (inc > 1);
}
算法复杂度
O(n3/2) - 优于直接插入排序法。