近似平衡的二叉搜索树
特点
- 每个节点颜色不是红色就是黑色
- 根节点是黑色
- 每个叶子节点有两个虚拟黑色子节点(nil)
- 红色节点不能相邻,也就是说红色节点的子节点都是黑色,红色节点的父节点也是黑色
- 从根节点出发,到叶子节点的黑色节点个数相同
旋转
左旋
假设对A进行左旋,左旋前后如下:
1 2 3 4 5 6 7 8 9 10 11
| A / \ B C / \ D E
C / \ A E / \ B D
|
右旋
假设对A进行右旋,右旋前后如下:
1 2 3 4 5 6 7 8 9 10 11
| A / \ B C / \ D E
B / \ D A / \ E C
|
插入节点
新插入的节点都是红色,就有5种情况,其中后3种需要进一步的调整:
- 根节点为
null - 父节点是黑色
- 父节点是红色,叔叔节点为红色
- 父节点是红色,叔叔节点为黑色,直线型
- 父节点是红色,叔叔节点为黑色,三角型
1. 根节点为null
最简单的情况,直接赋值即可
2. 父节点是黑色
添加的节点是红色,此时依然满足红黑树的条件,直接添加即可
3. 父节点是红色,叔叔节点为红色
- 将父节点和叔叔节点置为黑色
- 将祖父节点置为红色
- 继续从祖父节点继续判断
4. 父节点是红色,叔叔节点为黑色,直线型
如下所示为直线型,新加入的节点为4,是左子节点,而其父节点也是左子节点
1 2 3 4 5
| 1(黑) / \ 2(红) 3(黑) / 4(红)
|
- 将父节点
2置为黑色 - 将祖父节点
1置为红色 - 对祖父节点进行右旋
1 2 3 4 5
| 2(黑) / \ 4(红) 1(红) \ 3(黑)
|
5. 父节点是红色,叔叔节点为黑色,三角型
如下所示为三角型,新加入的节点为4,是右子节点,而其父节点是左子节点
1 2 3 4 5
| 1(黑) / \ 2(红) 3(黑) \ 4(红)
|
1 2 3 4 5
| 1(黑) / \ 4(红) 3(黑) / 2(红)
|
代码实现
参考TreeMap实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
| public void insert(int value) { if (root == null) { root = new Node(value); } else { Node node = root, parent; boolean left; do { parent = node; left = value < node.value; if (left) { node = node.left; } else { node = node.right; } } while (node != null);
Node newNode = new Node(value, parent); if (left) { parent.left = newNode; } else { parent.right = newNode; }
fixAfterInsertion(newNode); } }
public void fixAfterInsertion(Node node) { node.color = RED; while (node != null && node != root && node.parent.color == RED) { Node parent = parentOf(node); Node grandparent = parentOf(parent); if (parent == leftOf(grandparent)) { Node uncle = rightOf(grandparent); if (colorOf(uncle) == RED) { setColor(parentOf(node), BLACK); setColor(uncle, BLACK); setColor(grandparent, RED); node = grandparent; } else { if (node == rightOf(parent)) { node = parent; rotateLeft(node); } setColor(parentOf(node), BLACK); setColor(grandparent, RED); rotateRight(grandparent); } } else { Node uncle = leftOf(grandparent); if (colorOf(uncle) == RED) { setColor(parent, BLACK); setColor(uncle, BLACK); setColor(grandparent, RED); node = grandparent; } else { if (node == leftOf(parent)) { node = parent; rotateRight(node); } setColor(parentOf(node), BLACK); setColor(grandparent, RED); rotateLeft(grandparent); } } } root.color = BLACK; }
private static boolean colorOf(Node n) { return n == null ? BLACK : n.color; }
|
删除节点
待续
参考