从直接插入排序到希尔排序

#希尔排序是一种属插入排序类的方法。

它的基本思想是:先将整个待排记录序列分割成为若干子序列,分别对其进行直接插入排序,不断重复上述步骤,待整个序列中的记录“基本有序”时,再对全体记录进行一次直接插入排序。

#本博客采用顺序表结构体如下,0号单元留空

typedef struct
{
    int *r;
    int length;
    int listsize;
}SqList;//构造顺序表结构体类型

#直接插入排序及解析

void InsertSort(SqList &L)
{
    int i,j;
    for(i=2;i<=L.length;i++)//从第2个元素开始,逐一向前进行插入
    {
        if(L.r[i]<L.r[i-1])//当待插入元素小于前一个元素时
        {
            L.r[0]=L.r[i];//将待插入元素放入0号单元
            L.r[i]=L.r[i-1];//将前一个元素放入待插入元素的位置

        for(j=i-2;L.r[0]<L.r[j];j--)//从前两个元素开始,依次往前,比较待插入元素与其的大小关系
        {
            L.r[j+1]=L.r[j];//当待插入元素小于第j个元素时,将第j个元素后移到j+1号单元
        }
            L.r[j+1]=L.r[0];//当待插入元素大于第j个元素时,将放在0号单元的待插入元素放在j+1号单元

        }
    }//每一次循环,将一个元素从未排序序列加入到已排序序列
}

#希尔排序以及解析

void ShellInsert(SqList &L,int dk)//以dk为增量进行一趟希尔排序
{
    int i,j;
    for(i=1+dk;i<=L.length;i++)//从1+dk个元素开始,逐一向前进行插入
    {
        if(L.r[i]<L.r[i-dk])//当待插入元素小于子序列中前一个元素时
        {
            L.r[0]=L.r[i];//将待插入元素放入0号单元
            L.r[i]=L.r[i-dk];//将子序列中前一个元素放入待插入元素位置

        for(j=i-2*dk;j>0&&L.r[0]<L.r[j];j=j-dk)//从子序列中前两个元素开始,依次在子序列中往前,比较待插入元素与其的大小关系
        {
            L.r[j+dk]=L.r[j];//当待插入元素小于第j个元素时,将第j个元素后移到j+dk号单元
        }
        L.r[j+dk]=L.r[0];//当待插入元素大于第j个元素时,将待插入元素放入j+dk号单元
        }
    }//每一次循环,将一个元素从子序列中的未排序序列加入到已排序序列
}//进行一趟希尔排序后,每个子序列变成单调有序递增序列

void ShellSort(SqList &L,int dlta[],int t)//按照增量数组dlta进行希尔排序
{
    int k;
    for(k=0;k<t;k++)
    {
        ShellInsert(L,dlta[k]);
    }
}

很容易观察到,直接插入排序就是当dk=1时的一趟希尔排序。

唯一区别是,直接插入排序代码中少了j>0的防越界操作。因为dk=1时,j不再进行跳跃式前进,而是一步一步往前进。当放在0号单元的待插入元素很小很小时,j最终只会减为0,因为当j=0时,L.r[0]<L.r[j]不成立。

而当dk不等于1时,j进行跳跃式前进,L.r[0]不一定会与L.r[j]进行比较,此时就有可能越界了,所以必须加上j>0。

#测试结果

#本博客参考了《数据结构(C语言版)》(严蔚敏,吴伟民编著)

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值