import java.util.NoSuchElementException; public class RedBlackTree<AnyType extends Comparable<? super AnyType>> { public RedBlackTree( ) { nullNode = new RedBlackNode<>( null ); nullNode.left = nullNode.right = nullNode; header = new RedBlackNode<>( null ); header.left = header.right = nullNode; } private int compare( AnyType item, RedBlackNode<AnyType> t ) { if( t == header ) return 1; else return item.compareTo( t.element ); } public void insert( AnyType item ) { current = parent = grand = header; nullNode.element = item; while( compare( item, current ) != 0 ) { great = grand; grand = parent; parent = current; current = compare( item, current ) < 0 ? current.left : current.right; // Check if two red children; fix if so if( current.left.color == RED && current.right.color == RED ) handleReorient( item ); } // Insertion fails if already present if( current != nullNode ) return; current = new RedBlackNode<>( item, nullNode, nullNode ); // Attach to parent if( compare( item, parent ) < 0 ) parent.left = current; else parent.right = current; handleReorient( item ); } public void remove( AnyType x ) { throw new UnsupportedOperationException( ); } public AnyType findMin( ) { if( isEmpty( ) ) throw new NoSuchElementException("BST underflow"); RedBlackNode<AnyType> itr = header.right; while( itr.left != nullNode ) itr = itr.left; return itr.element; } public AnyType findMax( ) { if( isEmpty( ) ) throw new NoSuchElementException("BST underflow"); RedBlackNode<AnyType> itr = header.right; while( itr.right != nullNode ) itr = itr.right; return itr.element; } public boolean contains( AnyType x ) { nullNode.element = x; current = header.right; for( ; ; ) { if( x.compareTo( current.element ) < 0 ) current = current.left; else if( x.compareTo( current.element ) > 0 ) current = current.right; else if( current != nullNode ) return true; else return false; } } public void makeEmpty( ) { header.right = nullNode; } public void printTree( ) { if( isEmpty( ) ) System.out.println( "Empty tree" ); else printTree( header.right ); } private void printTree( RedBlackNode<AnyType> t ) { if( t != nullNode ) { printTree( t.left ); System.out.println( t.element ); printTree( t.right ); } } public boolean isEmpty( ) { return header.right == nullNode; } private void handleReorient( AnyType item ) { // Do the color flip current.color = RED; current.left.color = BLACK; current.right.color = BLACK; if( parent.color == RED ) // Have to rotate { grand.color = RED; if( ( compare( item, grand ) < 0 ) != ( compare( item, parent ) < 0 ) ) parent = rotate( item, grand ); // Start dbl rotate current = rotate( item, great ); current.color = BLACK; } header.right.color = BLACK; // Make root black } private RedBlackNode<AnyType> rotate( AnyType item, RedBlackNode<AnyType> parent ) { if( compare( item, parent ) < 0 ) return parent.left = compare( item, parent.left ) < 0 ? rotateWithLeftChild( parent.left ) : // LL rotateWithRightChild( parent.left ) ; // LR else return parent.right = compare( item, parent.right ) < 0 ? rotateWithLeftChild( parent.right ) : // RL rotateWithRightChild( parent.right ); // RR } private RedBlackNode<AnyType> rotateWithLeftChild( RedBlackNode<AnyType> k2 ) { RedBlackNode<AnyType> k1 = k2.left; k2.left = k1.right; k1.right = k2; return k1; } private RedBlackNode<AnyType> rotateWithRightChild( RedBlackNode<AnyType> k1 ) { RedBlackNode<AnyType> k2 = k1.right; k1.right = k2.left; k2.left = k1; return k2; } private static class RedBlackNode<AnyType> { // Constructors RedBlackNode( AnyType theElement ) { this( theElement, null, null ); } RedBlackNode( AnyType theElement, RedBlackNode<AnyType> lt, RedBlackNode<AnyType> rt ) { element = theElement; left = lt; right = rt; color = RedBlackTree.BLACK; } AnyType element; // The data in the node RedBlackNode<AnyType> left; // Left child RedBlackNode<AnyType> right; // Right child int color; // Color } private RedBlackNode<AnyType> header; private RedBlackNode<AnyType> nullNode; private static final int BLACK = 1; // BLACK must be 1 private static final int RED = 0; // Used in insert routine and its helpers private RedBlackNode<AnyType> current; private RedBlackNode<AnyType> parent; private RedBlackNode<AnyType> grand; private RedBlackNode<AnyType> great; // Test program public static void main( String [ ] args ) { RedBlackTree<Integer> t = new RedBlackTree<>( ); final int NUMS = 400000; final int GAP = 35461; System.out.println( "Checking... (no more output means success)" ); for( int i = GAP; i != 0; i = ( i + GAP ) % NUMS ) t.insert( i ); if( t.findMin( ) != 1 || t.findMax( ) != NUMS - 1 ) System.out.println( "FindMin or FindMax error!" ); for( int i = 1; i < NUMS; i++ ) if( !t.contains( i ) ) System.out.println( "Find error1!" ); } }