Splay树简介

来源:互联网 发布:医院釆用什么数据库 编辑:程序博客网 时间:2024/05/01 00:54

这篇虽不是完全关于linux kernel,但也有些相关。

作者:硅谷农民 http://nongmin.coku.com

计算器算法和数据结构中,有各种多样的树,比如AVL树,红黑树,B+树等等,这几种树主要的主要目的是尽量保持平衡,保证即使在最坏情况下,时间复杂度是O(logN),也就是说,从根节点到最底层的叶子节点,路径不会相差太远。比如B+树,它通过节点的分裂来保持尽量平衡,而且这种树比较散,高度不高,访问路径都比较短,比较适合在数据库中作索引。


但是今天我要说一说splay树,我不知道中文叫什么名字,也许该叫它「变根树」。Splay树与众不同的是:它并不一味追求平衡,而是追求整体的效率。当一个节点被访问以后,通过树的旋转,这个节点被移动到最上层,成为新的根节点。旋转以后,这棵树有可能变得很不平衡。但是,同样一个节点如果再被访问的话,只用一次比较就可以返回了。当这棵树被访问了一段时间以后,常访问的节点就会浮到了上面(靠近根节点),也就是说,splay树天生就有缓存的功能!


Splay
树的主要理论依据(assumption)是应用程序访问树节点的时候,总是有偏颇性的,有些节点访问得多,有些节点访问得少,不停地将访问得多的节点移到顶部,对整个访问效率有好处。理论的证明大家可以参考文献。对有些应用来说,例如网络包处理,这种树能起很大的作用,因为在相近的时间段中,网络包有同样IP的可能性很大。

但是。Splay树的最大缺点是搜索是可能需要写很多次内存,在现代的CPU中,写内存的开销相对而言是挺大的,所以有一种观点是Splay树不适合用在内核编程中。


我欣赏splay树的算法,但我更欣赏它背后说折射出来的思想:尽量追求个体利益最大化,并不能保证总体利益的最大化。二叉树不平衡了,有些节点的访问开销会比平衡的二叉树大,但总体而言,它又提高了效率。一味钻牛角尖,还不如有时候适当的妥协来得更有用一些。计算器算法中,同样的想法也有很多,比如,Linux地输入输出调度器(IO scheduler)设计,一般的想法就是让磁盘越忙,效率越高,但是2.6的内核中,Anticipatory IO Scheduler采取了等一等的策略,反而得到总体的更高效率。


从算法中懂得了一些生活的道理,大概也是搞计算机的一些乐趣吧...


硅谷农民
2006 4/17



参考:

http://www.cs.cmu.edu/~sleator/papers/self-adjusting.pdf
http://en.wikipedia.org/wiki/Splay_tree
http://www.link.cs.cmu.edu/cgi-bin/splay/splay-cgi.pl

 

 

更多的资料见:

http://www.fcicq.net/wp/?p=107

http://blog.chinaunix.net/u/9831/showart_109148.html

http://bbs.chinaunix.net/viewthread.php?tid=1122220

原创粉丝点击