一棵 2-3 树是一棵查找树,该查找树要么为空要么满足以下性质(令 left、middle、right 为 2-3 树结点的孩子指针;dl, dr为 2-3 树结点元素):
根据定义,可以看出,2-3 树本身就是一个自平衡树。对于高度为 h 的一棵 2-3 树,其上的元素个数介于 2h - 1 到 3h - 1 之间。一棵包含 n 个结点的 2-3 树,其高度在 log2(n+1) 和 log3(n + 1) 之间。
Java 定义
1 public class TwoThreeNode<T extends Comparable<T>> { 2 private T dataLeft; 3 private T dataRight; 4 private TwoThreeNode left; 5 private TwoThreeNode middle; 6 private TwoThreeNode right; 7 private TwoThreeNode parent; 8 }
结点有2个元素,定义一个比较函数,返回值含义:
Java 定义
1 public TwoThreeNode<T> search(T data) { 2 TwoThreeNode<T> node = head; 3 while (node != null) { 4 int r = compare(node, data); 5 switch (r) { 6 case 1: node = node.getLeft(); break; 7 case 2: node = node.getMiddle(); break; 8 case 3: node = node.getRight(); break; 9 case 4: 10 case 8: return node; 11 } 12 } 13 return null; 14 }
插入新元素,必然是插入到叶子结点中,如果是 2 结点的话,直接插入就结束了,但如果是3结点的话,如果向下溢出,则破坏了 2-3 树的平衡,因此需要拆分当前的结点然后向上合并,直到树根,以此保持 2-3 树自身的平衡。
找到待删除元素所在结点 n,如果 n 不是叶子结点,用它的直接前驱(左子树的最大元素)或者直接后继(右子树的最小元素)替换,进而转换为对叶子结点的删除。