Você está na página 1de 3

RED-BLACK TREES Time complexity in big O notation Average Worst case Space O(n) O(n) Search O(log n) O(log

n) Insert O(log n) O(log n) Delete O(log n) O(log n) 1. Every node is either red or black. 2. The root is always black. 3. If a node is red, its children must be black (although the converse isnt necessarily true). 4. Every path from the root to a leaf, or to a null child, must contain the same number of black nodes. The number of black nodes on a path (black height). Must be the same for all paths from the root to a leaf . ASSUME NO DUPLICATES BECAUSE: Search process becomes more complicated if all items with the same key must be found. IF COLOR RULES VIOLATED: 1. change the colors of nodes. 2. You can perform rotations. COLOR FLIP: -changes a black node with two red children to a red node with two black children. ROTATION: -one node is designated the top node. A right rotation moves the top node into the position of its right child, and the top nodes left child into its position. A left rotation moves the top node into the position of its left child, and the top nodes right child into its position. INSERTION: After a new node is inserted, red-red conflicts are checked again. If a violation is found, appropriate rotations are carried out to make the tree red-black correct.
/** * Print the tree contents in sorted order. */ public void printTree( ) { if( isEmpty( ) ) System.out.println( "Empty tree" ); else printTree( header.right );} /** * Internal method to print a subtree in sorted order. * @param t the node that roots the subtree. */ private void printTree( RedBlackNode<AnyType> t ) {if( t != nullNode ) { printTree( t.left ); System.out.println( t.element ); printTree( t.right ); } }

public class RedBlackTree<AnyType extends Comparable<? super AnyType>> { private RedBlackNode<AnyType> header; private RedBlackNode<AnyType> nullNode; private static final int BLACK = 1; // BLACK must be 1 private static final int RED = 0; //Construct the tree. public RedBlackTree( ) { nullNode = new RedBlackNode<>( null ); nullNode.left = nullNode.right = nullNode; header = new RedBlackNode<>( null ); header.left = header.right = nullNode;}

private static class RedBlackNode<AnyType> { AnyType element; // The data in the node RedBlackNode<AnyType> left; //Left child RedBlackNode<AnyType>right; //Right child int color; //Color // 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; }}} /** * Internal routine that performs a single or double rotation. * Because the result is attached to the parent, there are four cases. * Called by handleReorient. * @param item the item in handleReorient. * @param parent the parent of the root of the rotated subtree. * @return the root of the rotated subtree. */ 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} /** * Compare item and t.element, using compareTo, with * caveat that if t is header, then item is always larger. * This routine is called if it is possible that t is header. * If it is not possible for t to be header, use compareTo directly. */ private final int compare( AnyType item, RedBlackNode<AnyType> t ) { if( t == header ) return 1; else return item.compareTo( t.element );

} // Used private private private private in insert routine and RedBlackNode<AnyType> RedBlackNode<AnyType> RedBlackNode<AnyType> RedBlackNode<AnyType> its helpers current; parent; grand; great;

/** * Internal routine that is called during an insertion * if a node has two red children. Performs flip and rotations. * @param item the item being inserted. */ 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 } /** * Insert into the tree. * @param item the item to insert. */ 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 );}

Você também pode gostar