希尔排序

希尔排序又称为缩小增量排序,是1959年由D.L.Shell提出来的,它也是一种插入排序类方法,但在时间效率上 ,较直接插入排序和折半插入排序有较大的改进。  

(1)算法思想

不断的把待排序的一组记录按照间隔值分成若干小组,然后对同一组的记录进行排序。具体做法如下:

a、取定一个正整数d1(d1<n)作为间隔值(或称为步长),然后把全部n个记录按照此间隔值从第一个记录起进行分组,每组记录的下标相差d1,对每组中的记录进行排序(排序方法任选,一般常用直接插入排序法)。

b、取定一个正整数d2(d2<d1)作为新的间隔值,对所有记录进行重新排序,再对各组进行组内排序;

    c、重复以上操作,直到di=1为止,即间隔为1时记录有序,也就是整体达到有序。


特点:

子序列的构成不是简单地“逐段分割”,而是将相隔某个“增量”的记录组成一个子序列。


    对间隔值的取法有多种,希尔提出的取法是:d1=n/2,di+1=di/2。另外还有克努特提出的di+1=di-1/3.。下面 按照希尔排序的方法举例说明。

    已知一组记录的关键字值为(43,25,39,29,65,57,76,22,41,39)

    由于元素个数n=10,根据希尔法,取间隔值为d1=10/2=5,d2=5/2=2,d3=2/2=1,排序的具体过程如下:

    第一趟  d1=5     43  25  39  29  65  57  76  22  41  39

                      |__________________|                            (43  57)

                          |__________________|                        (25  76)

                            |___________________|                    (39  22)

                                |___________________|                (29  41)

                                    |__________________|            (65  39)

    第一趟排序结果    43  25  22  29  39  57  76  39  41  65

    第二趟  d2=2      |_______|_______|_______|_______|               (43  22  39  76  41)

                          |_______|_______|_______|_______|           (25  29  57  39  65)

    第二趟排序结果    22  25  39  29  41  39  43  57  76  65

    第三趟  d3=1      |___|___|___|___|___|___|___|___|___|        (22 25 39 29 41 39 43 57 76 65)

    第三趟排序结果    22  25  29  39  39  41  43  57  65  76

    注:对括号内的关键字值进行直接插入排序


    由以上实例可以看出,希尔排序每一趟以不同的间隔距离d进行分组排序。当d较大时,被移动的记录是跳跃式进 行的。到最后一次排序时(d=1),许多记录已经有序,并不需要多少移动,所以提高了排序的速度。

    用C语言实现的希尔排序算法如下:

#include <stdio.h>
void ShellSort(int r[],int n)
{
    int i,j,d;
    d=n;
    do{
        d=d/2;  //设定间隔值
        for(i=d+1;i<=n;i++)
        {
            r[0]=r[i];
            j=i-d;
            while((j>0)&&(r[0]<r[j]))
            {
                r[j+d]=r[j];   //记录后移
                j-=d;
            }
            r[j+d]=r[0];       //插入记录
        }
    }while(d!=1);
}
int main()
{
    int a[101],n,i;
    scanf("%d",&n);
    for(i=1;i<=n;i++)
      scanf("%d",&a[i]);
    ShellSort(a,n);
    for(i=1;i<=n;i++)
    printf("%d ",a[i]);
    printf("\n");
    return 0;
}

(2)算法性能分析

    希尔排序的速度一般要比直接插入排序快,但希尔排序是一个比较复杂的问题,因为时间的复杂度依赖于所取增量序列,截止目前,增量的选择无一定论。如果按照希尔法来取,每次后一个增量是前一个增量的1/2,则经过t =log2(n+1)次以后,dt=1,这时该算法的时间复杂度为O(nlog2n)。

    根据上述实例分析希尔排序可知,相同关键字的记录在排序后的前后顺序有了改变,所以,希尔排序是一种不稳定的排序方法。

          

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值