当前课程知识点:数据结构(下) > 第十二章 排序 > (c1) 希尔排序:Shell序列 > 12c1-5: Shell序列
我们在这里结识的第一个步长序列
就出自于希尔排序的发明者
Shell本人之手
我们接下来就会看到
这个序列存在很多缺点
尽管从某种意义上来看
它非常优美
因为我们注意到
它的每一项都整齐划一的是
2的k次方的形式
也就是说每一项都是前一项的两倍
那么这个序列的缺点
就集中体现在它在最坏情况下
可能会导致n平方量级的运行时间
为此我们可以构造这样一个
具体的实例
我们首先来考察
两个整数区间
也就是0到2的n减1次方
以及2的n减1次方
到2的n次方
其中包含的整数都是2的N减1次方个
只不过在数值上前者更小
而后者更大
接下来我们将这两组整数
分别的打乱次序
并相应的构成两个字序列A以及B
然后我们按照ABAB交错的形式
将它们会合为一个完整的序列
比如对于n等于4而言
这就是一个可能的生成序列
可以看到它是有两个
规模都为八的子序列交错构成的
子序列A中的元素
都被安置在秩为奇数的位置
而对称的子序列B中的元素
都被安放在秩为偶数的位置
现在我们假设就采用希尔的序列
来对它进行排序
我们考察算法的倒数第二步
也就是以二为间隔的
那轮排序刚刚结束的时候
我们可以断言
此时序列的组成必然是这样
也就是说原先来自于子序列A中的
那些元素
依然占据着秩为奇数的位置
而且这八个元素的相对次序
已经是完全有序的
同时对称的原先来自于子序列
B中的那些元素
也必然仍就占据着
秩为偶数的那些位置
而且仅就这八个元素而言
它们之间的相对次序也已经是有序的
这两个字序列在这个时刻的有序性
并不难理解
在刚刚过去的这一论排序中
这两个子序列
恰好各自就是独立成为一列
因此所谓的2-sorting
其实就是对这两列分别进行排序
所以它们的结果自然应该是
各自有序的
当然刚才我们所指出的另一个现象
更会引发我们的好奇
也就是说无论我们此前
经历过多少趟的排序交换
来自于子序列A和子序列B中的元素
始终都是分别占据着
秩为奇数和偶数的位置
二者泾渭分明没有任何的元素互换
为此我们需要反观希尔序列
我们注意到在这个序列中
除了第一项其余各项都是偶数
没错 偶数
这就意味着在这些项
所对应的每一个重组的
二维矩阵中同属一列的元素
或者都来自于集合A
或者都来自于B
自然不会发生A与B之间的元素互换了
因此直到执行完2-sorting之后
这两个序列必然都是井水不犯河水
互补相扰
然而这恰恰正是问题所在
对于这样的序列
在接下来的最后一趟排序
也就是one-sorting中
我们必然需要付出高昂的代价
因为在这个序列中
依然包含着大量的逆序对
我们不妨只统计B中的元素
所参与构成的逆序对
首先是全局最大的15
它与其后的七
就构成了一个逆序对
接下来再考察4大的14
不难看出
它与6和7构成了两个逆序对
再接下来是13
它与5 6 7 总共构成了
三个逆序对
以下类推元素12
将与4 5 6 7总共构成四个逆序对
我想你已经看出其中的规律了
没错
B中的各元素所参与构成的逆序对数
恰好构成一个算术级数
没错算术级数
我想经过这门课的学习
你现在应该有了一个直觉的反馈
是的
这样一个算术级数对应的将是
平方量级的运行成本
也就是说算法的效率
已经退化为个与起泡排序相当了
当然在这里我们并不满足于
仅仅指出希尔排序的缺点
而更重要的是
我们需要探究导致这种缺陷的根源
让我们将目光再次投回到希尔序列
我们会发现与其说
其中大量的元素都是偶数
不如更一般的说
其中的各项并非互素
因此每一轮的排序
都有大量的精力浪费于
对前一抡排序工作的重复之上
是的
相邻项要尽可能的互素
这样我们也就拿到了
打开新方法大门的钥匙
-选课之前
--写在选课之前
--宣传片
-考核方式
--考核方式
-OJ系统说明
--关于OJ
--1-注册与登录
--2-界面与选课
--3-提交测试
-关于课程教材与讲义
--课程教材与讲义
-关于讨论区
--关于讨论区
-微信平台
--html
-PA晋级申请
--PA晋级
-(a)概述
--07A-1 纵览
--07A-5 接口
-(a)概述--作业
-(b1)BST:查找
-第七章 二叉搜索树--(b1)BST:查找
-(b2)BST:插入
-(b2)BST:插入--作业
-(b3)BST:删除
-第七章 二叉搜索树--(b3)BST:删除
-(c)平衡与等价
-(c)平衡与等价--作业
-(d1)AVL树:重平衡
-第七章 二叉搜索树--(d1)AVL树:重平衡
-(d2)AVL树:插入
-(d2)AVL树:插入--作业
-(d3)AVL树:删除
-(d3)AVL树:删除--作业
-(d4)AVL树:(3+4)-重构
-(d4)AVL树:(3+4)-重构--作业
-本章测验
--章节测验
-(a1)伸展树:逐层伸展
--习题
-(a2)伸展树:双层伸展
--习题
-(a3)伸展树:算法实现
--习题
-(b1)B-树:动机
--习题
-(b2)B-树:结构
--习题
-(b3)B-树:查找
--习题
-(b4)B-树: 插入
--习题
-(b5)B-树: 删除
--习题
-(xa1)红黑树:动机
--习题
-(xa2)红黑树:结构
--习题
-(xa3)红黑树:插入
--习题
-(xa4)红黑树:删除
-本章测验
--习题
-(b)散列:原理
--09B-3 数组
--09B-4 原理
--09B-5 散列
--09B-6 冲突
--习题
-(c)散列:散列函数
--习题
-(d1)散列:排解冲突(1)
--习题
-(d2)散列:排解冲突(2)
--习题
-(e)桶/计数排序
--习题
-本章测验
--本章测试
-(a1)需求与动机
--习题
-(a2)基本实现
--习题
-(b1)完全二叉堆:结构
--习题
-(b2)完全二叉堆:插入与上滤
--习题
-(b3)完全二叉堆:删除与下滤
--习题
-(b4)完全二叉堆:批量建堆
--习题
-(c)堆排序
--习题
-(xa1)左式堆:结构
--习题
-(xa2)左式堆:合并
--习题
-(xa3)左式堆:插入与删除
-本章测验
--本章测试
-(a)ADT
--习题
-(b1)串匹配
--习题
-(b2)蛮力匹配
--习题
-(c1)KMP算法:从记忆力到预知力
--习题
-(c2)KMP算法:查询表
--习题
-(c3)KMP算法:理解next[]表
--习题
-(c4)KMP算法:构造next[]表
--习题
-(c5)KMP算法:分摊分析
--习题
-(c6)KMP算法:再改进
-(d1)BM_BC算法:以终为始
-(d2)BM_BC算法:坏字符
-(d3)BM_BC算法:构造bc[]
-(d4)BM_BC算法:性能分析
-(e1)BM_GS算法:好后缀
-(e2)BM_GS算法:构造gs表
-(e3)BM_GS算法:综合性能
-(f1)Karp-Rabin算法:串即是数
-(f2)Karp-Rabin算法:散列
-本章测验
--本章测试
-(a1)快速排序:算法A
-- 12a1-5: 实例
--习题
-(a2)快速排序:性能分析
--习题
-(a4)快速排序:变种
-(b1)选取:众数
-(b3)选取:通用算法
--习题
-(c1) 希尔排序:Shell序列
--习题
-(c2)希尔排序:逆序对
-本章测验
--本章测试