插入排序(Insert Sort)

插入排序顾名思义,应该是在有序的序列中插入一个数据,并经过一系列变化,成为一个新的有序的序列。像是在玩扑克牌时,抓到的第一张牌是5,放在手里,就是一个有序的序列;抓到的第二张牌是3,则将3放在5的右面,又形成了一个有序的序列;第三张抓到4,则从手上最后一张开始比较,4比3大,则4应该在3的左边,再和5比较,4比5小,则4应该在5的右边,至此把4插入到5和3之间,形成一个新的有序的序列。


时间复杂度:O(n^2)
虽然插入排序是个O(n^2)级别的算法,但在某些情况下,他甚至比O(nlogn)级别的算法还要快。在下面的代码实现中会提到。


稳定性:稳定


代码实现
按照上面的描述,先实现一个简单的方法

template <typename T>
void insertSort(T arr[],int n)
{
    for (int i = 1; i < n;i++)
    {
        for (int j = i; j> 0 && arr[j] < arr[j - 1]; j--)
        {
            swap(arr[j], arr[j - 1]);
        }
    }
}

这里思考一下这个过程有没有更好的办法?
上面实现的代码转变成起牌的过程就是:假如手上从左至右依次拿着9、8、6、5、4,这时我们摸到了一张7:
首先与4比较,7>4,交换4和7的位置。
-当前序列为:8、6、5、7、4
我们实际上相当于把7先插入了5和4之间,这就有问题了。我们现实中玩牌,都是从右开始比较,直到找到正确的位置才插入,我们上面写的代码势必会造成不必要的多次赋值。

下面是我依照现实情况做的优化:

template<typename T>
void insertSort(T arr[], int n)
{
    for (int i = 1; i < n; i++)
    {
        T e = arr[i];
        int j;
        for (j = i; j > 0 && arr[j - 1] > e; j--)
        {
            arr[j] = arr[j - 1];
        }
        arr[j] = e;
    }
}

这个实现算法在数组基本有序的情况下,性能好到爆炸。


测试性能

Test1
数据量:100000
数据关系:完全随机
测试的算法:插入排序两个版本
这里写图片描述

Test2
数据量:1000000
数据关系:基本有序
测试的算法:插入排序两个版本
这里写图片描述

Test3
数据量:100000
数据关系:含有大量重复元素
测试的算法:插入排序两个版本
这里写图片描述

结果大家自己体会一下,哈哈

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值