• 算法分析之希尔排序


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

    以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;

                     }

                   }

    }

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

  • 相关阅读:
    CSS 样式清单整理
    JavaScript常用方法封装
    c# 异常:值不能为 null。 参数名: source
    iframe重新加载
    jquery 获取 父级 iframe 里的控件对象
    添加外键约束
    LinQ to entities 不能识别方法“system.string.ToString(system.String)”.因此该方法无法转换为存储表达式
    c# pcm
    .Net Core 2.0 App中读取appsettings.json
    c# 泛型demo
  • 原文地址:https://www.cnblogs.com/pianruijie/p/6776411.html
Copyright © 2020-2023  润新知