或者是一棵空树,或者是具有下列性质的二叉树:
(1)若左子树不空,则左子树上所有节点的值均小于它的根节点的值;
(2)若右子树不空,则右子树上所有节点的值均大于它的根节点的值;
(3)左、右子树也分别为二叉排序树。
优点:相对于顺序查找来说,效率高了很多,提升了查询效率。
缺点:若二叉树极度不平衡,会导致查找效率大大降低。如下:
为避免类似极端情况我们可以选择一种算法,将不平衡的二叉排序树转化为平衡二叉排序树。
在符合二叉查找树的条件下,还满足任何节点的两个子树的高度最大差为 1.
如下图:
红黑树是每个节点带有颜色属性的二叉查找树,颜色或红或黑。在二叉查找树的强制要求以外,加入以下要求:
(1)节点是红色或者黑色。
(2)根节点是黑色节点。
(3)每个叶子节点都是黑色的空节点(NULL)
(4)每个红色节点的两个子节点都是黑色的(从根节点到叶子节点不存在连续两个红色的节点)。
(5)从任意节点到叶子节点所有路径中包含的黑色节点数目相同。
当插入删除时,就会对平衡造成破坏,这时候需要对树进行调整,从而重新达到平衡。
首先将插入节点着色为红色,再插入二叉树将会产生三种情况:
情况①说明:被插入的节点是根节点。
处理方法:直接把此节点涂为黑色。
情况②说明:被插入的节点的父节点是黑色。
处理方法:什么也不需要做。节点被插入后,仍然是红黑树。
情况③说明:被插入的节点的父节点是红色。
处理方法:那么,该情况与红黑树的“特性(4)”相冲突。这种情况下,被插入节点是一定存在非空祖父节点的;进一步的讲,被插入节点也一定存在叔叔节点(即使叔叔节点为空,我们也视之为存在,空节点本身就是黑色节点)。理解这点之后,我们依据"叔叔节点的情况",将这种情况进一步划分为3种情况(Case)。
现象说明 | 处理策略 | |
---|---|---|
Case1 | 当前节点的父节点是红色,且当前节点的祖父节点的另一个子节点(叔叔节点)也是红色。 | (01) 将“父节点”设为黑色。 (02) 将“叔叔节点”设为黑色。 (03) 将“祖父节点”设为“红色”。 (04) 将“祖父节点”设为“当前节点”(红色节点);即,之后继续对“当前节点”进行操作。 |
Case2 | 当前节点的父节点是红色,叔叔节点是黑色,且当前节点是其父节点的右孩子 | (01) 将“父节点”作为“新的当前节点”。 (02) 以“新的当前节点”为支点进行左旋。 |
Case3 | 当前节点的父节点是红色,叔叔节点是黑色,且当前节点是其父节点的左孩子 | (01) 将“父节点”设为“黑色”。 (02) 将“祖父节点”设为“红色”。 (03) 以“祖父节点”为支点进行右旋。 |
如下图:
由于父节点15是黑色节点,所以此时没有破环结构,不需要做调整。
插入新节点值为21(情况③Case1):
插入21节点:
将祖父节点25设为红色,同时重置为插入节点,即现在插入节点为25:
此时新的节点25符合情况③Case2:
红黑树的旋转与变色
红黑树(一)之 原理和算法详细介绍
B-Tree是为磁盘等外存储设备设计的一种平衡查找树。
为了描述B-Tree,首先定义一条数据记录为一个二元组[key, data],key为记录的键值,对于不同数据记录,key是互不相同的;data为数据记录除key外的数据。一棵m阶的B-Tree有如下特性:
B+Tree是在B-Tree基础上的一种优化,常见的如MySQL就普遍使用B+Tree实现其索引结构。
在B-Tree数中可以看到每一个节点不仅包含数据的key值,还有data值,若data数据较大或存储数据量很大时性能会受影响。
而B+Tree中,所有数据记录节点都是按照键值大小顺序存放在同一层的叶子节点上,而非叶子节点上只存储key值信息,这样可以大大加大每个节点存储的key值数量,降低B+Tree的高度。
B+Tree相对B-Tree有几点不同:
通常在B+Tree上有两个头指针,一个指向根节点,另一个指向关键字最小的叶子节点,而且所有叶子节点(即数据节点)之间是一种链式环结构。
因此可以对B+Tree进行两种查找运算:一种是对于主键的范围查找和分页查找,另一种是从根节点开始,进行随机查找。
BTree和B+Tree详解
MySQL索引原理及BTree(B-/+Tree)结构详解