算法基础学习---直接插入排序

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 + " ");
        }
    }
}


一次循环的图解是这个样子: 


欢迎指导。。。






评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值