当前课程知识点:数据结构(下) > 第八章 高级搜索树(上) > (a3)伸展树:算法实现 > 08A3-7 综合评价
最后我们来对伸展树的性能和特点
做一个综合的回顾
首先需要再次强调的是
相对于此前的AVL树
伸展树显得更为灵活和变通
它不需要再记录节点的高度
或者平衡因子之类的附加信息
因此从编程实现的角度来看会更为简便易行
而另一方面 就时间复杂度而言
依然可以确保是在logn的范围以内
这也与此前的AVL树相当
请注意这样一个复杂度界限
并没有任何更多的先决条件
包括我们最初所介绍的局部性的条件
事实上 当局部性存在的时候
伸展树的性能还会更高
不妨考虑一种极端的情况
也就是局部性非常强的时候
在这个时候 即便数据集的规模能够达到n
在相当长的一段时间之内
我们所访问的数据
可能只是其中很少的一部分
比如只有远远小于n的k个
而我们的操作次数呢 却要远远的大于n
比如你用电脑的过程往往就是这样
尽管你的硬盘上所存放的数据文件等等
是数以万计甚至几百万计
但是在很短的时间内
你所经常使用的数据
往往只是其中非常低的一个百分比
比如当你在我们的online judge上
苦苦做题的几天之内
你所访问的数据很可能只是
你的硬盘中屈指可数的那么几个文件
是不是
也就是说 这类情况的特点 可以概括为
尽管我们所存放的数据非常的多
但是在相当长的时间内
我们所访问的只是其中很小的一部分
如果我们把这个数据集组织为一棵BST
并且采用伸展树的策略进行自我调整
那么可想而知的是
经过一段时间的使用之后
我们最常用的那部分数据
都会逐步的集中到树根的附近
以至于其他部分的数据几乎可以忽略掉
他们存在与否 已经不甚重要了
也就是说 我们完全可以认为数据集
无非就是一个规模为k而不是n的一棵BBST
这样一棵规模为k的BBST 其访问的效率
自然就应该接近于每次是logk而不是logn
因此对于任何一个足够长的操作序列而言
其中每一次操作的均摊时间复杂度
也就大致是logk
当然在达到这种状态之前
我们大致要经过常规的n次操作
每次的操作时间复杂度是logn
你使用电脑的经历
也应该能够验证这样一个规律
难道不是吗
你的每一台新安装的电脑
不都是在经过一段时间的应用之后
就会变得非常顺手
使得在接下来的足够长的时间之内
都能够飞速的运转
是的 这是因为通常的操作系统
都充分利用了数据访问的局部性
从而使得缓存的命中率能够达到尽可能的高
当然 尽管具有以上的诸多优点
我们不得不说 伸展树也并非十全十美
比如尽管它的分摊效率很好
它依然不能够保证杜绝单次最坏情况的出现
实际上 在此前我们已经看到
伸展树的形状在任何时刻
通常都是不平衡 甚至是极其不平衡
因此我们完全可能在某一个不幸的时刻
需要访问一个足够深甚至是最深的节点
尽管伸展树在此后会随即
将这条路径缩短至接近一半
但是在此前的这次查找过程中
你不得不仍需付出沉重的代价
因此在对单次操作效率十分敏感的场合
伸展树依然是不能适用而胜任的
这类例子虽然不多 但也的确存在
比如在手术室里 控制手术器械的程序
断乎不能采用伸展树这一类的数据结构
当然也正如我们所看到的
伸展树的复杂度分析是一个非常复杂的课题
在这里我们只是以形象的方式
通过举例进行了一定的验证
而严格的证明却要更加复杂
关于这一结论的严密证明
请参照我们的习题[8-2]
-选课之前
--写在选课之前
--宣传片
-考核方式
--考核方式
-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)希尔排序:逆序对
-本章测验
--本章测试