红黑树 是一种 平衡二叉搜索树, 这里的平衡和我们之前说的AVL树的平衡有一点不一样,AVL的平衡是任意节点的子树 的高度差不能大于1. 但是红黑树的平衡是对于他的几点性质来说的。
红黑树的性质:
1. 每个节点有两种颜色 红色或者黑色
2. 根节点是黑色的
3. 每个叶子节点都是黑色 [ 注意,该叶子节点为NULL 或者NIL 的节点 如下图]
4. 如果一个节点是红色的, 则它的子节点必须是黑色的
5. 从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点 - 该性质确保没有一条路径会比其他路径长出两倍.
红黑树的操作:
1. 左旋和右旋 红黑树的左旋和右旋是和AVL树的操作大体是相同的. 如下图
.
就像在 AVL 博客中提到的如何旋转一样, 找定Root 和 Pivot 然后交换它俩的位置, 再对他们的孩子进行处理, 就能简单的完成. 上图是对 40 进行 左旋, 可以将
40 看作是root, 60 看作是 pivot.
对120 进行右旋, 那么将它的左孩子作为pivot.
总结: 将哪个节点旋转就把哪个节点作为Root 节点, 然后如果左旋 那么 右孩子作为pivot, 如果右旋左孩子作为pivot.
2. 红黑树的添加
1.) 按照二叉搜索树的插入原则插入 (因为红黑树本身是一个 二叉搜索树)
2.) 将新插入的节点 着色为 红色
3.) 将新获得的树通过左旋或者右旋使其满足 红黑树的几条基本性质. 直到根节点
首先是简单的两种情况1. 该树为空,直接将插入的节点由红变黑 2. 插入的节点的父节点为根节点, 不用动。 以下是复杂的三种添加情况.
对于红黑树的添加 ( 其实也就是3.) ), 我们可以概括为以下三种情况.
A. 当前节点的父节点是红色, 且当前节点的叔叔节点也是红色
策略是: A1. 将父节点设为黑色 A2. 将叔叔节点也设为黑色 A3. 将祖父节点设为红色 A4. 将祖父节点设为当前节点 - 接下来需要进行判断当前的状态属于ABC中哪种情况, 继续进行操作
B. 当前节点的父节点是红色, 叔叔节点是黑色, 且当前节点是其父节点的右孩子
策略是: B1. 将父节点作为新的当前节点 B2. 将新的当前节点进行左旋
C. 当前节点的父节点是红色, 叔叔节点是黑色, 且当前节点是其父节点的左孩子
策略是: C1. 将父节点改为黑色 C2. 将祖父节点设为红色 C3. 以祖父节点为支点进行右旋.
3. 红黑树的删除
1.) 将红黑树当作一颗二叉查找树, 将节点删除
2.) 通过 旋转和从新着色, 使之成为一颗新的红黑树
在reference中写的很好,可以去那里看看关于这一部分的讲解。
但是对于删除那一部分我要补充。。
什么是 双黑节点? 因为红黑树依旧是 二叉搜索树, 当我们进行删除操作之后(简单按照二叉搜索树的删除规则),被删除的那个点所在的路径上的黑色节点的总数会比其他路径上的黑色节点数目小1, 那么该点被称为双黑节点。
如下图,当我们需要删除-7的时候, 将-7 设为null 节点,并且丢失它本身的颜色, 所以 从根节点到叶子节点的黑色节点的数量就小一,我们将这个null节点作为双黑节点,然后对其进行不同情况的匹配和相应的操作。
Reference: http://www.cnblogs.com/skywang12345/p/3245399.html