240 likes | 329 Views
CMSC 341 Lecture 14. Bottom Up Implementation. Perform insertion; new node is red Check for balance violations Are all nodes red or black? Is every NULL pointer black? If a node is red, are both of its children black?
E N D
Bottom Up Implementation • Perform insertion; new node is red • Check for balance violations • Are all nodes red or black? • Is every NULL pointer black? • If a node is red, are both of its children black? • Does every path from a node to a descendent leaf contain the same number of black nodes? • If necessary, make adjustments starting at altered node
Bottom Up Insertion (cont) • Insert node; X is pointer to it • Cases 0: X is the root -- color it black 1: Both parent and uncle are red -- color parent and uncle black, color grandparent red, point X to grandparent, check new situation 2: Parent is red, but uncle is black. X and its parent are both left or both right children -- color parent black, color grandparent red, rotate right on grandparent 3: Parent is red, but uncle is black. X and its parent are opposite type children -- color grandparent red, color X black, rotate left on parent, rotate right on grandparent
Reorient • template <class Comparable> • void RedBlackTree<Comparable>::handleReorient (const Comparable & item) { • current->color = RED; • current->left->color = current->right->color = BLACK; • if (parent->color == RED) { • grand->color = RED; • if ((item < grand->element) != (item < parent->element) • parent = rotate(item, grand); // start dbl rotate • current = rotate(item, great); • current->color = BLACK; • } • header->right->color = BLACK; // make root black • }
Rotate • template <class Comparable> • RedBlackNode<Comparable> *RedBlackTree<Comparable>::rotate(const Comparable &item, RedBlackNode<Comparable> *theParent) const; { • if (item < theParent->element) { • if (item < theParent->left->element) • rotateWithLeftChild(theParent->left) // LL • else • rotateWithRightChild(theParent->left) // LR • return theParent->left;} • else { • if (item < theParent->right->element) • rotateWithLeftChild(theParent->right) // RL • else • rotateWithRightChild(theParent->right) // RR • return theParent->right;} • }
Asymptotic Cost • O(lg n) to descend to insertion point • O(1) to do insertion • O(lg n) to ascend and readjust -- worst case only for case 1 • Total: O(lg n)
Bottom Up Deletion • Normal BST deletion 0: if node is leaf, just delete 1: if node has one child, replace it with child 2: if node has two children, replace value at node by value of its inorder predecessor, then recursively delete inorder predecessor • Eventually case 0 or 1 will be reached, where node is replaced by another node V. If node to be deleted then is red, no adjustments are needed. If black, adjustments must be made to preserve number of black nodes.
Bottom Up Deletion (cont) • Cases 0: If S, sibling of V, is red. Do rotation at recoloring to produce a situation that can be handled as another. 1: Node S is black and both its children are black. Color S red. If P is red, make P black and terminate. Otherwise, check again and continue. 2: Node S is black and its right child is red. Do a rotation followed by a color swap between S and P. Now done. 3: Node S is black, its left child is red, and its right child is black. Do a rotation around S and a recoloring. The situation can now be handled as 2.
Top Down Implementation • Make adjustments on way down to site for operation (insert, remove) • Perform operation
Insert • template <class Comparable> • void RedBlackTree<Comparable>::insert(const Comparable &x) { • current = parent = grand = header; • nullNode->element = x; • while (current->element != x) { • great = grand; grand = parent; parent = current; • current = (x < current->element) • ? current->left : current->right; • // if two red children, fix • if ((current->left->color == RED) • &&( current->right->color == RED)) • handleReorient(x); • }
Insert (cont) • // insertion fails if already present • if (current != nullNode) return; • current = new RedBlackNode<Comparable> • (x, nullNode, nullNode); • // attach to parent • if (x < parent->element) • parent->left = current; • else • parent->right = current; • handleReorient(x); • }
Proof: # Internal Nodes • Theorem 1: Any red-black tree, with root x, has at least n = 2bh(x)-1 internal nodes, where bh(x) is the black-height of node x. • Proof: by induction on height of x • Base: x is a leaf, height is zero, bh(x) = 0, 20 - 1 = 0 • Induction: Let x be an internal node with two children. If a child of x is red, its black height is bh(x). If the child is black, its black height is bh(x)-1. In any event, the IH holds for the children since their height is less than that of x. Therefore, each child subtree has at least 2bh(x)-1-1 internal nodes. Therefore, the tree rooted at x has at least 2(2bh(x)-1-1)+1=2bh(x)-1 internal nodes.
Proof: # Black • Theorem 2: In a red-black tree, at least half of the nodes on any path from root to a leaf must be black. • Proof: Since no red node can have a red child, the maximum number of red nodes in any path from root to leaf will be every other node.
Proof: Path Length • Theorem 3: In a red-black tree, no path from any node N to a leaf is more than twice as long as any other path from N to any other leaf. • Proof: By definition, every path from a node to a leaf contains the same number of black nodes. By Theorem 2, at least half of the nodes on any such path must be black. Therefore, there can be no more than twice as many red nodes on any path from a node to a leaf. Therefore, the length of every path is no more than twice as long as that of any other path.
Proof: Height • Theorem 4: A red-black tree with n internal nodes has height h 2 lg(n+1) • Proof: Let h be the height of the red-black tree. By theorem 2, bh(x) h/2. Therefore, • n 2h/2 -1 • n - 1 2h/2 • lg (n-1) h/2 • 2 log(n-1) h