前面讲到了二叉搜索树(BST)和二叉平衡树(AVL),二叉搜索树在最好的情况下搜索的时间复杂度为O(logn),但如果插入节点时,插入元素序列本身就是有序的,那么BST树就退化成一个线性表了,搜索的时间复杂度为O(n)。
如果想要减少比较次数,就需要降低树的高度。在插入和删除节点时,要保证插入节点后不能使叶子节点之间的深度之差大于1,这样就能保证整棵树的深度最小,这就是AVL树解决BST搜索性能降低的策略。但由于每次插入或删除节点后,都可能会破坏AVL的平衡,而要动态保证AVL的平衡需要很多操作(左旋,右旋),这些操作会影响整个数据结构的性能,除非是在树的结构变化特别少的情形下,否则AVL树平衡带来的搜索性能提升有可能还不足为了平衡树所带来的性能损耗。
因此,引入了2-3树来提升效率。2-3树本质也是一种平衡搜索树,但2-3树已经不是一棵二叉树了,因为2-3树允许存在3这种节点,3-节点中可以存放两个元素,并且可以有三个子节点。
说白了,2-3树其实就是为了保证搜索树平衡的同时,减少了维持平衡的操作代价,提升了效率。当然,必须要牺牲结构的严格性来换取灵活性。
2-3树
2-3树定义
(1)2-3树要么为空要么具有以下性质:
(2)对于2-节点,和普通的BST节点一样,有一个数据域和两个子节点指针,
两个子节点要么为空,要么也是一个2-3树,当前节点的数据的值要大于左子树中所有节点的数
据,要小于右子树中所有节点的数据。
(3)对于3-节点,有两个数据域a和b和和三个子节点指针,
左子树中所有的节点数据要小于a,中子树中所有节点数据要大于a而小于b,右子树中所有节点
数据要大于b。
#### 2-3树性质
(1)对于每一个结点有1或者2个关键码。
(2)当节点有1个关键码的时,节点有2个子树。
(3)当节点有2个关键码时,节点有3个子树。
(4)所有叶子点都在树的同一层。
2-3树的插入
2-3树的插入相对来说比较简单,只需牢记一种情况:
当插入一个节点到3节点之后
选择中节点D,将D提升为父节点
2-3树的删除
删除节点大概分为3种情形:
(1)删除非叶子节点。
(2)删除不为2-节点的叶子节点。
(3)删除为2-节点的叶子节点。
删除始终关注一个词:中序遍历下的直接后继节点
先来看(1)的图解:
第(2)种情况比较简单,直接删除即可。
第(3)种情况:
再来看另一种情况:
满二叉树的删除:
2-3-4树
在上文中介绍了2-3树的定义以及插入删除操作。现在将在2-3树的基础上更进一步,介绍比2-3树更为复杂的数据结构2-3-4树。之所以介绍2-3-4树是因为2-3-4树与极为重要的红黑树有着等价关系,通过先学习2-3-4树为后面学习红黑树打下基础,增进对于红黑树的理解。
2-3-4树定义
2-3树不再是单纯的二叉树了,因为2-3树中除了2-节点之外还存在3-节点。在2-3树的基础上进一步扩展,2-3-4树在2-3树的基础上添加4-节点。4-节点可以存储3个键值,最多可以拥有4棵子树。
(1)每个节点每个节点有1、2或3个key,分别称为2-节点,3-节点,4-节点。
(2)所有叶子节点到根节点的长度一致(也就是说叶子节点都在同一层)。
(3)每个节点的key从左到右保持了从小到大的顺序,两个key之间的子树中所有的 key一定大于它的父节点的左key,小于父节点的右key。
#### 2-3-4树插入
和2-3树一样,2-3-4树插入也非常简单。只需记住在4节点插入,要先分裂,再插入。
注意(3)到(4)完全是为了满足定义中的“所有叶子节点到根节点长度相等”
2-3-4树删除
删除非叶子节点
删除方法:当删除的节点是非叶子节点,无论待删除节点的key是多少个,先使用中序遍历找到待删除节点的后继节点,然后将后继节点与待删除节点位置互换,此时就将问题转化为删除节点为叶子节点(平衡树的非叶子节点中序遍历后继节点肯定叶子节点),如果该叶子是非2-节点,则与6.1节情形一样,如果该节点是2-节点,则跟后面的6.3情形一样。
删除的叶子节点为2-节点
删除方法:当删除的叶子节点是2-节点,则将节点删除后,需要对树进行调整,调整规则如下:
(1)当前节点的父节点是2-节点,兄弟节点不为2-节点,则将兄弟节点的一个key上移成父节点,而父节点下移成子节点,此时树满足2-3-4树,完成调整。
(2)当前节点的父节点是2-节点,兄弟节点也为2-节点,则此时将父节点与兄弟节点合并,将合并后的节点看成当前节点,然后重复的判断,即判断合并后的当前节点的兄弟节点与父节点的情况,然后走对应的(1)(2)(3)处理,直到满足2-3-4树,完成调整。
(3)当前节点的父节点不为2-节点,即此时有两个或三个兄弟节点,此时需要根据相邻兄弟节点情形进行调整,规则如下:
(3)-a:若当前节点的相邻兄弟节点为非3个key,则父节点的一个key下移,与相邻兄弟节点合并,此时树满足2-3-4树,完成调整。
(3)-b:若当前节点的相邻兄弟节点为3个key,则父节点的一个key下移成1个key的节点,相邻兄弟节点的一个key上移与父节点合并,此时树满足2-3-4树,完成调整。
是不是看着很头疼,没关系,时刻记着2-3-4树的定义,然后看下面的图解,还是很容易理解的:
图解一:
图解二:
图解三:
本篇文章主要介绍了2-3树与2-3-4树的性质,以及插入删除等操作。介绍2-3-4树的目的主要是为了为后续学习红黑树和B-树打下基础。
本文部分参考:https://xiaozhuanlan.com/topic/5036471892 同学们可以移步去看一看