1.什么是插入排序?
算法导论上面举了一个比较形象的例子:扑克牌。桌子上面放一副扑克牌,我们抓牌的时候,刚开始手里是没有牌的,我们开始一张一张拿到牌往左手塞,第一张K,放到手里,这时候左手已经有一张牌了,而且是有序的,这时候就开始有了循环不变的一组(接下来会解释),拿到第二张牌,是Q,就放到K的右边(当然你也可以习惯放到左边),这时候左手已经有两张牌了,而且是有序的,第三张是A,就寻找合适的位置,比一眼,比Q大,往左(右)放,再比一眼,比K大,再往左(右)放,放完接着抓牌。这时候,你左手的扑克牌会一直是有序的,直到抓完所有的牌。。。这就是一个很形象的插入排序。
对一个数组来说,插入排序的过程:
2.什么是循环不变式?
循环不变式主要用来帮助我们理解算法的正确性。关于循环不变式必须证明的三条性质:
初始化:循环的第一次迭代之前,它为真;
保持:如果循环的某次迭代之前它为真,那么下次迭代之前它仍为真;
终止:在循环终止时,不变式为我们提供一个有用的性质,该性质有助于证明算法是正确的。
当前两条性质成立时,在循环的每次迭代之前循环不变式为真。(也就是说,每次摸牌之前,左手的扑克牌已经是有序的)
3.插入排序的伪代码:(来自于算法导论)
INSERTION-SORT(A)
for j=2 to A.length
key=A[j]
//insert A[j] into the sorted sequenceA[1......j-1]
i=j-1
while i>0 and A[i]>key
A[i+1] = A[i]
i = i - 1
A[i+1] = key
基于一个数组,插入排序在开始循环的数组索引是第二个,也就是说,数组的第一个元素已经是有序的了,循环每一个数组元素,与之前排好序的子数组(就当是分出一个有序的子数组)进行比较,找到合适的位置,插入到有序的子数组中,一次迭代完成,数组已经成为一个有序数组(插入排序对于少量元素的排序来说,是一个有效的算法)。
4.JAVA代码实现插入排序:
package com.yushen.insertsort;
/**
* 插入排序算法
*
* @author yushen
*
*/
public class InsertSort {
/**
* 插入排序的实现方法(针对int型数组)
*
* @param array
* 需要进行排序的数组
* @return
*/
public static int[] sortArray(int[] array) {
if (null == array || (null != array && array.length == 0)) {
System.out.println("Error:array is empty!");
return null;
}
int temp = 0, i = 0;
// 循环开始于数组第二个元素 j=1
for (int j = 1; j < array.length; j++) {
// 将当前数组元素,存放于临时变量中
temp = array[j];
i = j - 1;
// 两个条件同事满足,进入循环:当前位置的前一个位置至少是第一个元素 同时, 当前数组元素大于它的前一个元素
while (i >= 0 && array[i] > temp) {
// 当前位置的元素覆盖为它的前一个位置的元素
array[i + 1] = array[i];
i -= 1;
}
// 将临时变量中存储的元素放入适当的位置
array[i + 1] = temp;
}
return array;
}
public static void main(String[] args) {
int[] array = { 5, 2, 4, 6, 1, 3 };
// 对数组进行排序
array = sortArray(array);
if (null == array) {
System.out.println("Error:sort Exception");
return;
}
for (int i : array) {
System.out.print(i + " ");
}
}
}
一次循环的图解是这个样子:
欢迎指导。。。