C++ 排序算法(3)---希尔排序

简介

希尔排序是插入排序的优化版本,又名缩小增量排序。
基本思想是把数组按一步长(gap)分组,后对每一组进行插入排序,通过缩小步长使每一组的数据增加,当步长为1时,完成对整组数据的排序。
例如现在有一个数组:
6 3 1 9 4 8 2 5 7 0
以步长5来进行排序,将6和8,3和2,1和5。。。。进行排序,
6 2 1 7 0 8 3 5 9 4
在以步长2(5/2)来排序,将{6,1,0,3,9}和{2,7,8,5,4}进行排序,
0 2 1 4 3 5 6 7 9 8
最后以步长1(2/2)来完成排序
0 1 2 3 4 5 6 7 8 9

由于直接插入排序在元素基本有序的情况下效率是很高的,希尔排序通过缩小数组增量的手段来使直接插入排序的效率发挥到最大。

代码

void ShellSort(int a[], int n)
{
    int gap,i,j,m,temp;
    for(gap = n/2; gap >= 1; gap /= 2)//缩小步长
        for(i = 0; i < gap; i++)//对各组进行排序
            for(j = i + gap; j < n; j += gap)//插入排序
                if (a[j] < a[j - gap])
                {
                    temp = a[j];
                    for (m  = j - gap; m >= 0 && a[m] > temp; m -= gap)
                        a[m + gap] = a[m];
                    a[m + gap] = temp;
                }
}

其实我们可以不用固执的一组一组的进行插入排序,在i循环遍历到的每一个数进行其组内的插入排序,比如先进行a1在a组内的插入,再执行b1在b组内的插入,再去执行a2在a组内的插入。。。。。(步长为2的情况)。

void ShellSort(int a[], int n)
{
    int gap,i,j,temp;
    for(gap = n/2; gap >= 1; gap /= 2)//缩小步长
        for(i = gap; i < n; i++)//对遍历到的数进行插入排序
                if (a[i] < a[i - gap])
                {
                    temp = a[i];
                    for (j  = i - gap; j >= 0 && a[j] > temp; j -= gap)
                        a[j + gap] = a[j];
                    a[j + gap] = temp;
                }
}

对于步长增量并不一定要使用gap/2的方式,只要满足一下两个要求就可以了
1. 最后一个增量必须为1
2. 应该尽量避免序列中的值(尤其是相邻的值)互为倍数的情况。
事实上增量的选择也会影响到希尔排序的复杂度,例如希尔增量( n/2i )时间复杂度为O(n²),而Hibbard增量( 2k1 )的希尔排序的时间复杂度为 O(n3/2) .

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值