希尔排序
【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.
顺序 选择 循环 坚持 总结