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

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

                 }

               }

}

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

posted on 2017-04-27 20:34  101-28  阅读(147)  评论(0编辑  收藏  举报