算法笔记–再回顾插入排序
插入排序也很符合人类的直觉,相比选择排序它看上去更加佛系,它的核心在于插入,就是从无序的元素中佛系取出一个元素然后插入到有序的元素中。这里仍然可以用一篮子苹果来形象描述这个过程,首先我们从篮子中随机取出一个,然后继续从篮子随机取出一个,这时手中有两个苹果,我们对他两按大小进行排序,然后继续从篮子随机取出一个,此时将第三个苹果按大小插入到前面排好序的苹果中去,重复此过程,直至篮子的苹果被拿完。对比可见选择排序在于挑,插入排序在于插。
解题:用一个数组来表示元素集合
- 佛系从数组中取出一个元素,我们这里取第一个
- 再次佛系从剩下的数组元素中取出一个元素,我们这里取第二个,比对这两个形成排序
- 再次佛系从剩下的数组元素中取出一个元素,我们这里取第三个,插入到前面两个有序元素中
- 重复步骤直至数组完全排序
时间复杂程度:
- O(n^2)
插入排序适合从大量无序元素中随机取出一个有序队列,比如从一个队列中抽取部分元素排序
案例实践
public class InserSort {
public static void main(String[] args) {
int[] a = {5,6,1,2,3,4,7,8,9};
sort(a);
for (int i = 0; i < a.length; i++) {
System.out.printf("%2d",a[i]);
}
}
/**
* 插入排序
* @param arr
*/
private static void sort(int[] arr){
int n = arr.length;
int tmp = 0;
for (int i = 0; i < n; i++) {
// 寻找元素 arr[i] 合适的插入位置
for( int j = i ; j > 0 ; j -- ){
if( arr[j] < arr[j-1]){
tmp = arr[j];
arr[j] = arr[j-1];
arr[j-1] = tmp;
}else{
break;
}
}
}
}
/**
* while循环更加直观这个插入的过程
* @param arr
*/
private static void sort2(int[] arr) {
for (int i = 1; i < arr.length; i++) {
// 只是将这两句代码的代表当前要插入的下标用外循环的变量来代替了
int currentInsertValue = arr[i];
int insertIndex = i - 1;
//插入到已排序的元素中
while (insertIndex >= 0
&& currentInsertValue < arr[insertIndex]
) {
arr[insertIndex + 1] = arr[insertIndex];
insertIndex--;
}
arr[insertIndex + 1] = currentInsertValue;
// System.out.println("第 " + i + " 轮排序后:" + Arrays.toString(arr));
}
}
}