刚开始的时候,把左面的第一个数当作是有序的,把从第二个数为起始,以最后一个数为终止,作为无序的,此时数组分为有序和无序的两个小数组
因为默认左面的第一个是有序的,所以i从1开始
public static int[] insertionSort(int[] a){
int length=a.length;
for(int i=1;i<length;i++){
for(int j=i;j>0;j--){
if(a[j]<a[j-1]){
int temp=a[j];
a[j]=a[j-1];
a[j-1]=temp;
}
}
}
return a;
}
插入排序和冒泡排序的区别:两种排序都是双层for循环,外层for循环都是为了确定遍历多少趟会让数组有序,都代表数组中有序的数的个数(但是两种排序的表达方式不同),都在内层for循环中做数字交换,其不同点在于两层for循环的()内,插入排序的外层for循环从i=1开始(因为在数组中,他默认a[0]为一个有序的小数组),循环到最后;内层for循环代表的是无序数组中的某一个数,需要在有序数组中遍历多少次(也就是判断条件:j>i),比如:有序数组中只有一个数,那么这个无序数组中的这个数只需要遍历一次。而冒泡排序,内层for循环的判断条件是j<length-1-i,其中length-1-i的目的是判断数组中还有多少数是无序的(而i恰恰对应的是有序的个数),然后比较两两比较连续的无序数组的数。
总的来说,插入排序是把无序的数插入到有序的数组中进行比较,找到无序的数在有序数组中最合适的位置,而冒泡排序刚开始的时候都是无序的,后面开始有序,但是冒泡排序只能在有序数组的边界插入;且着重点不同,插入排序是把无序的数和有序的数比较,并把这个无序的数存放到有序数组中最适合他的位置;而冒泡排序是把无序的数进行比较,每次找到一个最值,把此最值存放到有序数组的边缘上。
优化
每次替换都要定义一个temp赋值需要插入的数,这样会造成不必要的浪费,通过在外层for循环中定义一个temp,然后在内层for循环中增加一个判断,如果temp比他前面的数小,则让前面的数覆盖掉temp数组所在的位置,然后j–(此时数组中有两个数都是a[j-1]),然后进行下一轮内层for循环的判断,若不满足判断条件则把temp赋值给此时的j(也就是上一次for循环的j-1),类似于快速排序的挖坑法。
public static int[] insertionSort(int[] a){
int length=a.length;
for(int i=1;i<length;i++){
int j;
int temp=a[i];
for(j=i;j>0&&a[j-1]>temp;j--){
a[j]=a[j-1];
}
a[j]=temp;
}
return a;
}