2-3树
真的是非常完美的平衡二叉树了,平衡二叉树(BST)的要点在于它的每条从根节点到叶子节点的路径都具有相同的长度,并且在数据结构中,对于查找和插入操作,最糟糕的情况下时间复杂度为O(log n)。
与我在第四十五天讲的BST有什么不一样呢?
2-3树扩展了节点的容量。2-节点包含了一个值和两个孩子节点【叶子节点除外】。
3-节点包含了两个值和三个孩子节点【叶子节点除外】。
若要向2-3树插入一个值,先在当前的平衡二叉树中找到合适的节点下的叶子并插入,如果当前节点的叶子包含三个值,那么称之为临时4-节点,将这个节点分裂得到三个2-节点,并将中间的值当做父亲节点。(注意到这里说的节点并非叶子节点)
虽然这听起来很棒,但2-3树确实很难实现,别急!我有妙招!用左倾变体(left-leaning variant)的红黑树(红黑树也叫自平衡二叉树)可以让你非常愉快地实现这些。
实话说,当初我回到大学被要求执行并证明红黑树的所有知识,但,在接触左倾变体之前,我真的理解不了红黑树背后的那层意义,左倾变体真的非常好理解。
我们可以将2-节点作为规则节点来实现并标记这个节点以及它的子节点为黑色,3-节点的实现则致使较低的值是较高值的孩子节点点,并被标记成红色。
当一个值被插入到叶子节点中,默认情况下它是红色的,然后往根节点的方向遍历,检查下面这些变量:只有左孩子节点可以是红色的,如果左孩子节点是黑色的,右孩子节点是红色的,则向左旋转节点。
红色的父节点不可以有红色的孩子节点--如果有这种情况,则向右旋转节点。
父节点不可以有两个红孩子节点--如果有这种情况,则将孩子节点标记为黑色,将父节点标记为红色。
这需要在纸上画两下,不过操作非常直观并且是和2-3树的操作一一对应的。
算法实现
插入操作
Draw操作
测试