排序算法---希尔排序

希尔排序

直接插入排序的时间复杂度在元素有序或者是元素数量少的时候是比较有效的,希尔排序为了提高算法的效率,所以将原始的元素进行分组使每个分组的元素个数较少,然后在这些分组中进行直接插入排序,当整个序列基本有序的时候再接着进行一次直接插入排序。

基本思想:假设有n个数据元素

先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。所有距离为dl的倍数的记录放在同一个组中。先在各组内进行直接插人排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。最后一次的增量一定是1,也就是对所有的元素进行一次直接插入排序。

实例:

假设待排序文件有10个记录,其关键字分别是:
49,38,65,97,76,13,27,49,55,04
增量序列的取值依次为:
 5,3,1

第一趟排序:

49386597761327495504//增量为5,所以49与38比较,互换,其余同样


第二趟排序:

13,27,49, 55,04,49,38,65,97,76//增量为3.所以对13,04,97进行直接插入排序


04,27,38 ,55 ,13 ,49  ,49 ,65 , 97,76

最后一趟排序直接进行一次直接插入排序,参照之前的算法。由于现在的元素已经基本有序,所以时间复杂度降低。

希尔排序是第一种时间复杂度突破O(n^2)的排序算法,平均时间复杂度为(O(nlgn)~O(n^2))

代码

void  ShellSort(SeqList R)
    {
     int increment=n; //增量初值,不妨设n>0
     do {
          increment=increment/3+1; //求下一增量
          ShellPass(R,increment); //一趟增量为increment的Shell插入排序
        }while(increment>1)
     } //ShellSort
void ShellPass(SeqList R,int d)
    {//希尔排序中的一趟排序,d为当前增量
     for(i=d+1;i<=n;i++) //将R[d+1..n]分别插入各组当前的有序区
       if(R[i].key<R[i-d].key){
          R[0]=R[i];j=i-d; //R[0]是暂存单元
         do {//查找R[i]的插入位置
            R[j+d];=R[j]; //后移记录
            j=j-d; //查找前一记录
         }while(j>0&&R[0].key<R[j].key);
         R[j+d]=R[0]; //插入R[i]到正确的位置上
       } //endif
    } //ShellPass


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值