• 算法分析之希尔排序


     希尔排序又称缩小增量排序,该方法的思想是将所有的待排元素分成若干个子序列,相隔距离为某个增量,将对每一个子序列进行直接插入排序,不断缩小增量,继续排序,最后增量很小时候进行最后一次插入排序

    以n=10的一个数组49, 38, 65, 97, 26, 13, 27, 49, 55, 4为例

    第一次 gap = 10 / 2 = 5

    49   38   65   97   26   13   27   49   55   4

    1A                                        1B

            2A                                         2B

                     3A                                         3B

                             4A                                          4B

                                      5A                                         5B

    1A,1B,2A,2B等为分组标记,数字相同的表示在同一组,大写字母表示是该组的第几个元素, 每次对同一组的数据进行直接插入排序。即分成了五组(49, 13) (38, 27) (65, 49)  (97, 55)  (26, 4)这样每组排序后就变成了(13, 49)  (27, 38)  (49, 65)  (55, 97)  (4, 26),下同。

    第二次 gap = 5 / 2 = 2

    排序后

    13   27   49   55   4    49   38   65   97   26

    1A             1B             1C              1D            1E

            2A               2B             2C             2D              2E

    第三次 gap = 2 / 2 = 1

    4   26   13   27   38    49   49   55   97   65

    1A   1B     1C    1D    1E      1F     1G    1H     1I     1J

    第四次 gap = 1 / 2 = 0 排序完成得到数组:

    4   13   26   27   38    49   49   55   65   97

    代码

    void shellsort(a[],n)

    {

            for(int gap=n/2;gap!=0;gap/=2)

            {

                   for(int i=0;i<gap;i++)

                  {

                       for(int j=i+gap;j<n;j+=gap)

                          if(a[j]<a[j-gap])

                         {

                               int temp=a[j];

                               int k=j-gap;

                               while(a[k]>temp&&k>=0)

                               {

                                      a[k+gap]=a[k];

                                      k-=gap;

                               }

                               a[k+gap]=temp;

                         }

              }

          }

    }

    还可以对代码进行优化,直接从增量处开始,这样可以少一层for循环,这样排序也是对的

    代码:

    void shellsort1(a[],n)

    {

          for(int gap=n/2;gap!=0;gap/=2)

          {

                for(int i=gap;i<n;i++)

                {

                     if(a[i]<a[i-gap])

                    {

                     int temp=a[i];

                     int k=i-gap;

                     if(a[k]>temp&&k>=0)

                     {

                          a[k+gap]=a[k];

                          k-=gap;

                     }

                     a[k+gap]=temp;

                    }

                }

             }

    }

    将后移的过程替换成上面博客中交换的过程

    代码:

    void shellsort3(a[],n)

    {

           for(int gap=n/2;gap!=0;gap/=2)

               for(int i=gap;i<n;i++)

                   if(a[i]<a[i-gap])

                   {

                    int k=i-gap;

                    while(a[k]>a[i]&&k>0)

                    {

                           swap(a[k],a[k+gap]);

                           k-=gap;

                     }

                   }

    }

    如果有不对的地方还请大家多多指教多多批判

  • 相关阅读:
    【刷题】LOJ 6009 「网络流 24 题」软件补丁
    lab 项目
    js内的时间戳指的是当前时间到1970年1月1日00:00:00 UTC对应的毫秒数,和 unix时间戳是对应的秒数,差了1000倍
    js 原生: 身份证脱敏、唯一随机字符串uuid、对于高 index 元素的隐藏与显示
    diy 滚动条 样式 ---- 核心代码
    PC_后台管理系统
    三端兼容项目
    阿里小程序
    到位App_jQuery_art-template
    一步一步 copy163: 网易严选 ---- vue-cli
  • 原文地址:https://www.cnblogs.com/pianruijie/p/6776411.html
Copyright © 2020-2023  润新知