排序算法系列:插入排序算法 概述 版权说明 文件夹 算法原理分析 算法步骤 逻辑实现 复杂度分析 Ref Github源代码下载

直接插入排序(Straight Insertion Sort)的基本操作是将一个记录插入到已经排好序的有序表中,从而得到一个新的、记录数增1的有序表。

                           – 《大话数据结构》


版权说明

著作权归作者所有。


商业转载请联系作者获得授权,非商业转载请注明出处。
本文作者:Coding-Naga
发表日期: 2016年3月24日
原文链接:http://blog.csdn.net/lemon_tree12138/article/details/50968422
来源:CSDN
很多其它内容:分类 >> 算法与数学


文件夹


算法原理分析

从上面的概述中我们也就能够知道了。这里对数组进行排序的过程须要两个序列才干完毕。
一个待排序的乱序序列。一个是已排序的有序序列。我们如今要要做的就是把乱序的元素一个一个地从乱序列中插入到有序序列中去。就像以下这样:
排序算法系列:插入排序算法
概述
版权说明
文件夹
算法原理分析
算法步骤
逻辑实现
复杂度分析
Ref
Github源代码下载
但是,这里还是有一些不太好的地方,比較明显地方就是我们须要额外加入一个辅助数组。

假设这个待排序数据比較大,那么可能加入辅助数组的策略就不能使用了。
这里我们不难想到,在原始数组中。有这种一个等式:总体序列 = 有序序列 + 乱序序列
也就是说我们能够把当前序列数组一分为二,左边为有序,右边为乱序。
排序算法系列:插入排序算法
概述
版权说明
文件夹
算法原理分析
算法步骤
逻辑实现
复杂度分析
Ref
Github源代码下载
这样每次从乱序序列中取出第一个元素,从有序列中插入。直到序列总体有序为止。详细的步骤请參见以下的算法步骤


算法步骤

  1. 默认序列中的第0个元素是有序的(由于仅仅有一个元素a[0]嘛,自然是有序的)。
  2. 从下标为1(下标从0開始)的元素開始,取当前下标i位置处的元素a[i]保存到一个暂时变量waitInsert里。
  3. 对前半部分有序序列的循环遍历,并与waitInsert比較。直到遇到一个比waitInsert小的元素(这里默认是从小到大排序),此时的下标为j,那么如今仅仅要对a[j+1]进行赋值waitInsert就可以。
  4. 将待插入元素的下标 i 向后推移一个位置。
  5. 反复进行第2步到第4步。直到乱序序列中的元素被所有插入到有序序列中。
  6. 经过以上5个步骤之后,总体序列必定有序。排序完毕。

逻辑实现

/*
     * 排序算法的核心模块
     * 
     * @param array
     *      待排序数组
     */
    private void sortCore(int[] array) {
        int arraySize = array.length;

        for (int i = 1; i < arraySize; i++) {
            int j = i;

            int waitInsert = array[i];
            while(j > 0 && waitInsert < array[j - 1]) {
                array[j] = array[j - 1];
                j--;
            }

            array[j] = waitInsert;
        }
    }

复杂度分析

排序方法 时间复杂度 空间复杂度 稳定性 复杂性
平均情况 最坏情况 最好情况
插入排序 O(n2) O(n2) O(n) O(n) 稳定 简单

这里的最坏的情况和平均情况从代码中就能够看出来,由于有两嵌套的for循环嘛。那么其最好的情况呢?这个就是对于一个有序的序列来说,不须要进行交换,仅仅是比較了n次,所以这里最好的时间复杂度就是O(n)。


Ref

  • 《大话数据结构》

Github源代码下载

https://github.com/William-Hai/ArraySortAlgorithm/blob/master/src/org/algorithm/array/sort/impl/InsertSort.java