2-3树是这样的一棵多路查找树:其中的每一个结点都具有两个孩子(我们称它为2结点)或三个孩子(我们称它为3结点)。
一个2结点包含一个元素和两个孩子(或没有孩子),且与二叉排序树类似,左子树包含的元素小于该元素,右子树包含的元素大于该元素。不过,与二叉排序树不同的是,这个2结点要么没有孩子,要有就有两个,不能只有一个孩子。
一个3结点包含一小一大两个元素和三个孩子(或没有孩子),一个3结点要么没有孩子,要么具有3个孩子。如果某个3结点有孩子的话,左子树包含小于较小元素的元素,右子树包含大于较大元素的元素,中间子树包含介于两元素之间的元素。
并且2-3树中所有的叶子都在同一层次上。
事实上,2-3树复杂的地方就在于新结点的插入和已有结点的删除。毕竟,每个结点可能是2结点也可能是3结点,要保证所有叶子都在同一层次,是需要进行一番复杂操作的。
一.2-3树的插入实现
对于2-3树的插入来说,与二叉排序树相同,插入操作一定是发生在叶子结点上。可与二叉排序树不同的是,2-3树插入一个元素的过程有可能会对该树的其余结构产生连锁反应。
2-3树插入可分为三种情况。
1)对于空树,插入一个2结点即可,这很容易理解。
2)插入结点到一个2结点的叶子上。应该说,由于其本身就只有一个元素,所以只需要将其升级为3结点即可。我们希望从左图的2-3树中插入元素3,根据遍历可知,3比8小、比4小,于是就只能考虑插入到叶子结点1所在的位置,因此很自然的想法就是将此结点变成一个3结点,即右图这样完成插入操作。当然,要视插入的元素与当前叶子结点的元素比较大小后,决定谁在左谁在右。例如,若插入的是0,则此结点就是“0”在左“1”在右了。
3)要往3结点中插入一个新元素。因为3结点本身已经是2-3树的结点最大容量(已经有两个元素),因此就需要将其拆分,且将树中两元素或插入元素的三者中选择其一向上移动一层。复杂的情况也正在于此。
2-3树是一种多路搜索树,每个内部节点可以有两个或三个子节点。
在代码中,当需要插入一个新节点时,首先进行遍历查找插入位置。如果插入位置是一个3节点,即该节点已经有两个元素,无法再插入新元素,则需要进行节点的拆分。
拆分操作会将当前节点拆分为两个节点,其中一个节点成为新的根节点,另一个节点作为根节点的子节点。其中,拆分节点的中间元素会被提升为根节点的元素,拆分节点的左边元素会成为根节点的左子节点,拆分节点的右边元素会成为根节点的右子节点。
如果拆分操作导致根节点的拆分,即原本的根节点为一个3节点,拆分后根节点变为一个4节点,则需要再次进行拆分,将根节点拆分为两个节点,并新建一个根节点作为树的新根节点。
通过这样的拆分操作,可以保持2-3树的平衡性,避免树的高度过高,提高搜索效率。
总结而言,这段代码的作用是在2-3树中进行插入操作,并实现树的自动平衡。通过拆分节点,保持树的平衡性,避免树的高度过高,提高了插入操作的效率和树的搜索性能。
二.2-3树的删除实现
在2-3树中删除元素时,需要考虑不同的情况。下面对每种情况进行详细的解释:
1) 删除元素位于一个3结点的叶子结点上:这种情况下,只需要在该结点处删除该元素即可,不会影响到整棵树的其他结点结构。例如,删除元素9,只需要将叶子结点9改为只有元素10的2结点。
2) 删除的元素位于一个2结点上:这种情况下,删除该结点会导致整棵树不满足2-3树的定义,因此需要进行特殊处理。如果删除了一个2结点,例如删除结点1,会破坏4结点的结构。此时,我们需要调整整棵树的结构。
- 如果该结点的双亲也是2结点,并且双亲拥有一个3结点的右孩子,可以进行左旋操作,将6作为双亲,4作为6的左孩子,7作为6的右孩子。
- 如果该结点的双亲是2结点,并且它的右孩子也是2结点,需要进行整体的结构变换。我们的目标是让7变成3结点,所以需要将比7稍大的元素8下移,然后将比8稍大的元素9放在8的位置上。最后进行左旋操作,使树达到平衡状态。
3) 删除的元素位于一个3结点的分支结点上:如果要删除的元素位于一个3结点的分支结点上,通常会选择该元素的前驱或后继元素来补位。例如,删除12、14结点的12,可以选择10作为补位元素,并将该元素上升到删除位置。
4) 删除的元素位于非叶子的分支结点上:如果要删除的元素位于非叶子的分支结点上,通常会选择该元素的前驱或后继元素来补位。例如,删除4结点,可以选择前驱元素1或后继元素6来补位。
在删除过程中,需要注意整棵树的平衡性,使用合适的旋转和结构变换操作来保持树的平衡状态。通过这些处理,可以确保删除操作不破坏2-3树的定义和性质。
总结而言,删除2-3树中的元素时,根据不同的情况进行相应的处理,包括直接删除叶子上的元素、处理2结点的情况、处理3结点的情况以及处理非叶子分支结点的情况。通过合适的操作来维持树的平衡性,并保持2-3树的定义和性质。
当然,如果对2-3树的插入和删除等所有的情况进行讲解,既占篇幅,又没必要,总的来说它是有规律的,需要你们在上面的这些例子中多去体会后掌握。