红黑树
1 概念介绍
1.每个节点或者是红色的,或者是黑色的
2.根节点是黑色的
3.每一个叶子节点(最后的空节点)是黑色的
4.如果一个节点是红色的,那么他的孩子节点都是黑色的(因为红色节点只能是黑色节点的左子节点,这也表明黑色节点右子树连接节点也是黑色的)
5.从任意一个节点到叶子节点,经过的黑色节点是一样的(因为和二三树等价,红色节点可以忽略。所以也说红黑树是黑平衡的二叉树,他的时间复杂度最差会退化成2logn)
- 红黑树和二三树其实是等价的
- 二三树是一种二分搜索树,但是不是二叉树
- 二三树是一颗绝对平衡树,即从根节点到任意叶子节点所经过的节点数一定相同
- 红黑树其实就是把二三树中三节点左侧的节点变为左子树,且变为红颜色
- 红黑树新添加节点都是红色的,红色节点首先要看是否能和上游节点融合
- 红黑树统计性能好,还有一种splay tree性能也好
![image-20200228105900091]()
2 代码实现
下面的代码是左倾的红黑树,也可以使用右倾
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 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
| public class RBTree<K extends Comparable<K>,V> { private static final boolean RED = true; private static final boolean BLACK = false; private class Node{ public K key; public V value; public Node left, right; public boolean color; public Node(K key,V value) { this.key = key; this.value = value; left = null; right = null; color = RED; } } private Node root; private int size; public RBTree(){ root = null; size = 0; } public int getSize() { return size; } public boolean isEmpty() { return size == 0; }
private boolean isRed(Node node){ if(node == null){ return BLACK; } return node.color; } public void add(K key, V value){ root = add(root,key,value); root.color = BLACK; } private Node add(Node node,K key, V value){ if(node == null){ size++; return new Node(key,value); } if(key.compareTo(node.key) < 0) node.left = add(node.left, key, value); else if (key.compareTo(node.key) > 0) node.right = add(node.right, key, value); else node.value = value; if(isRed(node.right) && !isRed(node.left)) leftRotate(node); if(isRed(node.left) && isRed (node.left.left)) node = rightRotate(node) ; if(isRed(node.left) && isRed(node. right)) flipColors (node); return node;
} private Node leftRotate(Node node){ Node x = node.right; node.right = x.left; x.left = node; x.color = node.color; node.color = RED; return x; } private void flipColors(Node node){ node.color = RED; node.left.color = BLACK; node.right.color= BLACK; } private Node rightRotate(Node node){ Node x = node.left; node.left = x.right; x.right = node; x.color = node.color; node.color = RED; return x; } }
|