伸展树
对于m次连续搜索操作有很好的效率,保证从空树开始任意M次对树的操作最多花费O(MlogN)的时间。
伸展树会在一次搜索后,对树进行一些特殊的操作。只要一个节点被访问过,那么就用AVL树的旋转方法把这个节点移动到根节点。
具体来说,分为以下情况:
- 如果访问节点X的父节点是树根,那么我们只要X和树根;这就是沿着访问路径上的最后的选择;
- X有父亲(P)和祖父(G),存在两种情况以及对称的情形要考虑:
①之字形(zig-zag):这里X是右儿子,P是左儿子形式,反之亦然(如下图所示);该情况,需要执行一次AVL那样的双旋转,详情见【数据结构与算法分析】02:树(1)
②一字型(Zig-zig):X和P或者都是左儿子,或者都是右儿子(如下图所示);这种情况下,把下图左边的树变换成右边的树;
虽然从一些小例子很难看出来,但是展开操作不仅将访问的节点移动到根处,而且还把访问路径上的大部分节点的深度大致减少一半的效果(某些浅的节点最多向下推后两个层次)。
B-树
一种不是二叉树的常用查找树,是一种平衡的多路查找树。诞生的原因:存储更多的指针信息,以降低I/O操作数。
阶为M的B-树是一棵具有以下结构特性的树:
- 树的根或者是一片树叶,或者其儿子树在2和M之间;
- 除根外,所有非树叶节点的儿子树在[M/2]和M之间;
- 所有的树叶都在相同的深度上;
- 所有数据都存储在树叶上,每个内部节点上皆含有指向该节点各儿子的指针P1,P2,…..,Pm和分别代表在子树P2,P3,……,Pm中发现的最小关键字的值k1,k2,…..,km-1;
- 对每一个节点,其子树P1中所有的关键字都小于子树P2的关键字
B-树示意图:
- B-树的插入操作(4阶B-树,又称2-3-4树,3阶B-树叫做2-3树,下面以2-3树为例,来描述B-树的操作)
【我们用椭圆表示内部节点(非树叶),每个节点含有两个数据;椭圆内短横线表示内部节点的第二个信息,表明该节点只有两个儿子;树叶用方框表示,框内含有关键字】
下面对树进行一次Insert(插入)操作,插入关键字为18的节点,结果如下:
【我们可以把该节点加到一片树叶儿不破坏2-3树的形状】
由于一片树叶只能容纳两个或三个关键字,所以上述做法不总是可能的,下面再插入关键字为1的节点,由于1所属节点已经满了,于是解决办法是构造两个节点,每个节点有两个关键字,同时调整它们父节点的信息,该方法可称为“分裂”,如下图:
然而这个想法也不总能够行得通,我们尝试插入19,如果构造两个节点,每个节点有两个关键字,就会得到下列的树:
这棵树,一个内部节点有了4个儿子,可我们只允许每个节点有3个儿子;该情况的解决方法就是,将该节点分裂成两个儿子;当然,该节点本身可能就是三个儿子节点之一,这样分裂节点其父节点就会有四个儿子,单我们可以在通向根的路径上一直分裂,直到根节点,或找到一个节点只有两个儿子;通过该方法,插入19得到如下所示的树: