希尔排序

涉及的一些知识

  1. 逆序对

    A A A为一个有 n n n个数字的有序集( n > 1 n>1 n>1),其中所有数字各不相同。如果存在正整数 i i i j j j使得 1 ≤ i < j ≤ n 1 \leq i < j \leq n 1i<jn而且 A [ i ] > A [ j ] A[i]>A[j] A[i]>A[j],则 ( A [ i ] , A [ j ] ) (A[i],A[j]) (A[i],A[j])这个有序对称为A的一个逆序对。

  2. 定理1

    任意 N N N个不同元素组成的序列平均具有 N ( N − 1 ) / 4 N(N-1)/4 N(N1)/4个逆序对。

  3. 定理2

    任何仅以交换相邻两元素来排序的算法,其平均时间复杂度为 Ω ( N 2 ) \Omega(N^2) Ω(N2)

    由该定理可知,要提高算法效率,我们可以:

    1. 每次消去不止一个逆序对
    2. 每次交换相隔较远的两个元素
  4. 稳定性

    能保证两个相等的数,经过排序之后,其在序列的前后位置顺序不变。( A 1 = A 2 A_1=A_2 A1=A2,排序前 A 1 A_1 A1 A 2 A_2 A2前面,排序后 A 1 A_1 A1还在 A 2 A_2 A2前面)

希尔排序

  1. 希尔排序(Shell’s Sort)

    希尔排序是把元素按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的元素越来越多,当增量减至1时,整个数组恰被分成一组,算法便终止。

  2. 例:用希尔排序对下面的数组按照从小到大排列
    例子

    1. 对该数组先做5-间隔排序,即把元素按照下标的增量为5的这个规则分组,对每组使用插入排序。
      81、35和41一组,对它们使用插入排序
      5-间隔排序1
      94、17和75一组,对它们使用插入排序
      5-间隔排序2
      11、95和15一组,对它们使用插入排序
      5-间隔排序3
      96和28一组,对它们使用插入排序
      5-间隔排序4
      12和58一组,对它们使用插入排序
      5-间隔排序5
    2. 对进行了5-间隔排序之后的数组再进行3-间隔排序。
      3-间隔排序
    3. 对进行了3-间隔排序之后的数组再进行1-间隔排序,即直接进行插入排序。
      1-间隔排序
  3. 主要步骤

    1. 定义增量序列 D M > D M − 1 > ⋯ > D 1 = 1 D_M>D_{M-1}> \cdots >D_1=1 DM>DM1>>D1=1
    2. 对每个 D k D_k Dk进行“ D k D_k Dk-间隔”排序( k = M , M − 1 , ⋯   , 1 k=M,M-1, \cdots ,1 k=M,M1,,1
    3. 注意:“ D k D_k Dk-间隔”有序的序列,在执行“ D k − 1 D_{k-1} Dk1-间隔”排序后,仍然是“ D k D_k Dk-间隔”有序的。
  4. 代码实现

    1. 原始希尔排序
      增量序列为: D M = ⌊ S i z e / 2 ⌋ D_M= \lfloor Size/2 \rfloor DM=Size/2 D k = ⌊ D k + 1 / 2 ⌋ D_k= \lfloor D_{k+1}/2 \rfloor Dk=Dk+1/2

      /* 希尔排序 */
      void ShellSort(ListElementType *A, int Size)
      {
          int Increment = 0, i = 0, j = 0;
          ListElementType Temp;
      
          for (Increment = Size; Increment > 0; Increment = Increment / 2) /* 增量序列 */
          {
              for (i = Increment; i < Size; i++) /* 插入排序 */
              {
                  Temp = A[i];
                  for (j = i; j >= Increment&&A[j - Increment] > Temp; j = j - Increment)
                  {
                      A[j] = A[j - Increment];
                  }
                  A[j] = Temp;
              }
          }
      }
      

      原始增量序列下,最坏情况时间复杂度是: T w o r s t ( N ) = Θ ( N 2 ) T_{worst}(N)=\Theta(N^2) Tworst(N)=Θ(N2)
      原因:增量元素不互质,则小增量可能根本不起作用。
      优化:使用更加高效的增量序列。

    2. 优化增量序列

      1. Hibbard增量序列: D k = 2 k − 1 D_k=2^k-1 Dk=2k1(可以保证相邻元素互质)
      2. Sedgewick增量序列: { 1 , 5 , 19 , 41 , 109 , ⋯   } \{1,5,19,41,109,\cdots \} {1,5,19,41,109,} 9 × 4 i − 9 × 2 i + 1 9\times4^i-9\times2^i+1 9×4i9×2i+1 4 i − 3 × 2 i + 1 4^i-3\times2^i+1 4i3×2i+1
  5. 时间复杂度

    1. 原始增量序列
      最坏情况时间复杂度: T w o r s t ( N ) = Θ ( N 2 ) T_{worst}(N)=\Theta(N^2) Tworst(N)=Θ(N2)

    2. Hibbard增量序列
      最坏情况时间复杂度: T w o r s t ( N ) = Θ ( N 3 / 2 ) T_{worst}(N)=\Theta(N^{3/2}) Tworst(N)=Θ(N3/2)
      平均时间复杂度: T a v g ( N ) = O ( N 5 / 4 ) T_{avg}(N)=O(N^{5/4}) Tavg(N)=O(N5/4)(只是猜想,尚未有人能证明)

    3. Sedgewick增量序列
      最坏情况时间复杂度: T w o r s t ( N ) = O ( N 4 / 3 ) T_{worst}(N)=O(N^{4/3}) Tworst(N)=O(N4/3)(只是猜想,尚未有人能证明)
      平均时间复杂度: T a v g ( N ) = O ( N 7 / 6 ) T_{avg}(N)=O(N^{7/6}) Tavg(N)=O(N7/6)(只是猜想,尚未有人能证明)

  6. 稳定性
    希尔排序是不稳定排序。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值