之所以叫2-3查找树是因为一个节点可以含有2条或3条链接(每个链接需要用一个键值隔开,所以2-3查找树中的每个节点可以含有1或2个键值)。
2-3查找树的插入
和二叉查找树一样,首先需要进行一次查找,获得新的键值的插入位置。
插入的节点为2-节点
只需将新的键值加入到2-节点中,使其成为3节点。
插入的节点为3-节点
首先,临时使这个节点变为4-节点(拥有3个键值)
可以很容易的将这个4-节点转换为一个三节点的完美平衡2-3树(所有叶子节点的深度相同),如图
现在出现了一个问题,右边由转换而来的树的高度比左边大1(上图),如果将这个子树插入到原来的位置,会破坏原来的树的平衡性,为了解决这个问题,我们将k1插入到它的父节点中,如图(下图)
这时候,有两种情况
- 父节点为2-节点,那么k1的插入如上图,不需要进行别的操作,插入完成
- 父节点为3-节点,那么在k1插入后父节点将成为一个临时的4-节点(点一下<( ̄︶ ̄)↗[GO!]),这和我们最初遇到的情况一样,进行向上的递归处理
上面的递归有两种归宿
- 新节点被插入某个2-节点中
- 根节点变成一个临时的4-节点,这时只需要将根节点变为三个2-节点的树即可,类似于上面的转换,这时候树的高度整体加1
2-3查找树的删除
这个过程比插入一个结点更加复杂,因为我 们不仅要在(为了删除一个结点而)构造临时 4- 结点时沿着查找路径向下进行变换,还要在分解遗留的 4- 结点时沿着查找路径向上进行变换(同插入操作)
用2-3-4树的插入算法引入
类似我们在2-3查找树的基础上学习红黑树,我们在2-3-4树的插入算法的基础上学习2-3树的删除算法
- 2-3-4树中允许4-节点(3个键,4个子节点)
- 2-3-4树的插入算法需要沿查找路径向上和向下变换(向下变换:分解节点;向上变换:向上传递键值)
- 沿查找路径向下进行变换是为了保证当前结点不是4-结点(这样树底才有空间来插入新的键)
- 沿查找路径向上进行变换是为了将之前创建的4结点配平有的操作会形成4-节点
向下的变换和我们在2-3树中分解4-结点所进行的变换完全相同,即将一个4-节点分解为一棵包含3个节点的平衡树
- 如果根结点是4-结点,我们就将它分解成三个2- 结点,使得树高加1,类似于分解2-3树中的4-节点
- 如果遇到一个父结点为2-结点的4-结点,我们将4-结点分解为两个2结点并将中间键传递给它的父结点,使得父结点变为一个3-结点,如下图
- 如果遇到一个父结点为3- 结点的4- 结点,我们将4- 结点分解为两个2- 结点并将中间键传递给它的父结点,使得父结点变为一个 4- 结点
- 我们永远不会遇到父节点为4-节点的4-节点,到达树的底部之后, 我们也只会遇到2-结点或者3-结点,所以我们可以插入新的键
2-3 树中删除最小键的操作
从树底部的3- 结点中删除键
很简单,将一个3-节点转换为2-节点即可
从树底部删除2-节点中的键
从 2- 结点中删除一个键会留下一个空结点,一般我们会将它替 换为一个空链接,但这样会破坏树的完美平衡性
为了保证我们不会删除一个2- 结点,我们沿着左链接向下进行变换,确保当前结点不是2- 结点(可能是 3- 结点,也可能是临时的4- 结点)
在根节点上
- 如果根是 2- 结点且它的两个子结点都是2- 结点, 我们可以直接将这三个结点变成一个4- 结点,再从中删除键(这里讨论的情况为最小键k1)
- 否则我们需要保证根结点的左子结点不是2-结点, 如有必要可以从它右侧的兄弟结点“借”一个键来,先将兄弟节点中的最小键值插入到父节点,再将父节点中的最小键值插入左子节点,这样间接的“借”
沿子链(这里为最左子链)向下的过程中
- 如果当前结点的左子结点不是 2- 结点,完成
- 如果当前结点的左子结点是 2- 结点而它的亲兄弟结点不是 2- 结点,将左子结点的兄弟结点 中的一个键移动到左子结点中,类似根节点上的”借“
- 如果当前结点的左子结点和它的亲兄弟结点都是2-结点,将左子结点、父结点中的最小键和左子结点最近的兄弟结点合并为一个4-结点,使父结点由3-结点变为2- 结点或者由4结点变为3-结点
最后能够得到一个含有最小键的3-结点或者4-结点,然后我们就可以直接从中将其删除,将3-结点变为2-结点,或者将4-结点变为3-结点
2-3树中普适的删除键的操作
在查找路径上进行和删除最小键相同的变换(根据情况决定在左,中,右3个节点哪个节点上操作)同样可以保证在查找过程中任意当前结点均不是2- 结点
- 如果被查找的键在树的底部,我们可以直接删除它
- 如果不在,我们需要将它和它的前驱或者后继结点交换,交换之后这个键值将处于一个叶子节点中,我们可以直接删除
- 前驱替换
- 后继替换
总结
一次插入操作在树的高度上可能带来两种结果
- 树的高度不变
- 树的高度整体加1
一次删除操作再树的高度上可能带来的结果
- 树的高度不变,或者整体减1
最总结论是2-3树的插入不会改变树的平衡性,这种性质将大大降低在含有大量键值的2-3树的高度,含有10亿个节点的2-3树的高度在19到30之间