二叉树实战(八) - 2-3查找树

一、平衡树

我们知道二叉查找树的查询效率比单纯的链表和数组的效率要高,大部分情况下是这样的,但是在最坏的情况下,二叉查找树的性能还是很糟糕的。

例如我们一次在二叉查找树种插入9,8,7,6,5,4,3,2,1。那么构造出来的树就会是下图这样的:
 

我们会发现,如果想查找1这个元素,查找的效率依旧会很低。效率低的原因是 树不平衡,全部是左向分支,如果我们有一种方法,能不受插入数据的影响,让生成的 树都像完全二叉树那样,那么即使在最坏额情况下,查找的效率依旧会比较好。

二、2-3查找树

为了保证树的平衡性,我们需要一些灵活性,因此我们允许树中的一个结点保存多个键。准确的说,我们将一棵标准的二叉查找树中的结点称为2-结点(含有一个键和两条链),而现在我们引入3-结点,它含有两个键和三条链。2-结点和3-结点中的每条链都对应着其中保存的键所分割产生的一个区间。

1、2-3查找树的定义

一棵2-3查找树要么为空,要么满足下面两个要求:

  • 2-结点:含有一个键及两个链,左连接指向2-3树中的键都小于该结点,右链接指向的2-3树中的键都大于该结点。
  • 3-结点:含有两个键和三条链,左连接指向2-3树中的键都小于该结点,中链接指向的2-3树种的键都位于该结点的两个键之间,右链接指向的2-3树中的键都大于该结点。

2、2-3查找树的查找逻辑

判断一个键是否在树中,我们先将其和根节点的键进行比较,如果它和其中任意一个相等,则查找命中,否则我们就根据比较的结果,找到指向对应区间的链接,并在其指向的子树中递归进行查找。如果找到最后为空连接的时候,则说明查找未命中。

3、2-3查找树的插入逻辑

2-3查找树的插入逻辑可以分为以下几种情况和类型:

1). 向2-结点插入新键

往2-3树中插入元素和之前我们往二叉查找树中插入元素一样,首先要进行查找,然后将节点挂到未找到的结点上。2-3树之所以能够保证在最差的情况下的查询效率是因为其在插入之后仍能保持平衡状态。如果查找后未找到的结点是一个2-结点,那么很容易,我们只需要将新的元素放到这个2-结点里面,使其变成一个3-结点即可。

2). 向一棵只含有一个3-结点的树中插入新键

假设2-3树中只包含一个3-结点,这个结点有两个键,没有空间来插入第三个键了,最自然的方式就是假设这个结点能存放三个元素,暂时将其变为一个4-结点,同时他包含四条链接,然后我们将这个4-结点的中间元素提升,左边的键作为其左子节点,右边的键作为其右子节点。插入完成后,就变为了一个平衡2-3查找树,树的高度也+1.

示意图如下: 

3). 向一个父节点为2-节点的3-结点中插入新键

和上面的情况一样,我们可以将新的元素插入到3-结点中,使其成为一个临时的4-结点,然后将该结点中的元素提升到父节点即2-结点中,使其父结点成为一个3-结点,然后将左右结点分别挂在这个3-结点的恰当位置。

4). 向一个父结点为3-节点的3-结点中插入新键

当我们插入的结点是一个3-结点的时候,开始的流程和上面一样,先生成一个临时的4-结点,然后进行拆分,将中间元素提升至父节点,但是此时父节点也是一个3-结点,插入后,父节点也变为了4-结点,这样我们需要继续讲中间元素提升至其父节点,知道遇到一个父节点是2-结点的,然后将其变为3-结点后,就不需要在进行拆分了。这里就不在放流程图了,基本逻辑和上面的一样,只不过多了父节点的逻辑。需要注意的是,如果插入结点和根结点的路径全部都是3-结点时,最终我们的根结点会变成一个临时的4-结点,需要将根节点拆分为两个2-结点,然后树的高度+1.

4、2-3树的性质

通过对2-3树的插入操作的分析,我们可以发现,插入的时候,2-3树需要一些局部变换来保持2-3树的平衡。

一个完全平衡的2-3树有如下的性质:

  1. 任意空链接到根节点的路径长度都是相等的。
  2. 4-结点变换为3-结点的时候,树的高度不会发生变化,只有当根节点是临时的4-结点的时候,分解根结点会使得树的高度+1
  3. 2-3查找树和普通二叉查找树的最大区别在于,普通二叉查找树的是自顶向下生长,而2-3树是自底向上生长。

5、2-3树的实现

直接按照上面我们讲述的逻辑实现2-3树的话,逻辑会很复杂,因为我们需要处理好以下逻辑:

  1. 需要处理不同的结点类型,实现起来逻辑非常繁琐;
  2. 需要多次比较操作来讲结点下移;
  3. 需要上移来拆分4-结点;
  4. 当拆分4-结点的时候,遇到的情况会有很多种。

总结来说就是,2-3查找树的实现比较复杂,在某些情况下插入后的平衡操作会使得效率降低。

这里提出2-3查找树并进行一定篇幅的讲解的原因是:其作为平衡树,实现的是思想和概念对我们后续了解、学习和实现红黑树、B树和B+树非常重要。

 

posted @ 2020-07-05 14:13  灰色飘零  阅读(93)  评论(0)    收藏  举报