插入思想:
把n个待排序的元素看成一个有序表和一个无序表
开始时有序表中只有一个元素,无序表中有n-1个元素
排序过程中每次从无序表中取出第一个元素,
依次和有序表中的元素比较,将他插入到合适的位置
思路图:
代码1-分解步骤:
public class InsertSort {
public static void main(String[] args) {
int[] arr={101,34,119,1};
insertSort2(arr);
}
//插入排序
public static void insertSort(int arr[]){
//使用逐步推导
//第一轮:{101,34,119,1} ==> {34,101,119,1}
/**
因为这4个数 把101看成一个有序表,"34,119,1"看成另一个无序表
每次都把无序表表中的第一个元素一有序表中最后一个数字比较
也就是从后面无序表中取出的数(第一个位置的数) 插入到前面的有序表中
*/
//定义待插入的数
int insertVal = arr[1];//存储的是34的值
int preInsertIndex = 1-1;//即arr[1]前面的那个数的下标
//给insertVal找到插入的位置
//preInsertIndex >=0 保证再给insertVal找到插入位置,不越界
//insertVal < arr[preInsertIndex] 说明待插入的数还没有找到插入位置
//就需要将 arr[preInsertIndex] 后移 ,腾出位置让34插入进去
while (preInsertIndex >=0 && insertVal < arr[preInsertIndex]){
/**
* 将arr[preInsertIndex] 后移
* 即:{101,34,119,1} ==> {101,101,119,1}
* 34 这个数 弄丢了?并没有,被我保存在了int insertVal=arr[1]变量
*/
arr[preInsertIndex+1]=arr[preInsertIndex];
preInsertIndex--;//减减是因为34这个数要跟101前面的数字比较
}
arr[preInsertIndex+1]= insertVal;
/**
* 当退出while循环时候:说明插入的位置找到了:就是preInsertIndex+1这个位置
* 为什么是preInsertIndex+1这个位置?
* 举个例子:
* {101,334,119,1}
* 先把334放在 int insertVal = arr[1]这个位置
* 又因为int preInsertIndex = 1-1
* 334一进入while循环 就不满足这个条件:insertVal < arr[preInsertIndex]
* 不满足直接就退出
* 那么334就应该在preInsertIndex+1这个位置,
* 因为刚开始就把preInsertIndex赋值为0了
* 上述可以debug来看看流程
*/
System.out.println("第1轮后:"+ Arrays.toString(arr));
//第2轮
insertVal = arr[2];//存储的是119的值
preInsertIndex = 2-1;//即arr[2]前面的那个数的下标
while (preInsertIndex >=0 && insertVal < arr[preInsertIndex]){
arr[preInsertIndex+1]=arr[preInsertIndex];
preInsertIndex--;
}
arr[preInsertIndex+1]= insertVal;
System.out.println("第2轮后:"+ Arrays.toString(arr));
//第3轮
insertVal = arr[3];//存储的是119的值
preInsertIndex = 3-1;//即arr[2]前面的那个数的下标
while (preInsertIndex >=0 && insertVal < arr[preInsertIndex]){
arr[preInsertIndex+1]=arr[preInsertIndex];
preInsertIndex--;
}
arr[preInsertIndex+1]= insertVal;
System.out.println("第3轮后:"+ Arrays.toString(arr));
}
}
// 上诉代码合并为最后总的排序方法:
public static void insertSort2(int arr[]){
//使用for循环来把上诉代码简化
for(int i=1;i<arr.length;i++) {
//定义待插入的数
int insertVal = arr[i];
int preInsertIndex = i - 1;
while (preInsertIndex >= 0 && insertVal < arr[preInsertIndex]) {
//insertVal > arr[preInsertIndex] 就变成从大到小了
arr[preInsertIndex + 1] = arr[preInsertIndex];
preInsertIndex--;
}
//优化一下:这里我们判断一下是否需要赋值
//
if(preInsertIndex+1!=i){
arr[preInsertIndex + 1] = insertVal;
}
}
}
代码2:
public static void InsertSort3(int A[]) {
int i, j, temp;
for (i = 1; i < A.length; i++) {
temp = A[i];//临时变量保存
for (j = i; j >0 && A[j - 1] > temp; j--) {
A[j] = A[j - 1];//移出空为
}
A[j]=temp;//还原值
}
}
结束语:
路漫漫其修远兮 吾将上下而求索