红黑树的性质
- 每个节点或者是黑色,或者是红色。
- 根节点是黑色。
- 每个叶子节点(NIL)是黑色。 [注意:这里叶子节点,是指为空(NIL或NULL)的叶子节点!]
- 如果一个节点是红色的,则它的子节点必须是黑色的。
- 从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点。
红黑树的应用
红黑树的应用比较广泛,主要是用它来存储有序的数据,它的时间复杂度是O(lgn),效率非常之高。例如,Java集合中的TreeSet和TreeMap,C++ STL中的set、map,以及Linux虚拟内存的管理,都是通过红黑树去实现的。
红黑树的操作 添加
- 第一步: 将红黑树当作一颗二叉查找树,将节点插入。
- 第二步:将插入的节点着色为”红色”。
第三步: 通过一系列的旋转或着色等操作,使之重新成为一颗红黑树。
旋转或着色操作又可以分为多个情况:
Case 1 当前节点的父节点是红色,且当前节点的祖父节点的另一个子节点(叔叔节点)也是红色。
- 将“父节点”设为黑色。
- 将“叔叔节点”设为黑色。
- 将“祖父节点”设为“红色”。
- 将“祖父节点”设为“当前节点”(红色节点);即,之后继续对“当前节点”进行操作。
Case 2 当前节点的父节点是红色,叔叔节点是黑色,且当前节点是其父节点的右孩子
- 将“父节点”作为“新的当前节点”。
- 以“新的当前节点”为支点进行左旋。
Case 3 当前节点的父节点是红色,叔叔节点是黑色,且当前节点是其父节点的左孩子
- 将“父节点”设为“黑色”。
- 将“祖父节点”设为“红色”。
- 以“祖父节点”为支点进行右旋
红黑树的操作 删除
- 第一步:将红黑树当作一颗二叉查找树,将节点删除。(查找后继节点X)
第二步:通过”旋转和重新着色”等一系列来修正该树,使之重新成为一棵红黑树。
我们假设后继节点x 有一个额外的黑色。如果x为“红+黑”,直接将x置为黑。
如果x为“嘿+嘿”就又要分多种情况讨论。- (Case 1)x是”黑+黑”节点,x的兄弟节点是红色
- (Case 2) x是”黑+黑”节点,x的兄弟节点是黑色,x的兄弟节点的两个孩子都是黑色
- (Case 3)x是“黑+黑”节点,x的兄弟节点是黑色;x的兄弟节点的左孩子是红色,右孩子是黑色的
- (Case 4)x是“黑+黑”节点,x的兄弟节点是黑色;x的兄弟节点的右孩子是红色的,x的兄弟节点的左孩子任意颜色