希尔排序
来源:互联网 发布:上海大剧院 座位 知乎 编辑:程序博客网 时间:2024/06/08 08:31
1.说明一点问题
-我们已经在上上篇博客中证明了:通过交换相邻元素进行的任何排序算法平均需要Ω( n ^ 2 )时间。
这个定理对一整类只进行交换相邻元素还包括未发现的算法适用。这个下界告诉我们,为使一个算法突破这个下界,我们就不可仅交换相邻的元素,而是要通过交换相距较远的元素,使得一次交换,不再消除一个逆序,而是有可能通过一次交换,消除多个逆序。
2.算法基本思想
- 算法使数组中任意间隔为h的元素都是有序的(满足这一条件对的数组称为 - h有序数组)。一个h有序数组就是h个互相独立的有序数组编制在一起组成的一个数组。
(图片中用的是w表示h,且假设n / w 为整数) - 我们要做的无非是将n个数分为w的子数组(图中每列)。我们每次对每列排序,这样可以使得数组中任意间隔为h的元素都是有序的。再减少h的值,进行同样的操作。因此我们不难看出,矩阵宽度随着h的减少也逐渐缩短。直到h减少为1,此时上图只有一列,我们要对这一列进行排序(相邻的元素间),进行的进行最后一次排序。最后一次排序,实质上依旧为”交换”相邻元素的算法,但得益于先前的排序过程,已经减少了一定数量的逆序,使得这趟排序只用进行较少次数的”交换”操作。
3.算法基本实现
void Shell_Sort( int A[] ,int N){ int h = 1; int temp; int i , j ; while( h < N / 3 ) h = 3 * h + 1;/* 1 4 13 40 121 364 ....*/ while( h >= 1 ) { for( i = h; i < N; i ++ ) { for( j = i ; j >= h && A[ j ] < A[ j - h ]; j -= h) { temp = A[ j ]; A[ j ] = A[ j - h ]; A[ j - h ] = temp; } } h = h / 3; }}
4.算法分析
< 1 >
正如前文提到的一样, 我们只需能完成对每一列的排序即可,(我们每次只需对很小的子数组排序,却使得有可能消除多个逆序),我们不必过于深究每次采用什么排序方法。我们要在意的是算法的主体框架已经固定,唯一能够让我们选择的无非是h如何变化。然而得益于插入排序的一些性质,如当待排序已基本有序情况下,插入排序可以达到线性时间,这与“希尔排序不断使待排元素有序”这一思想仿佛是地造天设的一对。
( 上面算法的实现使用了序列1 / 2 ( 3 ^ k - 1 ),从N / 3 开始递减至 1,我们将这个序列称为 “递增序列”。
)
因此我们选择的递增序列成为影响希尔排序的主要因素。- 另一个希尔排序依赖的重要定理是:
当一个"h 有序"的数组按照增幅k排序后,仍是“h有序”的.
- 希尔排序更高效的原因是它权衡了子数组的规模和有序性。
< 2 >
- 使用希尔增量的最坏情况
递增序列成为影响希尔排序的主要因素,为我们不难得到一个序列,来分析最坏情况下希尔排序的表现。- 希尔增量是希尔排序中希尔给出的增量序列ht = n / 2, h[k] = h[k+1] / 2,即{n/2, (n / 2)/2, …, 1}。
- 我们给定一个数组(大小为N且假设N为2的幂)作为输入,他的偶数位置上有N/2个同为最大值的数(N/2个相同的数),奇数位置上有N/2个同为最小值的数(N/2个相同的数)。由于除最后的那个增量是外其余增量均为偶数,因此但我们进行最后一次排序前,数组不会发生变化。同为最大值的N/2个数依旧处于偶数位置上,同为最小值的N/2个数依旧处于奇数位置上。这使得整个数组中逆序对数没有发生变化。将第 i 个(i <= N/ 2 )最小在位置2 * i - 1 上,我们需要在数组中移动 i - 1 个间隔(如第N/2个最小的数,在位置N - 1上,要它移动到 N /2号位置上 ).这样我们仅仅将N / 2 个最小的元素移动到正确位置上,我们就需要∑ (1 →N / 2 ) (i - 1 ) = Ω( N ^ 2 ).
- 带有增量h[ k ] 的一趟排序由h[ k ]个N / h[ k ]个插入排序组成,插入排序时间复杂度为二次的,因此一趟排序总开销是Ο( h[ k ] * ((N / h[ k ]) ^2))= Ο( N ^ 2 / h[ k ] ).对每趟排序求和的得到一个几何级数(详见《数据结构与算法分析:C语言描述》),我们可以得到总界Ο(N ^2 )。
- 综上我们可以得到使用希尔增量时希尔排序最坏情况下运行时间为Θ(N ^2 ).
(上面关于增量序列的选择问题稍微比较简短,希望以后能继续学到更多知识,以完善这篇博客,也希望各位能继续深入理解。)
阅读全文
0 0
- 希尔排序
- 希尔排序
- 希尔排序
- 希尔排序
- 希尔排序
- 希尔排序
- 希尔排序
- 希尔排序
- 希尔排序
- 希尔排序
- 希尔排序
- 希尔排序
- 希尔排序
- 希尔排序
- 希尔排序
- 希尔排序
- 希尔排序
- 希尔排序
- 欢迎使用CSDN-markdown编辑器
- sourceinight4使用
- 操作系统-内存管理-内存与外存的对换(swapping)
- tensorflow学习笔记(一) --- 一元线性模型
- Team的创建和规划
- 希尔排序
- poj 3317 Stake Your Claim(极大极小搜索经典 a-b+剪枝+记忆化dp)
- java学习记录(1)-jvm安装
- Java —— 多线程笔记 三、线程通信 与 线程组、线程异常
- 【C++】联发科初赛第三题《进制数转换》
- 计蒜客 2017 NOIP 提高组模拟赛(一)Day1
- 什么叫工业4.0,这篇接地气的文章终于讲懂了
- 减小包大小
- ubuntu14.04中安装NVIDIA(GTX650)驱动以及cuda8.0