希尔排序

【1】希尔排序

严格而言,希尔排序(Shell Sort)是插入排序的一种。是针对直接插入排序算法的改进。

该方法又称缩小增量(逐渐缩小排序元素相隔差距)排序。

希尔排序是不稳定排序算法(参见随笔《常用排序算法稳定性分析》)。

【2】希尔排序逻辑

希尔排序逻辑分析:

(1)先取一个小于N的整数d1作为第一个增量,把待排序的全部记录分成d1个组。所有距离相隔为d1(或距离为d1的倍数)记录放在同一个组中。

怎么理解这个规则?即就是:如果N == 16 ,d1 == 4,那么按照索引(index)分组为:

<1> 0,4,8,12为一组;

<2> 1,5,9,13为一组;

<3> 2,6,10,14为一组;

<4> 3,7,11,15为一组。

(2)先在各组内进行直接插入排序;

(3)取第二个增量d2 < d1重复上述的分组和排序。

(4)重复(1),(2),(3)直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。

【3】希尔排序动态演示

假设待排序序列有10个记录,其关键数据分别为:

49,38,65,97,76,13,27,49,55,04

增量序列的取值依次为:

5,3,1

那么,排序过程【动画模拟演示

【4】C++实现希尔排序

(1)实现并测试程序

  1 #include<iostream>
  2 using namespace std;
  3 
  4 #define   MAXSIZE  10
  5  
  6 int nCnt = 0;   //统计排序趟数
  7 
  8 //打印排序结果
  9 void  PrintArr(int ar[],int n)
 10 {
 11     for(int i = 0; i < n; ++i)
 12         cout<<ar[i]<<" ";
 13     cout<<endl;
 14 }
 15 
 16 void ShellSort(int ar[], int begin, int end)  
 17 {  
 18     int gap = end-begin+1;    //gap初始值
 19     cout<<"gap = "<<gap<<endl;
 20     while(gap > 1)  
 21     {  
 22         ++nCnt;
 23         gap = gap/3 + 1;    //当趟排序gap值确定
 24         cout<<"gap = "<<gap<<endl;
 25         for(int i = begin + gap; i < end; ++i)  
 26         {  
 27             cout<<"i = "<<i<<endl;
 28             int temp = ar[i];    //暂存关键数据
 29             cout<<"temp = "<<temp<<endl;
 30             int j = i;  
 31             while(j-gap >= begin && temp < ar[j-gap])  
 32             {  
 33                 ar[j] = ar[j-gap];   //后移
 34                 j = j-gap;     //前置索引
 35             }  
 36             cout<<"j = "<<j<<endl;
 37             ar[j] = temp;   //插入关键数据
 38         } 
 39         cout<<""<<nCnt<<"趟排序gap = "<<gap<<"结果如下:"<<endl;
 40         PrintArr(ar, MAXSIZE);
 41     }  
 42 } 
 43 
 44 void  main()
 45 {
 46     int  ar[MAXSIZE] = {56, 38, 65, 97, 76, 13, 27, 49, 55, 04};
 47     ShellSort(ar,0,MAXSIZE);
 48 }
 49 
 50 /*
 51 gap = 11
 52 gap = 4
 53 i = 4
 54 temp = 76
 55 j = 4
 56 i = 5
 57 temp = 13
 58 j = 1
 59 i = 6
 60 temp = 27
 61 j = 2
 62 i = 7
 63 temp = 49
 64 j = 3
 65 i = 8
 66 temp = 55
 67 j = 0
 68 i = 9
 69 temp = 4
 70 j = 1
 71 第1趟排序gap = 4结果如下:
 72 55 4 27 49 56 13 65 97 76 38
 73 gap = 2
 74 i = 2
 75 temp = 27
 76 j = 0
 77 i = 3
 78 temp = 49
 79 j = 3
 80 i = 4
 81 temp = 56
 82 j = 4
 83 i = 5
 84 temp = 13
 85 j = 3
 86 i = 6
 87 temp = 65
 88 j = 6
 89 i = 7
 90 temp = 97
 91 j = 7
 92 i = 8
 93 temp = 76
 94 j = 8
 95 i = 9
 96 temp = 38
 97 j = 5
 98 第2趟排序gap = 2结果如下:
 99 27 4 55 13 56 38 65 49 76 97
100 gap = 1
101 i = 1
102 temp = 4
103 j = 0
104 i = 2
105 temp = 55
106 j = 2
107 i = 3
108 temp = 13
109 j = 1
110 i = 4
111 temp = 56
112 j = 4
113 i = 5
114 temp = 38
115 j = 3
116 i = 6
117 temp = 65
118 j = 6
119 i = 7
120 temp = 49
121 j = 4
122 i = 8
123 temp = 76
124 j = 8
125 i = 9
126 temp = 97
127 j = 9
128 第3趟排序gap = 1结果如下:
129 4 13 27 38 49 55 56 65 76 97
130 
131  */

(2)希尔排序实现代码

 1 void ShellSort(int ar[], int begin, int end)  
 2 {  
 3     int gap = end-begin+1;    //gap初始值大于0
 4     while(gap > 1)  
 5     {  
 6         gap = gap/3 + 1;    //当趟排序gap值确定
 7         for(int i = begin + gap; i < end; ++i)  
 8         {  
 9             int temp = ar[i];    //暂存关键数据
10             int j = i;  
11             while(j-gap >= begin && temp < ar[j-gap])  
12             {  
13                 ar[j] = ar[j-gap];   //后移
14                 j = j-gap;     //前置索引
15             }  
16             ar[j] = temp;   //插入关键数据
17         } 
18     }  
19 } 

 

Good Good Study, Day Day Up.

顺序  选择  循环  坚持  总结

posted @ 2013-01-14 11:16  kaizenly  阅读(2900)  评论(0编辑  收藏  举报
打赏