插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,算法时间复杂度为O(n ^ 2),虽然时间复杂度为O(n ^ 2),但对于近乎有序的数组,时间效率会得到极大的提升,插入排序一般用于小数据量数组或者应用于近乎有序的数组,可以用于归并排序和快速排序的优化。
以下是插入排序具体实现过程
public class InsertSort {
public void insertSort(int[] arr, int n) {
//从1索引元素开始,0元素位置只有一个元素已经有序
for(int i = 1; i < n; i++) {
int e = arr[i];//保存当前元素
int j; //内层循环控制变量
//将当前元素与前面有序数据进行比较,如果比前面元素小,则进入循环
for( j = i; j > 0 && arr[j -1] > e; j--)
//将前面大的元素往后复制,即所谓的往后挪动一下
arr[j] = arr[j -1];
//循环结束此时的j就是当前元素需要插入的位置
arr[j] = e;
}
}
//插入排序方法重载,主要针对数组中一个区间数据进行排序
public void insertSort(int arr[], int l, int r){
for( int i = l + 1 ; i <= r ; i ++ ) {
int e = arr[i];
int j;
for (j = i; j > l && arr[j-1] > e; j--)
arr[j] = arr[j-1];
arr[j] = e;
}
return;
}
}
以下是测试程序,首先是测试数据量为10000的随机随机数组和近乎有序的数组进行测试
import cn.zjut.util.SortTestUtil;
public class Main {
public static void main(String[] args){
int n = 10000;
System.out.println("Test for Random Array, size = " + n + ", random range [0, " + n + ']');
int[] arr1 = SortTestUtil.generateRandomArray(n, 0, n);
SortTestUtil.testSort("InsertSort", "cn.zjut.sort.InsertSort", "insertSort", arr1, n);
System.out.println("--------------------------------");
int swapTime = 10;
System.out.println("Test for Random Nearly Ordered Array, size = " + n + ", swap time = " + swapTime);
arr1 = SortTestUtil.generateNearlyOrderedArray(n, swapTime);
SortTestUtil.testSort("InsertSort", "cn.zjut.sort.InsertSort", "insertSort", arr1, n);
}
}
以下是测试结果
从结果可知,对于近乎有序的数组的排序插入排序的效率比随机数据的时间效率优化不在一个数量级
下面进行1000000数据量进行测试,只需将n进行修改,故不贴代码,下面是测试结果
对于一百万整型数据排序,对于随机数据插入排序消耗时间太大符合O(n ^ 2)排序算法特点,但对于近乎有序的数组,排序效果也挺快。
以上整过程就是插入排序整个过程,插入排序适用于小数据量或者数据较为有序的数组,在归并和快速排序的优化中会使用到插入排序。