算法入门系列 插入排序 小白也能看懂 动态图解(3/10)

文章详细介绍了插入排序算法,包括其简介、图解排序过程、算法性能分析以及代码实现。通过图解方式帮助读者更好地理解插入排序的工作原理,强调了在数组接近有序时插入排序的效率,并对比了与其他排序算法如选择和冒泡排序的差异。此外,还提供了C语言的插入排序函数实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

作者想说

1.插入排序算法的简介

1.1.什么是插入排序

1.2.插入排序的算法性能

2.插入排序算法的图解

2.1.第一轮排序

2.2.第二轮排序

2.3.第三轮排序

2.4.第四轮排序

3.插入排序算法的代码实现

3.1.定义数组并传入到我们的插入排序函数

3.2.插入排序函数的实现

4.插入排序算法的思考

4.1.插入排序的特点

4.2.插入排序的最坏情况


作者想说

介于网上的算法文章大多都是死板的文字,本人文字理解能力一直不强。决定花时间做图解,把困难的问题变简单,把抽象的思维变具体。给想学习程序的小伙伴更好理解的文章资源。

文学家的浪漫是把一切用文字来书写,程序员的浪漫是把我们心中所想用代码书写

这里我将用图解来书写,程序在我脑子里的样子,我叫@张三xy,致力于写出优质作品的编程爱好者

1.插入排序算法的简介

1.1.什么是插入排序

插入排序(InsertionSort),一般也被称为直接插入排序。

对于少量元素的排序,它是一个有效的算法。插入排序是一种简单的排序方法,它的基本思想是将一个记录插入到已经排好序的有序表中,从而一个新的、记录数增 1 的有序表

。在其实现过程使用双层循环,外层循环对除了第一个元素之外的所有元素,内层循环对当前元素前面有序表进行待插入位置查找,并进行移动。

1.2.插入排序的算法性能

插入排序的平均时间复杂度也是 O(n^2),空间复杂度为常数阶 O(1),具体时间复杂度和数组的有序性也是有关联的。

2.插入排序算法的图解

2.1.第一轮排序

 第一轮排序,我们从后往前找,发现 前面的值 > VAL 时,我们用前面的值覆盖了我们后面的值,然后在找到最左边时,我们把VAL插入到了我们刚刚找到的位置

2.2.第二轮排序

 第二轮排序,我们从后往前找,发现 3 < VAL,此时的位置,我们的VAL 要放在 3 的后面

所以此时我们的位置已经确定,把 VAL 插入到 的后面,最终结果不变化

2.3.第三轮排序

 第三轮排序,这一轮我们能够清晰的看到,我们的数组,整体向后移动的感觉,

注意,我们这次找到了最小值1,我们不断寻找,凡是比 VAL 小的我们都往后面移动一下,直到我们找到最顶端

因为比VAL大的都往后面移动了,此时VAL和它后面的 i 个值保持相对有序,有没有get到插入的感觉呢?

2.4.第四轮排序

 第四轮排序,我们一样是先记录下VAL,然后不断往前找到属于它的位置,最后我们完成了这个排序的过程

3.插入排序算法的思考

3.1.插入排序为什么比选择和冒泡快一些?

答:

因为在计算机里,交换数据是很浪费时间的,我们减少了判断次数和交换次数,保持相对有序,自然而然就提升了排序速度和效率

3.2.插入排序的特点

答:

稳定相对顺序不会变,在序列基本有序的情况下,排序时间相对较快。会比我们的冒泡,选择快很多。最差的情况应该是将序列倒序变成顺序。

插入排序不仅不需要大量交换,而且我们比较次数也很少,我们用赋值覆盖的方式实现了这个数组往后移动,有了一个往前插入的效果

3.3.插入排序的最坏情况

答:

插入排序中,当待排序数组是有序时,是最优的情况,只需当前数跟前一个数比较一下就可以了,这时一共需要比较 N-1 次,时间复杂度为 O(N)。最坏的情况是待排序数组是逆序的,此时需要比较次数最多,最坏的情况是 O(n^2)。

而我们下一期要讲解的希尔排序完美的结合插入排序的优点,避开了缺点!

4.插入排序算法的代码实现

4.1.定义数组并传入到我们的插入排序函数

int main() {
    //自定义一个数组演示
    int len = 5;    //数组长度
    int a[] = {3,2,5,1,4};

    //把数组 和 数组长度 传入到插入排序函数中
    insertionSort(a,len);
    return 0;
}

4.2.插入排序函数的实现

#include <stdio.h>

/**
 * 插入排序
 * @param a
 * @param len
 */
void insertionSort(int a[],int len)
{
    //从第二个数据开始
    for(int i = 1;i < len;i++)
    {
        int val = a[i];//当前数据项
        int idx = i - 1;//前一个数据的位置

        //如果前一个数据项 >= 0,并且前一个数据项大于 当前数据项
        while(idx >= 0 && a[idx] > val)
        {
            a[idx+1] = a[idx];
            idx--;
        }

        //被插入的位置 和 i 的位置不一样,我们就进行插入操作(小优化)
        if(idx + 1 != i)a[idx + 1] = val;
    }
}


评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值