Chinaunix首页 | 论坛 | 博客
  • 博客访问: 165721
  • 博文数量: 43
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 675
  • 用 户 组: 普通用户
  • 注册时间: 2013-01-26 00:58
文章分类
文章存档

2014年(2)

2013年(41)

我的朋友

分类: C/C++

2013-08-07 17:36:20

    日志系统保存缓存的就是伸展树,所以简单介绍下。
      假设想要对一个二叉查找树执行一系列的查找操作。为了使整个查找时间更小,被查频率高的那些条目就应当经常处于靠近树根的位置。于是想到设计一个简单方法, 在每次查找之后对树进行重构,把被查找的条目搬移到离树根近一些的地方。splay tree应运而生。splay tree是一种自调整形式的二叉查找树,它会沿着从某个节点到树根之间的路径,通过一系列的旋转把这个节点搬移到树根去。
     总体就是一个思想,在向下查找的过程中,把不符合标准的按照左小右大的原则分别放在左右两棵树上。等到找到想找的节点,把它作为新的根节点,然后把左右棵树作为这个根节点的子树。
这样就实现了查找节点的上移。

同样,如果是插入的话,移上来的会是两个最接近插入数据的,然后把需要插入的节点作为根节点。

那么怎么移动到左右两边呢?

按照常规思路,无非就是从根节点开始,大的放左边,小的放右边。

如下图。

 

在划分的时候,就这样。

就左树而言,新加入的子树放在左树的最右边的节点。(因为二叉树的查找肯定是缩小范围,这样的话,越后面的节点与查找节点的差距越小。)

但这样存在一个问题,那就是很多时候无法使得树的结构变平衡。

比如

在划分的时候,就这样。

就左树而言,新加入的子树放在左树的最右边的节点。(因为二叉树的查找肯定是缩小范围,这样的话,越后面的节点与查找节点的差距越小。)

但这样存在一个问题,那就是很多时候无法使得树的结构变平衡。

比如

比如左左,左左结构就会三点一线,影响平衡,这种情况最好进行旋转。

这样移出去的子树就会不平衡。

尽量让插入的每部分都平衡以此来保证总体的平衡。

 

当然左右或者右左就不需要了,首先,这种结构是否旋转对于是否平衡影响不大(直观是这样,我不会证明哈),其次,这种结构本身就是折线,怎么旋转....

所以

就得到了左左或者右右需要旋转,两点一组

这样就得到了自顶向下的方法

同时还有自底向上的,也是遇到左左或者右右需要做不同的处理。

本来就是以要访问的节点X为轴,一直旋转,直到X转到根节点。

但是如果XX的父节点,X父节点的父节点三点一线的话,就需要特殊处理,需要先以X的父节点为轴转动,再以X为节点转动。也是为了平衡...

代码我自己写了一份,跟lighttpd的很相似
这个网址有用C++实现的代码,可以参考下
http://www.cnblogs.com/huangxincheng/archive/2012/08/04/2623455.html

阅读(2013) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~