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

最近在和小伙伴们一起研究排序,排序分好多总,后期会做整体总结,本篇则主要对插入排序进行一个整理
插入排序(插入分选)的算法思想十分简单,就是对待排序的记录逐个进行处理,每个新纪录与同组那些已排好序的记录进行比较,然后插入到适当的位置用三个字总结就是- “ 多对一 ”关系的
插入排序分好几种,比如二分插入排序,交换插入排序,直接插入排序,本篇我们重点总结最熟悉的“直接插入排序”。
比如有一个数组【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;
        }
    }

通过代码我们来看一下时间复杂度和空间复杂度。
因为我们只引入了一个辅助存放插入记录的临时变量,因此空间代价为一个记录大小 及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)

猜你喜欢

转载自blog.csdn.net/huo065000/article/details/81069053
今日推荐