插入排序是一种常见的排序算法,它主要包含直接插入排序、折半插入排序、希尔排序等几种常见的排序算法。
1.直接插入排序:
- 思想:将数组中的数据分为两个区间:有序区间和无序区间。每次取无序区间的一个元素与有序区间的元素进行比较,找到该元素合适的插入位置并插入;重复这个过程。直到无序区间没有元素,即排序完成。
- 注意:在进行元素比较的时候,无序区间的这个元素,要与有序区间的所有元素进行比较找到插入位置,此时是从后往前遍历。
- 代码实现:
package www.first;
import java.util.Scanner;
public class InsertSort {
public static void directInsertSort(int[] arr){
if(arr.length<=1||arr==null){
return;
}
//i为无序数组的第一个元素
for(int i = 1;i<arr.length;i++) {
//保存要比较的无序数组的第一个元素值
int value = arr[i];
//j为有序数组的最后一个元素
int j = i-1;
for (; j >= 0; j--) {
if(value<arr[j]){
//将此时比较大的元素值赋值给后面的位置
arr[j+1] = arr[j];
}else{
break;
}
}
//此时找到了该元素应该插入的位置
arr[j+1] = value;
}
for(int a:arr){
System.out.print(a+" ");
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String str = scanner.nextLine();
String[] data = str.split(" ");
int[] array = new int[data.length];
for(int i = 0;i<data.length;i++){
array[i] = Integer.parseInt(data[i]);
}
directInsertSort(array);
}
}
结果如下:
- 分析:插入排序使用的是赋值操作。每次将无序数组的第一个元素value与有序数组从最后一个元素arr[j]开始比较,如果value小于arr[j],则将此时的arr[j]的值赋给arr[j+1];直到最后找到位置,再将保存的value赋值给相应位置。
- 基本流程如下:
下面我举例的是:当无序数组只剩一个元素时,程序的具体流程:
2.直接插入排序总结:
- 时间复杂度:当数组有序时,最好时间复杂度为O(n),此时只需要从后往前遍历一次;当数组完全无序时,时间复杂度为O(n^2)。
- 空间复杂度:因为插入排序的核心是赋值操作,不需要开辟额外空间,所以空间复杂度为O(1),是一种原地排序算法。
- 直接插入排序是一种稳定性排序算法。
3.直接插入排序与冒泡排序的比较:
虽然两种排序算法的时间复杂度,空间复杂度看似一样,但实际上插入排序要比冒泡排序快很多。我随机生成了一万条数据,结果如下:
这是为什么呢?
来看这里:
可以看出,冒泡排序的每次比较交换至少要执行3条语句,而直接插入排序只用执行1条赋值语句,大大提高了执行效率,所以大家更喜欢插入排序。