排序算法:希尔排序

希尔排序

希尔排序(Shell’s Sort)是插入排序的一种又称“缩小增量排序”(Diminishing Increment Sort),是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。该方法因D.L.Shell于1959年提出而得名。
希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。

言简意赅,希尔排序的实质就是插入排序。但是希尔排序的优化就是将一个长的序列,利用步长,分组开来,分组进行插入排序。最后一直到步长为 1 的时候,插入排序结束,这个过程就是希尔排序。由于使用插入排序的时候,如果这个带插入的序列基本有序,那么插入排序的效率是非常高的。而希尔排序正是利用了这个原则,进行分组,那么到最后的时候,插入的序列是一个大致有序的序列,效率会非常高。

思路

这里写图片描述

观察整个排序的过程,在选取步长的时候起初选取元素总个数除 2 ,接下来每次gap都除等于 2 。最后直至等于 1 。这个序列又叫做希尔序列。其实还有更高效的序列。希尔排序提高效率的一大方法就是选取一个好的序列。

实现

void ShellSort(int array[], int size)
{
  if (size <= 1) {
    return;
  }
  // 这里利用希尔序列作为希尔排序的步长 
  // 希尔序列 2 4 8 16...
  int gap = size;

  // 注:在使用步长时,一定要从 size 开始向下除
  // 不能用 2^N 这样来计算
  // 因为不一定 2^N 刚好等于 size

  for (; gap > 0; gap /= 2) { // 步长控制循环
    int cur = 0;
    for(; cur < gap; ++cur) { // 每组起始元素
      int bound = cur + gap;
      for(; bound < size; bound += gap) { // 插入排序,不过每组元素间相差 gap
        int bound_value = array[bound];
        int index = bound - gap;
        while (index >= 0 && bound_value < array[index]) {
          array[index + gap] = array[index];
          index -= gap;
        }
        array[index + gap] = bound_value;
      } // end for (; bound < size; ++bound)
    }
  } // end for (; gdp <= size; gap *= 2)
  return;
}

希尔排序其实就是一种变相的插入排序,它利用了插入排序的优点,并且避开其短处,插入排序在处理少数量元素时效率较高,希尔排序利用步长分组,从而达到分解一个大量数据域。最后gap为 1 的时候,此时的数据已经是一个大致有序的数列,这时候直接进行插入排序,效率依旧很高。

希尔排序的时间复杂度最好能到 O(N^1,3),最坏就是 O (N^2),如果选取一个好的gap序列,能够提高效率。空间复杂度为 O(1)。


欢迎大家共同讨论,如有错误及时联系作者指出,并改正。谢谢大家!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值