• 经典算法——直接插入排序


    1. 算法的定义

    任何被明确定义的计算过程都可以称作 算法 ,它将某个值或一组值作为输入,并产生某个值或一组值作为输出。所以 算法可以被称作将输入转为输出的一系列的计算步骤

    说白了就是步骤明确的解决问题的方法。由于是在计算机中执行,所以通常先用伪代码来表示,清晰的表达出思路和步骤,这样在真正执行的时候,就可以使用不同的语言来实现出相同的效果。

    2. 直接插入排序

    输入:😊

    n个数的序列,通常存放在数组中可能是任意顺序。

    输出:😃

    输入序列的一个新排列(有顺序的),满足从小到大(默认按照升序,通过简单的修改就可实现降序)

    算法说明:😳

    从原有的 无序 的序列中取出一个数(待排元素),插入到当前已经排好的 有序序列 当中,直到所有数全部取完,那么最后得到的新的序列也就是一个有序序列。最开始有序区里只有一个元素。

    理解:😐
    和打扑克牌一样,在抓起第一张牌的时候,直接放在手里面就可以。在抓后面牌的时候要和手里面的牌进行一个比较,然后才能决定后面的牌要放在哪里(后面抓起的牌就是待排元素

    过程 :😠

    将无序区中的元素一个一个插入到有序区当中的过程,最后输出的就是一个新的有序序列

    1️⃣1. 第一个元素:放在第一个位置,直接排好
    2️⃣2. 第二个元素:与第一个元素比较,如果更大,放在第二个位置,如果更小,放在第一个位置
    3️⃣3. 第三个元素:顺序从后往前比较,如果更小,将已排好的元素向后串位,最后插入第三个元素
    4️⃣4. 剩余其他元素:顺序从后向前比较,如果更小,将已排好元素向后串位,直到找到合适的位置插入
    5️⃣5. 如果待排元素是已排好的元素中最大的,只需要比较一次,然后直接追加到已排好的序列后面

    在这里插入图片描述

    3. 代码实现

    Java 代码实现⚠️⚠️⚠️

    @Test
    public void main() {
        // input data
        int[] a = {86, 34, 40, 7, 18, 38, 10, 57, 29, 47};
        // 数组下标从0开始,j初始为1,指向第二个元素
        for (int j = 1; j < a.length; j++) {
            // 使用key记录当前元素的值
            int key = a[j];
            // 初始化i,为j的前一个元素
            int i = j - 1;
            // while循环作用:在已经排好的有序数列中确定key的位置,并串出对应的位置
            while (i >= 0 && a[i] > key) {
                // 串位覆盖,不需要使用交换,值已经被记录在key中
                a[i + 1] = a[i];
                // 逐渐前移
                i = i - 1;
            }
            // 将待排元素放在对应的位置
            a[i + 1] = key;
        }
        // 查看排序结果
        for (int data : a) {
            System.out.print(data + "\t");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    4. 算法效率

    4.1 时间复杂度

    最坏的情况 👎

    按照最坏的情况(每次插入都遍历一遍已经排好序的数组),外层循环n-1次,内层循环1+2+3+…+(n-2)=(n-2)(n-1)/2次,所以最坏情况是O(n²)

    最好的情况 👍

    最好的情况就是指能不被执行的步骤都没有被执行,来的数据刚刚好,并且每个数据都是这样。
    对于直接插入排序来说,如果输入的元素已经是正向有序的,那么每次取出一个元素,在和已经排好的序列中的最后一个元素比较之后,就可以直接放到后面,循环都不用进,因为已经找到了它应该在的位置。
    在这种情况下,内层的while循环可以只看成一个判断语句了,嗯,就是这样。所以代码执行的次数主要看外层for循环就好了,一共是n-1次,属于O(n)

    平均情况✌️
    综合两种情况,插入排序的时间复杂度为 O(n²)

    4.2 空间复杂度

    除计数器以外,算法执行过程中需要使用临时变量key来记录一下当前元素的值,除此之外的其他操作都可以在原数据结构(数组)上完成,所以空间复杂度为O(1)

  • 相关阅读:
    MySQL 8.0与MySQL 5.7的binlog差异小结
    Vue3最佳实践 第六章 Pinia,Vuex与axios,VueUse 1(Pinia)
    热力图展示相关矩阵
    TYPE-C接口桌面显示器:视频与充电的双重革新
    NetSuite Plug-In 101
    Python技能树测评报告
    蒋鑫鸿:9.10国际黄金原油最新外盘行情趋势点评附解一套技术指导
    问题汇总20231117
    字节技术官手码1938页LeetCode热门高解,GitHub已上榜
    HTTP Basic 认证
  • 原文地址:https://blog.csdn.net/weixin_43847283/article/details/126167751