红黑树定义和性质
红黑树是一种自平衡的二叉查找树,它满足以下性质:
- 每个节点要么是红色,要么是黑色。
- 根节点是黑色的。
- 每个叶子节点(NIL节点,空节点)是黑色的。
- 如果一个节点是红色的,那么它的两个子节点都是黑色的。
- 对于每个节点,从该节点到其所有后代叶子节点的简单路径上,均包含相同数目的黑色节点。
其中,性质1、2、3是红黑树的基本性质,性质4和5保证了红黑树的平衡性。
具有以下性质的红黑树是平衡的:
- 根节点为黑色。
- 所有叶子节点都为黑色。
- 每个红色节点的两个子节点都是黑色的。
- 对于任意节点而言,其到叶子节点的所有简单路径都包含相同数目的黑色节点。
除了上面提到的基本性质和平衡性质,红黑树还有一些其他的特性:
- 从根节点到任意一个节点的最长简单路径不超过最短路径的两倍,因此红黑树是近似平衡的。
- 对于插入和删除操作,红黑树可以在O(log n)时间内完成,其中n是树中节点的数量。
- 与平衡二叉查找树(如AVL树)相比,红黑树的旋转操作较少,因此在实际应用中更加高效。
红黑树的应用广泛,例如C++ STL中的map和set就是基于红黑树实现的。在大多数情况下,红黑树是一种非常好的选择,可以提供快速的查找、插入和删除操作,并且具有良好的平衡性能。
结点叫法约定
- 根节点:树的顶端节点,通常用黑色表示。
- 叶子节点(NIL节点,空节点):没有子节点的节点,通常用黑色表示。
- 红色节点:具有红色标记的节点,其父节点是黑色的。
- 黑色节点:没有红色标记的节点,其子节点可以是红色或黑色。
- 父节点:指向某个节点的直接上级节点。
- 子节点:某个节点的直接下级节点。
- 兄弟节点:具有相同父节点的节点。
- 左子节点和右子节点:与节点的大小顺序相关,左子节点比父节点小,右子节点比父节点大。
这些叫法可以帮助我们更好地理解和描述红黑树的结构和操作。
黑结点可以同时包含一个红子结点和一个黑子结点吗? 是的,黑色节点可以同时包含一个红色子节点和一个黑色子节点。这是符合红黑树的定义和性质的。在红黑树中,一个节点可以有0个、1个或2个子节点,如果一个节点有2个子节点,则它的左子节点比它小,右子节点比它大。
在红黑树中,红色节点必须满足“如果一个节点是红色的,那么它的两个子节点都是黑色的”这个性质,而黑色节点没有这个限制。因此,黑色节点可以有一个红色子节点和一个黑色子节点,也可以有两个黑色子节点,但不能有两个红色子节点。
总之,红黑树的规定是一个节点要么是黑色的,要么是红色的,并不要求每个黑色节点都必须包含两个黑色子节点。
红黑树查找 红黑树的查找操作与普通的二叉查找树类似,其基本思路是从根节点开始,按照节点大小顺序向左或向右逐级查找,直到找到目标节点或者到达叶子节点。
具体地,红黑树查找的步骤如下:
- 从根节点开始查找,如果目标节点等于当前节点,则查找成功,返回该节点。
- 如果目标节点小于当前节点,说明目标节点在当前节点的左子树中,继续在左子树中递归查找。
- 如果目标节点大于当前节点,说明目标节点在当前节点的右子树中,继续在右子树中递归查找。
- 如果递归查找到一个空节点(NIL节点),说明目标节点不存在于树中,查找失败,返回空。
在红黑树中,由于满足“左小右大”和“红色节点的子节点必须是黑色”的性质,每个节点到其子孙节点的路径上的所有节点的大小顺序是唯一确定的。因此,红黑树的查找操作时间复杂度为O(log n),其中n是树中节点的数量。
需要注意的是,红黑树的查找操作只能找到等于目标节点的节点,不能找到大于或小于目标节点的节点。如果需要查找大于或小于目标节点的节点,可以使用红黑树的其他操作,如插入、删除、前驱和后继等操作。
红黑树插入 红黑树的插入操作是向树中插入一个新节点,并保证插入后仍然满足红黑树的性质。
具体地,红黑树的插入操作可以分为以下几个步骤:
-
将新节点插入到红黑树中的适当位置,并将其颜色设置为红色。
-
如果插入节点的父节点是黑色的,不需要进行任何操作,因为此时红黑树的性质依然满足。
-
如果插入节点的父节点是红色的,需要进行颜色调整和旋转操作,以保证红黑树的性质。
-
如果插入节点的父节点是其祖父节点的左子节点,且叔叔节点也是红色的,则将父节点和叔叔节点都设置为黑色,将祖父节点设置为红色,并将当前节点指向祖父节点,然后重新从第2步开始。
-
如果插入节点的父节点是其祖父节点的右子节点,且叔叔节点也是红色的,则将父节点和叔叔节点都设置为黑色,将祖父节点设置为红色,并将当前节点指向祖父节点,然后重新从第2步开始。
-
如果插入节点的父节点是其祖父节点的左子节点,且叔叔节点是黑色的(或者为空),则需要进行旋转操作。
- 如果插入节点是其父节点的右子节点,需要先对父节点进行左旋,然后将当前节点指向父节点,再进行下一步操作。
- 如果插入节点是其父节点的左子节点,将父节点设为黑色,将祖父节点设为红色,然后对祖父节点进行右旋。
-
如果插入节点的父节点是其祖父节点的右子节点,且叔叔节点是黑色的(或者为空),需要进行类似的操作,只是左右互换。
-
-
如果插入节点的父节点是黑色的,不需要进行任何操作,因为此时红黑树的性质依然满足。
-
将根节点设置为黑色,以满足红黑树性质之一:根节点是黑色的。
总之,红黑树的插入操作是一种复杂的操作,需要根据不同的情况进行颜色调整和旋转操作,以保证红黑树的性质。时间复杂度为O(log n),其中n是树中节点的数量。
红黑树删除 红黑树的删除操作是删除树中的一个节点,并保证删除后仍然满足红黑树的性质。
红黑树的删除操作可以分为以下几个步骤:
-
如果要删除的节点没有子节点或只有一个子节点,直接删除该节点。
-
如果要删除的节点有两个子节点,找到该节点的后继节点(即比该节点大的最小节点),用后继节点的值替换要删除的节点的值,并将要删除的节点指向后继节点。
-
如果要删除的节点是红色的,直接删除该节点,并不会影响红黑树的性质。
-
如果要删除的节点是黑色的,需要进行颜色调整和旋转操作,以保证红黑树的性质。为了保证删除后的树仍然是红黑树,需要维护删除节点的父节点、兄弟节点和兄弟节点的子节点之间的关系,以及颜色的变化。
- 如果删除节点的兄弟节点是红色的,需要进行旋转操作,使得删除节点的兄弟节点变为黑色。如果删除节点的父节点是红色的,则将父节点和兄弟节点的颜色互换,并对父节点进行旋转操作。
- 如果删除节点的兄弟节点是黑色的,且兄弟节点的两个子节点都是黑色的(或者为空),需要将兄弟节点的颜色设置为红色,并将删除节点的父节点设为新的删除节点。如果删除节点的父节点是黑色的,则需要递归地对父节点进行操作,直到整个树恢复平衡。
- 如果删除节点的兄弟节点是黑色的,且兄弟节点的左子节点是红色的,需要进行旋转操作,使得兄弟节点的左子节点变为删除节点的兄弟节点。然后将删除节点的兄弟节点和父节点的颜色互换,并将兄弟节点的左子节点设为黑色。
- 如果删除节点的兄弟节点是黑色的,且兄弟节点的右子节点是红色的,需要进行旋转操作,使得兄弟节点变为删除节点的父节点。然后将删除节点的父节点和兄弟节点的颜色互换,并将兄弟节点的右子节点设为黑色。
-
将根节点设置为黑色,以满足红黑树性质之一:根节点是黑色的。
总之,红黑树的删除操作也是一种复杂的操作,需要根据不同的情况进行颜色调整和旋转操作,以保证红黑树的性质。