一、什么是插入排序?
我的理解:将元素分为两组,已经排序的和没有排序的,用没有排序的第一个元素与已经排序的元素进行比较(从已排序的最后一个元素开始比较,倒序比较),如果小于已经排序的数,则互换位置,继续比较,遇到大于,则直接推出循环,这个退出循环和之前的冒泡排序和选择排序是不同的,因为冒泡排序和选择排序必须一直循环到最后或者最前一个元素。
二、Java算法实现
import java.lang.reflect.Array;
import java.util.Arrays;
/**
* 插入排序需要实现的方法包括:
* 1--比较元素大小
* 2--互换位置
* 3--排序,先比较大小,再考虑是否互换位置
*/
//实现Comparable接口
class InsertSort {
//比较算法,如果大于零,表示a比b大.
// 注意Comparable接口类型可能让人能疑惑,
// 请记住父类接口指向子类实例,就懂了,类/接口是可以作为类型的
public static boolean comparing(Comparable a,Comparable b){
return a.compareTo(b)>0;
}
//交换算法,要有一个临时变量进行传递
public static void exchange(Comparable[]arr,int i,int j){
Comparable temp;
temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
//排序
public static void sort(Comparable[]arr){
// 第一层循环,确定第一个未排序元素
for (int i=1;i<arr.length;i++){
// 第二层循环,确定要和多少已经排序的元素进行比较
//关于这两层循环的理解可参考下面的第三部分内容
for (int j=i;j>0;j--){
//如果arr[j-1]>arr[j]
if(comparing(arr[j-1],arr[j])){
//交换数据
exchange(arr,j-1,j);
}
//否则,代表循序正确,可以退出循环
else{
break;
}
}
}
}
}
public class Test{
public static void main(String[] args) {
// 定义一个数组
Integer[]arr={6,5,4,7,1,70,9,0};
System.out.println("排序前的数组:"+Arrays.toString(arr));
// 调用方法,注意是静态方法,可以这样调用
InsertSort.sort(arr);
System.out.println("排序前的数组:"+Arrays.toString(arr));
}
}
结果:
三、插入排序两层循环的理解
1、内层循环
先从内层循环开始理解,内层循环就是我们每次插入排序的情况,假设我们现在处于第五趟排序处,这个时候第一个未排序元素的索引为5,进行循环就是要将这个元素与之前的已经排序了的5个元素进行比较,其实需要比较5次,因此此时的内层循环是for (int j=5;j>0;j–),这里需要注意,这里的5是会随着排序次数而变化的,这就和外层循环有关了。
2、外层循环
外层循环表示插入排序的次数,第一次排序的时候未排序的第一个数的索引应该为1,也就是第二个数,第二次排序的时候索引应该为2,也就是第三个数,一直会到最后一个数,也就是为n-1,n个元素的数组一共需要排序多少次呢?答案就是n-1次,所以外层循环应该为 for (int i=1;i<arr.length;i++),此时内层循环就变为了for (int j=i;j>0;j–)。