排序算法之希尔排序
希尔(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...)