插入排序算法思路
给定一个无续的数组,对其进行排序,思路如下
相当于用两个数组进行排序,一个是无序的,一个是有序的,每次从无序数组中拿出一个数,与有序的数组中的数进行比较,确定插入的位置后插在有序数组中,最后输出有序数组即可:
- 首先从无序数组中取出第一个数直接放在有序数组中,放到第一个位置。
- 然后从无序数组中拿出第二个数,先与有序数组中的数进行比较,如果此数较大,则放在有序数组中那个数的后面,如果此数小,则放在前面
- 从无序数组中取出取出第三个数,与有序数组中的数进行比较,确定存放的位置后,进行插入。
- 以此类推。。。
插入算法粗暴实现
package com.njupt.Algorithm.insert;
import java.util.Arrays;
/**
* Creat with IntelliJ IDEA
*
* @Auther:倔强的加瓦
* @Date:2021/07/18/18:12
* @Description:
*/
public class Insert {
public static void main(String[] args) {
int[] arr = {101, 34, 119, 1};
insertMethod(arr);
}
//插入排序
public static void insertMethod(int[] arr) {
//第一轮,先从无序数组中取出第2个数与有序数组中的比较
int insertVal = arr[1];
int insertIndex = 1 - 1;
//当取出的数小于有序数组中的那个数则进行交换
while (insertIndex >= 0 && insertVal < arr[insertIndex]) {
//如果无序数组中那个数更小,则需要将有序数组中的数往后移动一位,空出来给要插入的那个数
arr[insertIndex + 1] = arr[insertIndex];
//一直向前比较,调整插入的位置
insertIndex--;
}
//确定好插入的位置后,开始插入数据
arr[insertIndex + 1] = insertVal;
System.out.println("第一轮输出");
System.out.println(Arrays.toString(arr));
//第2轮,应该拿出无序数组中的第三个数到有序数组中比较
insertVal = arr[2];
//假设要插入的数插入的位置
insertIndex = 2 - 1;
//如果有序数组中要插入元素的位置的数大于拿出来的那个数,则将要插入位置的数后移一位
while (insertIndex >= 0 && insertVal < arr[insertIndex]) {
arr[insertIndex + 1] = arr[insertIndex];
//调整要插入的位置
insertIndex--;
}
//找到要插入位置后,将要插入的数插入即可
arr[insertIndex + 1] = insertVal;
System.out.println("第2轮输出");
System.out.println(Arrays.toString(arr));
//第3轮
//从无序数组中取出第四个数,拿出来与有序数组中的数进行比较
insertVal = arr[3];
//假设要插入有序数组中的位置
insertIndex = 3 - 1;
//如果新数组中要插入位置的数大于拿出来的数,则需要将新数组的数后移,给插入的数腾位置
while (insertIndex >= 0 && insertVal < arr[insertIndex]) {
arr[insertIndex + 1] = arr[insertIndex];
insertIndex--;
}
arr[insertIndex + 1] = insertVal;
System.out.println("第3轮输出");
System.out.println(Arrays.toString(arr));
}
}
测试结果:
第一轮输出
[34, 101, 119, 1]
第2轮输出
[34, 101, 119, 1]
第3轮输出
[1, 34, 101, 119]
Process finished with exit code 0
真正的插入算法
package com.njupt.Algorithm.insert;
import java.util.Arrays;
/**
* Creat with IntelliJ IDEA
*
* @Auther:倔强的加瓦
* @Date:2021/07/18/19:25
* @Description:
*/
public class RealInsert {
public static void main(String[] args) {
int[] arr = {101, 34, 119, 1};
insertMethod(arr);
}
public static void insertMethod(int[] arr) {
//需要比较n-1次
for (int i = 1; i < arr.length; i++) {
int insertVal = arr[i];
int insertIndex = i - 1;
while (insertIndex >= 0 && insertVal < arr[insertIndex]) {
arr[insertIndex + 1] = arr[insertIndex];
insertIndex--;
}
//需要优化的地方
arr[insertIndex + 1] = insertVal;
System.out.println("第" + (i) + "轮输入");
System.out.println(Arrays.toString(arr));
}
}
}
第1轮输出
[34, 101, 119, 1]
第2轮输出
[34, 101, 119, 1]
第3轮输出
[1, 34, 101, 119]
存在的问题:当判断出要插入新数组的位置时,如果恰好就是假设的插入位置时,不需要在进行插数操作,直接进行下一次取数判断即可。
插入排序算法的优化
package com.njupt.Algorithm.insert;
import java.util.Arrays;
/**
* Creat with IntelliJ IDEA
*
* @Auther:倔强的加瓦
* @Date:2021/07/18/19:39
* @Description:
*/
public class BetterInsert {
public static void main(String[] args) {
int[] arr = {101, 34, 119, 1};
insertMethod(arr);
}
public static void insertMethod(int[] arr) {
for (int i = 1; i < arr.length; i++) {
int insertVal = arr[i];
int insertIndex = i - 1;
while (insertIndex >= 0 && insertVal < arr[insertIndex]) {
arr[insertIndex + 1] = arr[insertIndex];
insertIndex--;
}
if (insertIndex + 1 != i) {
arr[insertIndex + 1] = insertVal;
System.out.println("第" + i + "轮输出");
System.out.println(Arrays.toString(arr));
} else {
System.out.println("第" + i + "轮不需要位置,直接放到假设的位置即可");
System.out.println(Arrays.toString(arr));
}
}
}
}
测试代码:
第1轮输出
[34, 101, 119, 1]
第2轮不需要找位置,直接放到假设的位置即可
[34, 101, 119, 1]
第3轮输出
[1, 34, 101, 119]
Process finished with exit code 0