感觉红黑树甚至比AVL简单,不过下面有几处参照了java。 package cai.tree; import java.io.*; import java.util.*; class RedBlackTree<E extends Comparable>{ private class RBNode<E>{ public E data; public RBNode<E> parent; public RBNode<E> left; public RBNode<E> right; public int col; public RBNode(E data, RBNode<E> p, RBNode<E> l, RBNode<E> r, int col){ this.data = data; parent = p; left = l; right = r; this.col = col; } } private static final int BLACK = 1; private static final int RED = 0; public RBNode<E> root; private int size; public RedBlackTree(){ size = 0; root = null; } public void makeEmpty(){ root = null; } public boolean isEmpty(){ return root == null; } public boolean contains(E element){ return containsRec(element, root); } public int size(){ return size; } public RBNode<E> findMin(RBNode<E> node){ if(node == null){ return null; } while(node.left != null){ node = node.left; } return node; } public RBNode<E> findMax(RBNode<E> node){ if(node == null){ return null; } while(node.right != null){ node = node.right; } return node; } private boolean containsRec(E element , RBNode<E> p){ if(p == null){ return false; } int t = element.compareTo(p.data); if(t > 0){ return containsRec(element , p.right); } else if(t < 0){ return containsRec(element , p.left); } else{ return true; } } private void rotateLeft(RBNode<E> p) { if (p != null) { RBNode<E> r = p.right; p.right = r.left; if (r.left != null) r.left.parent = p; r.parent = p.parent; if (p.parent == null) root = r; else if (p.parent.left == p) p.parent.left = r; else p.parent.right = r; r.left = p; p.parent = r; } } private void rotateRight(RBNode<E> p) { if (p != null) { RBNode<E> l = p.left; p.left = l.right; if (l.right != null) l.right.parent = p; l.parent = p.parent; if (p.parent == null) root = l; else if (p.parent.right == p) p.parent.right = l; else p.parent.left = l; l.right = p; p.parent = l; } } private int colorOf(RBNode<E> p){ return (p == null) ? 1 : p.col; } private RBNode<E> leftOf(RBNode<E> p){ return (p == null) ? null : p.left; } private RBNode<E> rightOf(RBNode<E> p){ return (p == null) ? null : p.right; } private RBNode<E> parentOf(RBNode<E> p){ return (p == null) ? null : p.parent; } private void setColor(RBNode<E> p, int col){ if(p != null){ p.col = col; } } public void insert(E element){ size++; if(root == null){ root = new RBNode(element, null, null, null, 1); return ; } RBNode<E> p = root; RBNode<E> pare = null; int re = 0; while(p != null){ pare = p; re = element.compareTo(p.data); if(re > 0){ p = p.right; } else if(re < 0){ p = p.left; } else{ size--; System.out.println("the element exists in the tree"); return ; } } RBNode<E> newNode = new RBNode<E>(element, pare, null, null, 0); //新加入节点必为红色节点。 if(re > 0){ pare.right = newNode; }else{ pare.left = newNode; } if(pare.col == BLACK){ //父节点为黑则完成 return ; }else{ //否则必有祖父节点且为黑色 RBNode<E> currentNode = newNode; while(currentNode != null && currentNode != root && currentNode.parent.col == RED){ if(parentOf(currentNode) == leftOf(parentOf(parentOf(currentNode)))) { RBNode<E> uncle = rightOf(parentOf(parentOf(currentNode))); if(colorOf(uncle) == RED){ //case 1 setColor(parentOf(currentNode), BLACK); setColor(uncle, BLACK); setColor(parentOf(parentOf(currentNode)), RED); currentNode = parentOf(parentOf(currentNode)); }else{ //case2 if(currentNode == rightOf(parentOf(p))){ currentNode = parentOf(currentNode); rotateLeft(currentNode); } setColor(parentOf(currentNode), BLACK); //case3 setColor(parentOf(parentOf(currentNode)), RED); rotateRight(parentOf(parentOf(currentNode))); } }else{ RBNode<E> uncle = leftOf(parentOf(parentOf(p))); if (colorOf(uncle) == RED) { //case1 setColor(parentOf(currentNode), BLACK); setColor(uncle, BLACK); setColor(parentOf(parentOf(currentNode)), RED); currentNode = parentOf(parentOf(currentNode)); } else { if (currentNode == leftOf(parentOf(currentNode))) { //case2 currentNode = parentOf(currentNode); rotateRight(currentNode); } setColor(parentOf(currentNode), BLACK); //case3 setColor(parentOf(parentOf(currentNode)), RED); rotateLeft(parentOf(parentOf(currentNode))); } } } root.col = BLACK; return; } } public void remove(E element){ if(root == null){ System.out.println("it's a empty tree"); return ; } RBNode<E> p = root; size--; RBNode<E> pre = null; while(p != null){ int re = element.compareTo(p.data); if(re > 0){ p = p.right; } else if(re < 0){ p = p.left; } else{ break; } } if(p == null){ size++; System.out.println("could not find the element in the tree"); return ; } pre = p.parent; if(p.left != null && p.right != null){ RBNode<E> tempNode = p.right; while(tempNode.left != null){ tempNode = tempNode.left; } p.data = tempNode.data; p = tempNode; } RBNode<E> temp = (p.left == null) ? p.right : p.left; if(temp != null){ temp.parent = p.parent; if(p.parent == null){ root = temp; } else if(p == p.parent.left){ p.parent.left = temp; } else p.parent.right = temp; p.left = p.right = p.parent = null; if(p.col == BLACK){ fixAfterDeletion(temp); } }else if(p.parent == null){ //root root = null; }else{ //叶子节点 if(p.col == BLACK){ fixAfterDeletion(p); } if(p.parent != null){ if(p == p.parent.left) p.parent.left = null; else if(p == p.parent.right) p.parent.right = null; p.parent = null; } } } private void fixAfterDeletion(RBNode<E> p){ while(p != root && colorOf(p) == BLACK){ if(p == p.parent.left){ RBNode<E> sib = rightOf(parentOf(p)); if(colorOf(sib) == RED){ //case 1 setColor(sib, BLACK); setColor(parentOf(p), RED); rotateLeft(p.parent); sib = rightOf(parentOf(p)); } if(colorOf(p) == BLACK && colorOf(sib) == BLACK){ //case2 setColor(sib, RED); p = parentOf(p); }else{ if(colorOf(rightOf(sib)) == BLACK){ //case3 setColor(leftOf(sib), BLACK); setColor(sib, RED); rotateRight(sib); sib = rightOf(parentOf(p)); } setColor(sib, colorOf(parentOf(p))); //case4 setColor(parentOf(p), BLACK); setColor(rightOf(sib), BLACK); rotateLeft(parentOf(p)); p = root; } }else{ RBNode<E> sib = leftOf(parentOf(p)); if (colorOf(sib) == RED) { setColor(sib, BLACK); setColor(parentOf(p), RED); rotateRight(parentOf(p)); sib = leftOf(parentOf(p)); } if (colorOf(rightOf(sib)) == BLACK && colorOf(leftOf(sib)) == BLACK) { setColor(sib, RED); p = parentOf(p); } else { if (colorOf(leftOf(sib)) == BLACK) { setColor(rightOf(sib), BLACK); setColor(sib, RED); rotateLeft(sib); sib = leftOf(parentOf(p)); } setColor(sib, colorOf(parentOf(p))); setColor(parentOf(p), BLACK); setColor(leftOf(sib), BLACK); rotateRight(parentOf(p)); p = root; } } } setColor(p, BLACK); } public void printTree(){ Stack<RBNode<E>> theStack = new Stack<RBNode<E>>(); theStack.push(root); while(!theStack.empty()){ RBNode<E> theNode = theStack.pop(); System.out.println(theNode.data); if(theNode.right != null){ theStack.push(theNode.right); } if(theNode.left != null){ theStack.push(theNode.left); } } } } class RedBlackTest{ public static void main(String[] args){ RedBlackTree theRBT = new RedBlackTree(); theRBT.insert("aa"); theRBT.insert("bb"); theRBT.insert("cc"); System.out.println("--------------------------------------------------"); theRBT.printTree(); theRBT.insert("dd"); System.out.println("--------------------------------------------------"); theRBT.printTree(); theRBT.insert("ee"); System.out.println("--------------------------------------------------"); theRBT.printTree(); theRBT.insert("ff"); theRBT.remove("ff"); theRBT.remove("ee"); theRBT.insert("gg"); System.out.println("--------------------------------------------------"); theRBT.printTree(); theRBT.insert("hh"); System.out.println("--------------------------------------------------"); theRBT.printTree(); theRBT.insert("kk"); System.out.println(theRBT.size()); System.out.println("--------------------------------------------------"); theRBT.printTree(); theRBT.remove("zz"); theRBT.remove("ss"); theRBT.remove("ff"); theRBT.printTree(); System.out.println("----@@@@@@@@@@---------------------"); theRBT.remove("bb"); theRBT.printTree(); System.out.println("-----@@@@@@@@@@@@@@@-------------------------"); theRBT.remove("aa"); theRBT.printTree(); System.out.println("----@@@@@@@@@@@@@@@------------------------"); theRBT.remove("cc"); theRBT.printTree(); System.out.println("---@@@@@@@@@@@@@@2-----------------------"); theRBT.remove("dd"); theRBT.printTree(); System.out.println("---@@@@@@@@@@@@-----------------------------"); System.out.println(theRBT.size()); theRBT.insert("zz"); System.out.println(theRBT.size()); System.out.println("--------------------------------------------------"); System.out.println("--------------------------------------------------"); theRBT.printTree(); } }