摘要:
普通BST并不能保证在多次操作后仍然保持良好的性能。因此我们需要一种BST,是的每次插入和搜索的开销是该树大大小的对数函数。2-3-4树就是这样一种能够保持平衡的BST。
2-3-4树介绍
为了保证BST是平衡的,我们需要树具备一定的灵活性。2-3-4树选择的方法是令结点可以容纳一个以上的关键字。更明确地说,我们将使用三种结点:2-结点,3-结点,4-结点。分别可以容纳1、2、3个关键字。关键字将后续子节点分成区间。如图:
性质:一棵平衡2-3-4搜索树,所有指向空树的链接到根的距离都相同。
解释:这里所谓空树,就是外部链接,即叶子节点的两个NULL链接。所以也可以理解为在平衡2-3-4树中所有叶子结点深度相同。
在2-3-4树中插入新关键字
为了向2-3-4树中插入新节点,我们可以先执行一次失败的搜索,然后插入该节点。但这样新树会不平衡。2-3-4树之所以重要,主要原因在于每种情况下,我们可以进行插入并仍能保持完美的平衡状态。例如:当新关键字插入到2-结点时,可以将其变成一个3-结点。当新关键字插入到3-结点时,可以将其变成一个4-结点。当心关键字插入到4-结点时,可以将其分裂成两个2-结点,并将中间的关键字向上传递,插入到父节点中。如果被分裂4-结点的父节点也是4-结点,可以一直向上不断分裂。一种更容易的方法是:在向下搜索树的过程中,分裂任何遇到的4-结点,从而保证搜索路径不会在一个4-结点终结。我们自上而下地插入过程中,所有遇到的4-结点全部分裂,这也保证了在进入下一层时,出发点绝对不会是4-结点。
关键一点是:这些分裂完全是局部的——除了分裂结点及其父节点部分,其他部分不需要检查或修改,完全不受影响。这为我们维护书的平衡提供了保障。
另外一个细节问题是:只要树根变成4-结点,就及时将其分裂为三个2-结点。分裂树根是唯一的会令树深度增加一层的行为。
下面我们给出一个2-3-4树插入图例。
性质:在n个结点的2-3-4树中搜索,最多访问lgn+1个结点。
解释:根据基本性质,我们有树根到叶子节点深度全部相等。插入例程对于树的深度没有影响,仅当分裂树根时深度加一。如果所有结点为2-结点,根据BST的性质,容易得出上述结果;当存在3-和4-结点时,高度只有可能更低。
性质:对n个结点的2-3-4树进行插入,最坏情况下需要对少于lgn+1个结点进行分裂。平均情况下,所需分裂次数可能少于1。
解释:可能的最坏情况实在通向插入点的路径上所有结点都是4-结点,将全部被分裂。但一般而言不会出现这种情况,因为树中不会存在很多4-结点。
讨论
对于2-3-4树的搜索操作,上述描述已经可以给出一个最坏情况下取得良好性能的算法了。虽然我们确实可以写出这样的算法,但其中涉及到的结点控制及分裂过于复杂。这些额外开销可能会导致这些算法比标准BST还慢。应当考虑到平衡的主要目的是为了提供最坏情况保障,提供保障的开销当然也应当越低越好。
因而我们将通过红黑树(Red Black Tree)来作为实现2-3-4树的载体。下一章将深入讨论红黑树的性质及实现。