插入排序的基本思想是:每步将一个待排序的记录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直到全部插入完为止。
算法适用于少量数据的排序,时间复杂度为O(n^2)
遍历一个数组,每次遍历一个数的时候,和前边的数判断,如果比前边的数小就和前边的数交换,这样直到满足条件即可。
下边我们看一下具体代码的实现
public class InsertSort {
public static void sort(Comparable[] arr){
//遍历这个数组
for (int i = 1;i<arr.length;i++){
//循环判断每个元素和前边的值
for (int j = i;j > 0;j--){
if (arr[j].compareTo(arr[j-1])<0){
swap1(arr,j-1,j);
}
}
}
}
public static void swap1(Object[] arr,int i, int j){
Object temp;
temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
}
public static void main(String[] args) {
int n = 10000;
Comparable[] arr = selectSort.generateRandomArray(n,0,n);
long startTime = System.currentTimeMillis();
InsertSort.sort(arr);
long endTime = System.currentTimeMillis();
System.out.println("插入排序时差:"+(endTime-startTime));
}
}
我们观察一下这个代码,在swap中每次交换都要做三步替代,那么这种数据小的话还可以接受,如果数据量很大的话应该可想而知是有多浪费时间的了。那么我们在这一块尽量优化一下。
大家想一下,我们可以把要遍历比较的数e先取出来,然后跟前边的比较,但是并不进行交换操作,而是直接把前边的值往后挪,当符合条件的时候就把e放到这个往后挪之后的元素地址这儿。
这样的话我们就减少了两步,数据量大的情况话速度就可想而知了
//改进版
public static void strong_sort(Comparable[] arr){
for (int i = 1;i<arr.length;i++){
Comparable e = arr[i];
int j;
for (j = i;j > 0 && arr[j-1].compareTo(e) > 0 ;j--){
arr[j] = arr[j-1];
}
arr[j] = e;
}
}
测试结果如下
这个差距确实不小的