插入排序
1.定义:
(1)插入排序类似于咱们日常打扑克的时候,通常我们给牌排序时,总是将一张牌插入到其他已经有序的排中的适当位置。
(2)由(1)可知,插入排序是通过遍历数组,并将当前元素与前面已经排好序的元素一一比较,获得最佳位置
(3)为了给要插入的元素腾出空间,需要将其余所有元素在插入之前都向后移动一位。
(4)与选择排序一样,当前索引左边的所有元素都是有序的,但它们的最终位置还不确定。
2.代码剖析
假设:数组a,长度n,下标i
(1)数组从小到大遍历。
(2)当下标索引为 i 时,比较 a[i] 与 a[i-1],若前者小于后者,则交换两个元素的位置,之后让 i--。
(3)循环第二步的操作,直到 a[i]>a[i-1],这时肯定是不交换位置了的,于是,a[i]的这个元素就已经找到了合适的位置了。
(4)如此往复,直到整个数组遍历结束。
3.图解
我们可以看出,首先,数组的第一位我们可以直接跳过不用做判断处理;其次,要等到算法跑完后,其元素的位置最终才定下来。其当前元素只要一判断到不符合条件就直接跳过进入下一个元素判断了,还是比较干脆的。
4.按照这个思路,写出代码如下:
/**
* 插入排序
* 排序过程:
* 1.数组从小到大遍历
* 2.将当前遍历到的元素插入到前面已经排序好的数组里
* 3.插入进去后,其他元素向后排序
* 4.如此往复,直到整个数组排序
* @param array
*/
public static void insertSort(int[] array) {
//将array[]按升序排序
int N = array.length;
int t;
for (int i = 1; i < N; i++) {
//将array[i]插入到a[i-1]、a[i-2]、a[i-3]...之中
//将当前元素与前一个元素相比较,若小于,则往前置换,否则不动
for (int j = i; j > 0 && array[j] < array[j - 1]; j--) {
t = array[j];
array[j] = array[j - 1];
array[j - 1] = t;
}
}
}
5.算法优劣判断
(1)对于随机排列的长度为N且主键不重复的数组,平均情况下插入排序需要N*N/4次比较以及N*N/4次交换。最坏情况下需要N*N/2次比较和N*N/2次交换,最好情况下需要N-1次比较和0次交换
(2)适合的用该算法的数组:数组中每个元素距离它的最终位置不远;一个有序的大数组接一个小数组;数组中只有几个元素的位置不正确。
(3)插入排序需要的交换操作和数组中倒置的数量相同,需要的比较次数大于或等于倒置的数量,小于等于倒置的数量加上数组的大小再减一。(倒置:指的是数组中的两个顺序颠倒的元素)
6.资料引用:
《算法Algorithms(第4版)》 p157~p159
上一节:Java算法(1):选择排序
下一节:Java算法(3):希尔排序