红黑树(Red-Black Tree)是一种自平衡的二叉搜索树,它是由 Rudolf Bayer 在 1972 年提出的,后来由 Leo J. Guibas 和 Robert Sedgewick 在 1978 年发表的论文中形式化定义。
红黑树具有以下特性:
1.节点颜色:每个节点都具有颜色属性,通常是红色或黑色。
2.根节点和叶子节点:根节点和叶子节点(NIL 节点)的颜色为黑色。
3.相邻节点颜色:不能有两个相邻的红色节点,即红色节点的子节点和父节点不能同时为红色。
4.黑色高度:任何一条从根节点到叶子节点(NIL节点)的路径上,黑色节点的数量必须相同,这个数量称为黑色高度。
由于红黑树具有这些特性,它能够保持在插入、删除等操作过程中的平衡状态,使得树的高度保持在较低水平,从而保证了查找、插入和删除操作的时间复杂度始终是O(log n)。
红黑树在实际中被广泛应用,尤其是在实现各种数据结构和算法中,比如在 Java 中的 TreeMap、TreeSet等集合类的实现中就使用了红黑树。因为红黑树具有较好的平衡性和高效性,能够快速地支持查找、插入和删除等操作,适用于很多需要快速查找、有序存储的场景。
下面这段代码是类似于 Map 的简单实现,实际的 Map 实现中,还可能包含更多的功能,比如支持迭代、删除、更新等操作,以及更复杂的实现方式。
public class RedBlackTree {
private static final boolean RED = true;
private static final boolean BLACK = false;
private static class Node {
int key;
String value;
Node left, right;
boolean color;
public Node(int key, String value, boolean color) {
this.key = key;
this.value = value;
this.color = color;
}
}
private Node root;
// 左旋转操作
private Node rotateLeft(Node h) {
Node x = h.right;
h.right = x.left;
x.left = h;
x.color = h.color;
h.color = RED;
return x;
}
// 右旋转操作
private Node rotateRight(Node h) {
Node x = h.left;
h.left = x.right;
x.right = h;
x.color = h.color;
h.color = RED;
return x;
}
// 颜色翻转操作
private void flipColors(Node h) {
h.color = RED;
h.left.color = BLACK;
h.right.color = BLACK;
}
// 插入操作
public void insert(int key, String value) {
root = insert(root, key, value);
root.color = BLACK;
}
private Node insert(Node h, int key, String value) {
if (h == null)
return new Node(key, value, RED);
if (key < h.key)
h.left = insert(h.left, key, value);
else if (key > h.key)
h.right = insert(h.right, key, value);
else
h.value = value; // 更新值
if (isRed(h.right) && !isRed(h.left))
h = rotateLeft(h);
if (isRed(h.left) && isRed(h.left.left))
h = rotateRight(h);
if (isRed(h.left) && isRed(h.right))
flipColors(h);
return h;
}
// 判断节点颜色
private boolean isRed(Node x) {
if (x == null)
return false;
return x.color == RED;
}
// 查找操作
public String search(int key) {
Node node = search(root, key);
return node == null ? null : node.value;
}
private Node search(Node x, int key) {
if (x == null)
return null;
if (key < x.key)
return search(x.left, key);
else if (key > x.key)
return search(x.right, key);
else
return x;
}
public static void main(String[] args) {
RedBlackTree tree = new RedBlackTree();
tree.insert(1, "A");
tree.insert(2, "B");
tree.insert(3, "C");
tree.insert(4, "D");
//tree.insert(5, "E");
tree.insert(6, "F");
tree.insert(7, "G");
tree.insert(8, "H");
System.out.println("Key 3 的值为:" + tree.search(3));
System.out.println("Key 5 的值为:" + tree.search(5));
System.out.println("Key 8 的值为:" + tree.search(8));
System.out.println("Key 9 的值为:" + tree.search(9));
}
}
运行一下
可以看到 insert 方法类似于Map中的put方法,search方法类似于Map中的get 方法