排序系列【比较排序系列之】直接插入排序

最近在和小伙伴们一起研究排序,排序分好多总,后期会做整体总结,本篇则主要对插入排序进行一个整理。
插入排序(insert sorting)的算法思想十分简单,就是对待排序的记录逐个进行处理,每个新纪录与同组那些已排好序的记录进行比较,然后插入到适当的位置。用三个字总结就是—-“多对一”的关系。
插入排序分好几种,比如二分插入排序,交换插入排序,直接插入排序,本篇我们重点总结最熟悉的“直接插入排序”。
比如有一个数组【45 34 78 12 34’ 32 29 64】,我们针对此进行一下讲解。

排序过程 数组{45 34 78 12 34’ 32 29 64}
第一遍 45和34比较,34<45,所以排序完成为34 45 78 12 34’ 32 29 64
第二遍 78和34 45比较 78>45 78>34,所以位置不变,排序完为 34 45 78 12 34’ 32 29 64
第三遍 12和34 45 78比较 12<78 左移+1,12<45 左移+2,12<34 左移+3,排序完为 12 34 45 78 34’ 32 29 64
第四遍 34’ 左移+2 排序完 12 34 34’ 45 78 32 29 64
第五遍 32 左移+4 排序完 12 32 34 34’ 45 78 29 64
第六遍 29 左移+6 排序完 12 29 32 34 34’ 45 78 64
第七遍 64 左移+1 排序完 12 29 32 34 34’ 45 64 78

用代码实现的话其实更简单,引入一个临时变量,具体看代码:

 public static void main(String[] args) {
        Test2 test2 = new Test2();
        //定义一个数组
        int[] array = {45, 34, 78, 12, 34, 32 ,29 ,64};
        test2.insertSort(array);
        System.out.println(Arrays.toString(array));
    }

    void insertSort(int[] array) {
        //定义的临时变量
        int tempRecord;
        //i从1开始的原因是j=j-1
        for (int i = 1; i < array.length; i++) {
            tempRecord = array[i];
            int j = i - 1;
            //j不能为负数,根据索引判定值大小,通过临时变量进行交换
            while (j >= 0 && tempRecord < array[j]) {
                array[j + 1] = array[j];
                j = j - 1;
            }
            array[j + 1] = tempRecord;
        }
    }
2018073014:30:55补充:
array[j + 1] = tempRecord,应该放入while循环内,因为若tempRecore不小于array[j],则此次i循环则直接结束。

通过代码我们来看一下时间复杂度和空间复杂度。
因为我们只引入了一个辅助存放插入记录的临时变量,因此空间代价为一个记录大小 及O(1);

当数据正序时,如上我们口述的排序比较过程,执行效率最好,每次插入都不用移动前面的元素,有N个元素参与比较,时间复杂度为O(N)。

当数据反序时,则执行效率最差,每次插入都要前面的元素后移,
i=1时,移动2-1;
i=2时,移动3-1;
当i=n时,移动n-1;
求和公式:n(n-1)/2=O(n2)
所以最坏的时间复杂度为O(N2)

posted on 2018-07-16 17:49  huohuoL  阅读(214)  评论(0编辑  收藏  举报

导航