插入排序--直接插入&希尔

排序的分类

这里写图片描述


这篇先从插入排序说起

直接插入排序

顾名思义,就是将一个数直接插入到对的位置,这个算法的思想就像我们打扑克时
这里写图片描述
这里写图片描述
我们拿到一个数(抽了一张牌),从后先前,将它插入到对的地方

  1. 从第一个数开始,这个数可以认为已经被排序
  2. 取出下一个数, 将这个数插入到前面以有序的序列中
  3. 如果这个数,小于前面的数,将前面的数向后移动,循环这个动作,直到插入合适的位置
//直接插入排序
//O(N*N)
void InsertSort(int* a,size_t n)
{
    assert(a);

    //从前向后抽排
    for (int i = 0; i<n-1; i++)
    {
        int end = i;
        //取出待插入值
        int tmp = a[end + 1];
        //从end开始,从后向前,遇到比插入值大的向后移一位
        while (end >= 0 && a[end] > tmp)
        {
            a[end + 1] = a[end];
            --end;
        }
        //找到要插入的位置,插入;
        a[end + 1] = tmp;
    }
}时时间复杂度O(n^2)
// 最好情况为输入序列是升序排列的,此时时间复杂度O(n)
// 平均时间复杂度 ---- O(n^2)

插入排序不适合对于数据量比较大的排序应用


希尔排序

希尔排序又称为“缩小增量排序”,至于为什么叫缩小增量排序,我们一会就会解释

希尔排序是对直接插入排序的改进,
它的基本思想是:先将整个待排序列分割成若干个子序列,分别对子序列进行组内直接插入排序(预排序),然后再对整个序列,以组为单位,进行直接插入排序

排序过程如下图所示:d表示增量
希尔排序的特点是:它的子序列的划分不是简单的“逐段分割”,而是将相隔某个“增量”的数据组成一个子序列。
这里写图片描述
过程:

  1. 先将序列以合适的增量进行分组
  2. 将分好的组,分别进行组内的排序
  3. 以组内第一个元素为值进行比较,将全部序列排序
  4. 然后缩小增量,重复上面三个步骤,直到增量为1

上面的例子,第一趟的排序增量为4,第二趟排序的增量为2,每一次的增量都在减小,直到最后一次增量为1,所以这就是为什么这种排序又叫“缩小增量排序”的原因

由于前两趟的插入排序中,在子序列的内部排序中,都是和自己隔了几个增量的前一个数据进行比较的,因此较小的数据就不是一步一步的往前移动的,而是跳跃式地往前移动,当最后一趟增量为1的插入排序时,序列已基本有序了,只要再做少量的比较和移动就可以完成整体的排序

void ShellSort(int*a, size_t n)
{
    int gap = n;
    while (gap > 1)
    {
        gap = gap / 3 + 1;
        for (size_t i = 0; i < n - gap; ++i)
        {
            int end = i;
            int tmp = a[end + gap];
            while (end >= 0 && a[end]>tmp)
            {
                a[end + gap] = a[end];
                end -= gap;
            }
            a[end + gap] = tmp;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值