排序算法之希尔排序

 

希尔(Shell)排序是插入排序的扩展,它允许非相邻的数据项进行交换来提高执行效率。

先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成(n除以d1)个组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。该方法实质上是一种分组插入方法。

例如:

初始:d=5

  49 38 65 97 76 13 27 49 55 04

  49 13

  |-------------------|

  38 27

  |-------------------|

  65 49*

  |-------------------|

  97 55

  |-------------------|

  76 04

  |-------------------|

  一趟结果

  13 27 49* 55 04 49 38 65 97 76

  d=3

  13 27 49* 55 04 49 38 65 97 76

  13 55 38 76

  |------------|------------|------------|

  27 04 65

  |-----------|------------|

  49* 49 97

   |------------|------------|

  二趟结果

  13 04 49* 38 27 49 55 65 97 76

  d=1

  13 04 49* 38 27 49 55 65 97 76

  |----|----|----|----|----|----|----|----|----|

  三趟结果

  04 13 27 38 49 49 55 65 76 97

一种实现:

 1 #include <iostream>
 2 #include <stdlib.h>
 3 using namespace std;
 4 template <typename Item>
 5 void shellsort(Item a[], int l, int r)
 6 {
 7     int h;
 8     //选择合适的步长,从1开始1,4,13,40...
 9     for (h=1;h<=(r-1)/9;h=h*3+1);
10     for (;h>0;h/=3)
11     {
12         for (int i=l+h;i<=r;i++)
13         {
14             int j=i;
15             Item v=a[i];
16             while(j>=l+h && v<a[j-h])
17             {
18                 a[j]=a[j-h];
19                 j-=h;
20             }
21             a[j]=v;
22         }
23     }
24 }
25 
26 void main()
27 {
28     int i;
29     int N=10;
30     int *a=new int[N];
31     int sw=1;
32 
33     if(sw)
34     {
35         for(i=0;i<N;i++)
36             a[i]=1000*(1.0*rand()/RAND_MAX);
37     }
38     else
39     {
40         N=0;
41         while(cin>>a[N])
42             N++;
43     }
44     for(i=0;i<N;i++)
45         cout<<a[i]<<" ";
46     cout<<endl;
47     shellsort(a,0,N-1);
48     for(i=0;i<N;i++)
49         cout<<a[i]<<" ";
50     cout<<endl;
51 }

实现中,首先要选择合适的步长h,这里的步长h取的数据长度的1/3,然后每次减小为原来的1/3,直到步长为1.

(To Be Continued...)

posted @ 2012-09-12 20:15  lscheng  阅读(216)  评论(0编辑  收藏  举报