• 希尔排序


    希尔排序,也称递减增量排序算法,是插入排序的一种高速而稳定的改进版本。

    希尔排序是基于插入排序的以下两点性质而提出改进方法的:

              插入排序在对几乎已经排好序的数据操作时, 效率高, 即可以达到线性排序的效率

              但插入排序一般来说是低效的, 因为插入排序每次只能将数据移动一位

    原始的算法实现在最坏的情况下需要进行O(n2)的比较和交换。V. Pratt的书[1] 对算法进行了少量修改,可以使得性能提升至O(n log2 n)。这比最好的比较算法的O(n log n)要差一些。

    希尔排序通过将比较的全部元素分为几个区域来提升插入排序的性能。这样可以让一个元素可以一次性地朝最终位置前进一大步。然后算法再取越来越小的步长进行排序,算法的最后一步就是普通的插入排序,但是到了这步,需排序的数据几乎是已排好的了(此时插入排序较快)。

    假设有一个很小的数据在一个已按升序排好序的数组的末端。如果用复杂度为O(n2)的排序(冒泡排序插入排序),可能会进行n次的比较和交换才能将该数据移至正确位置。而希尔排序会用较大的步长移动数据,所以小数据只需进行少数比较和交换即可到正确位置。

    一个更好理解的希尔排序实现:将数组列在一个表中并对列排序(用插入排序)。重复这过程,不过每次用更长的列来进行。最后整个表就只有一列了。将数组转换至表是为了更好地理解这算法,算法本身仅仅对原数组进行排序(通过增加索引的步长,例如是用i += step_size而不是i++)。

      1 // 参考白话经典算法之希尔排序的思想
      2 #include <stdio.h>
      3 
      4 void SwapValue(int *OperatorA, int *OperatorB)
      5 {
      6     if ((NULL == OperatorA) || (NULL == OperatorB))
      7     {
      8         printf ("Invalid Parameter(s)!\n");
      9         return;
     10     }
     11 
     12     if ((*OperatorA) != (*OperatorB))
     13     {
     14         *OperatorA ^= *OperatorB;
     15         *OperatorB ^= *OperatorA;
     16         *OperatorA ^= *OperatorB;
     17     }
     18 }
     19 
     20 void ShellSort(int *a, int N)
     21 {
     22     if ((NULL == a) || (N <= 0))
     23     {
     24         printf ("Invalid Parameter(s)!\n");
     25         return;
     26     }
     27 
     28     int nGap = N >> 1;
     29 
     30     while (nGap > 0)
     31     {
     32         for (int i = 0; i < nGap; ++i)
     33         {
     34             for (int j = i + nGap; j < N; j += nGap)
     35             {
     36                 if (a[j] < a[j-nGap])
     37                 {
     38                     int nTemp = a[j];
     39 
     40                     for (int k = j - nGap; (k >= 0) && (a[k] > nTemp); k -= nGap)
     41                     {
     42                         SwapValue (&a[k], &a[k+nGap]);
     43                     }
     44                 }
     45             }
     46         }
     47         
     48         nGap >>= 1;
     49     }
     50 }
     51 
     52 // 优化一,从nGap开始依次往后循环,但是每个元素都只与自己组内的元素做插入排序
     53 void ShellSort1(int *a, int N)
     54 {
     55     if ((NULL ==a) || (N <= 0))
     56     {
     57         printf ("Invalid Parameter(s)!\n");
     58         return;
     59     }
     60 
     61     int nGap = N >> 1;
     62 
     63     while (nGap > 0)
     64     {
     65         for (int i = nGap; i < N; ++i)
     66         {
     67             if (a[i] < a[i-nGap])
     68             {
     69                 int nTemp = a[i];
     70 
     71                 for (int j = i - nGap; (j >= 0) && (a[j] > nTemp); j -= nGap)
     72                 {
     73                     SwapValue (&a[j], &a[j+nGap]);
     74                 }
     75             }
     76         }
     77         
     78         nGap >>= 1;
     79     }
     80 }
     81 
     82 int main(void)
     83 {
     84     int a1[9] = {9, 8, 7, 6, 5, 4, 3, 2, 1};
     85     int a2[9] = {9, 8, 7, 6, 5, 4, 3, 2, 1};
     86 
     87     ShellSort (a1, 9);
     88     ShellSort1 (a2, 9);
     89 
     90     for (int i = 0; i < 9; ++i)
     91     {
     92         printf ("%d ", a1[i]);
     93     }
     94 
     95     printf ("\n");
     96 
     97     for (int i = 0; i < 9; ++i)
     98     {
     99         printf ("%d ", a2[i]);
    100     }
    101 
    102     printf ("\n");
    103 
    104     return 0;
    105 }

  • 相关阅读:
    MySQL修改配置,区分大小写
    mvc中validateinput属性在asp.net4中不工作
    VS2010开发环境最佳字体及配色
    推荐19个很有用的 JavaScript 库
    Mysql limit 优化,百万至千万级快速分页,复合索引的引用并应用于轻量级框架
    C:\Windows\system32\MSVCR100.dll 没有被指定在 Windows 上运行,或者它包含错误。请尝试使用原始安装媒体重新安装程序,或联系您的系统管理员或软件供应商以获取支持。【解决办法】
    log4net配置步骤
    TraceSource记录程序日志
    [转] WPF TextBox控件中文字实现垂直居中
    SQL Server实现类似split功能
  • 原文地址:https://www.cnblogs.com/ldjhust/p/2986145.html
Copyright © 2020-2023  润新知