1.具体算法
/** * 算法3.4 红黑树 * Created by huazhou on 2015/12/2. */ public class RedBlackBST<Key extends Comparable<Key>, Value> { private Node root; private final boolean RED = true; private final boolean BLACK = false; private class Node{ Key key; //键 Value val; //相关联的值 Node left, right; //左右子树 int N; //这棵子树中的结点总数 boolean color; //由其父结点指向它的链接的颜色 Node(Key key, Value val, int N, boolean color){ this.key = key; this.val = val; this.N = N; this.color = color; } } private boolean isRed(Node x){ if(x == null){ return false; } return x.color == RED; } private Node rotateLeft(Node h){ Node x = h.right; h.right = x.left; x.left = h; x.color = h.color; h.color = RED; x.N = h.N; h.N = 1 + size(h.left) + size(h.right); 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; x.N = h.N; h.N = 1 + size(h.left) + size(h.right); return x; } private void flipColors(Node h){ h.color = RED; h.left.color = BLACK; h.right.color = BLACK; } public int size(){ return size(root); } private int size(Node x){ if(x == null){ return 0; } else{ return x.N; } } //查找key,找到则更新其值,否则为它新建一个结点 public void put(Key key, Value val){ root = put(root, key, val); root.color = BLACK; } private Node put(Node h, Key key, Value val){ //标准的插入操作,和父结点用红链接相连 if(h == null){ return new Node(key, val, 1, RED); } int cmp = key.compareTo(h.key); if(cmp < 0){ h.left = put(h.left, key, val); } else if(cmp > 0){ h.right = put(h.right, key, val); } else{ h.val = val; } 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); } h.N = size(h.left) + size(h.right) + 1; return h; } public boolean contains(Key key) { return get(key) != null; } public Value get(Key key) { return get(root, key); } private Value get(Node x, Key key) { while (x != null) { int cmp = key.compareTo(x.key); if (cmp < 0) x = x.left; else if (cmp > 0) x = x.right; else return x.val; } return null; } public Iterable<Key> keys() { if (isEmpty()) return new Queue<Key>(); return keys(min(), max()); } public Iterable<Key> keys(Key lo, Key hi) { if (lo == null) throw new NullPointerException("first argument to keys() is null"); if (hi == null) throw new NullPointerException("second argument to keys() is null"); Queue<Key> queue = new Queue<Key>(); // if (isEmpty() || lo.compareTo(hi) > 0) return queue; keys(root, queue, lo, hi); return queue; } private void keys(Node x, Queue<Key> queue, Key lo, Key hi) { if (x == null) return; int cmplo = lo.compareTo(x.key); int cmphi = hi.compareTo(x.key); if (cmplo < 0) keys(x.left, queue, lo, hi); if (cmplo <= 0 && cmphi >= 0) queue.enqueue(x.key); if (cmphi > 0) keys(x.right, queue, lo, hi); } public boolean isEmpty() { return root == null; } public Key min() { return min(root).key; } private Node min(Node x) { // assert x != null; if (x.left == null) return x; else return min(x.left); } public Key max() { return max(root).key; } private Node max(Node x) { // assert x != null; if (x.right == null) return x; else return max(x.right); } }
2.执行过程
3.算法分析
命题:一棵大小为N的红黑树的高度不会超过2lgN
命题:一棵大小为N的红黑树中,根结点到任意结点的平均路径长度为~1.001lgN
【源码下载】