chapter 10: binary search...
TRANSCRIPT
© 2010 Pearson Addison-Wesley. All rights reserved.
Addison Wesley
is an imprint of
CHAPTER 10:
Binary Search Trees
Java Software Structures:
Designing and Using Data Structures
Third Edition
John Lewis & Joseph Chase
1-2
© 2010 Pearson Addison-Wesley. All rights reserved. 1-2
Chapter Objectives
• Define a binary search tree abstract data structure
• Demonstrate how a binary search tree can be used to solve problems
• Examine various binary search tree implementations
• Compare binary search tree implementations
1-3
© 2010 Pearson Addison-Wesley. All rights reserved. 1-3
Binary Search Trees
• A binary search tree is a binary tree with the added property that for each node, the left child is less than the parent is less than or equal to the right child
• Given this refinement of our earlier definition of a binary tree, we can now include additional operations
1-4
© 2010 Pearson Addison-Wesley. All rights reserved. 1-4
The operations on a binary search tree
1-5
© 2010 Pearson Addison-Wesley. All rights reserved. 1-5
BinarySearchTreeADT
/**
* BinarySearchTreeADT defines the interface to a binary search tree.
*
* @author Dr. Lewis
* @author Dr. Chase
* @version 1.0, 8/19/08
*/
package jss2;
public interface BinarySearchTreeADT<T> extends BinaryTreeADT<T>
{
/**
* Adds the specified element to the proper location in this tree.
*
* @param element the element to be added to this tree
*/
public void addElement (T element);
1-6
© 2010 Pearson Addison-Wesley. All rights reserved. 1-6
BinarySearchTreeADT (continued)
/**
* Removes and returns the specified element from this tree.
*
* @param targetElement the element to be removed from this tree
* @return the element removed from this tree
*/
public T removeElement (T targetElement);
/**
* Removes all occurences of the specified element from this tree.
*
* @param targetElement the element that the list will have all instances
* of it removed
*/
public void removeAllOccurrences (T targetElement);
/**
* Removes and returns the smallest element from this tree.
*
* @return the smallest element from this tree.
*/
public T removeMin();
1-7
© 2010 Pearson Addison-Wesley. All rights reserved. 1-7
BinarySearchTreeADT (continued)
/**
* Removes and returns the largest element from this tree.
*
* @return the largest element from this tree
*/
public T removeMax();
/**
* Returns a reference to the smallest element in this tree.
*
* @return a reference to the smallest element in this tree
*/
public T findMin();
/**
* Returns a reference to the largest element in this tree.
*
* @return a reference to the largest element in this tree
*/
public T findMax();
}
1-8
© 2010 Pearson Addison-Wesley. All rights reserved. 1-8
UML description of the
BinarySearchTreeADT
1-9
© 2010 Pearson Addison-Wesley. All rights reserved. 1-9
Implementing Binary Search Trees
With Links
• We can simply extend our definition of a
LinkedBinaryTree to create a
LinkedBinarySearchTree
• This class will provide two constructors,
one to create an empty tree and the other
to create a one-element binary tree
1-10
© 2010 Pearson Addison-Wesley. All rights reserved. 1-10
LinkedBinarySearchTree
/**
* LinkedBinarySearchTree implements the BinarySearchTreeADT interface
* with links.
*
* @author Dr. Lewis
* @author Dr. Chase
* @version 1.0, 8/19/08
*/
package jss2;
import jss2.exceptions.*;
import jss2.*;
public class LinkedBinarySearchTree<T> extends LinkedBinaryTree<T>
implements BinarySearchTreeADT<T>
{
/**
* Creates an empty binary search tree.
*/
public LinkedBinarySearchTree()
{
super();
}
1-11
© 2010 Pearson Addison-Wesley. All rights reserved. 1-11
LinkedBinarySearchTree (cont.)
/**
* Creates a binary search with the specified element as its root.
*
* @param element the element that will be the root of the new binary
* search tree
*/
public LinkedBinarySearchTree (T element)
{
super (element);
}
1-12
© 2010 Pearson Addison-Wesley. All rights reserved. 1-12
Implementing Binary Search Trees
With Links
• Now that we know more about how this
tree is to be used (and structured) it is
possible to define a method to add an
element to the tree
• The addElement method finds the proper
location for the given element and adds it
there as a leaf
1-13
© 2010 Pearson Addison-Wesley. All rights reserved. 1-13
LinkedBinarySearchTree -
addElement /**
* Adds the specified object to the binary search tree in the
* appropriate position according to its key value. Note that
* equal elements are added to the right.
*
* @param element the element to be added to the binary search tree
*/
public void addElement (T element)
{
BinaryTreeNode<T> temp = new BinaryTreeNode<T> (element);
Comparable<T> comparableElement = (Comparable<T>)element;
if (isEmpty())
root = temp;
else
{
BinaryTreeNode<T> current = root;
boolean added = false;
while (!added)
{
if (comparableElement.compareTo(current.element) < 0)
{
if (current.left == null)
1-14
© 2010 Pearson Addison-Wesley. All rights reserved. 1-14
LinkedBinarySearchTree –
addElement (continued)
{
current.left = temp;
added = true;
}
else
current = current.left;
}
else
{
if (current.right == null)
{
current.right = temp;
added = true;
}
else
current = current.right;
}
}
}
count++;
}
1-15
© 2010 Pearson Addison-Wesley. All rights reserved. 1-15
Adding elements to a binary search tree
1-16
© 2010 Pearson Addison-Wesley. All rights reserved. 1-16
Removing Elements
• Removing elements from a binary search
tree requires
– Finding the element to be removed
– If that element is not a leaf, then replace it with
its inorder successor
– Return the removed element
1-17
© 2010 Pearson Addison-Wesley. All rights reserved. 1-17
Removing Elements
• The removeElement method makes use of
a private replacement method to find the
proper element to replace a non-leaf
element that is removed
1-18
© 2010 Pearson Addison-Wesley. All rights reserved. 1-18
LinkedBinarySearchTree -
removeElement
/**
* Removes the first element that matches the specified target
* element from the binary search tree and returns a reference to
* it. Throws a ElementNotFoundException if the specified target
* element is not found in the binary search tree.
*
* @param targetElement the element being sought in the binary
* search tree
* @throws ElementNotFoundException if an element not found exception occurs
*/
public T removeElement (T targetElement)
throws ElementNotFoundException
{
T result = null;
if (!isEmpty())
{
if (((Comparable)targetElement).equals(root.element))
{
result = root.element;
root = replacement (root);
count--;
}
1-19
© 2010 Pearson Addison-Wesley. All rights reserved. 1-19
LinkedBinarySearchTree –
removeElement (continued)
else
{
BinaryTreeNode<T> current, parent = root;
boolean found = false;
if (((Comparable)targetElement).compareTo(root.element) < 0)
current = root.left;
else
current = root.right;
while (current != null && !found)
{
if (targetElement.equals(current.element))
{
found = true;
count--;
result = current.element;
if (current == parent.left)
{
parent.left = replacement (current);
}
1-20
© 2010 Pearson Addison-Wesley. All rights reserved. 1-20
LinkedBinarySearchTree –
removeElement (continued)
else
{
parent.right = replacement (current);
}
}
else
{
parent = current;
if (((Comparable)targetElement).compareTo(current.element) < 0)
current = current.left;
else
current = current.right;
}
} //while
if (!found)
throw new ElementNotFoundException("binary search tree");
}
} // end outer if
return result;
}
1-21
© 2010 Pearson Addison-Wesley. All rights reserved. 1-21
LinkedBinarySearchTree -
replacement
/**
* Returns a reference to a node that will replace the one
* specified for removal. In the case where the removed node has
* two children, the inorder successor is used as its replacement.
*
* @param node the node to be removeed
* @return a reference to the replacing node
*/
protected BinaryTreeNode<T> replacement (BinaryTreeNode<T> node)
{
BinaryTreeNode<T> result = null;
if ((node.left == null)&&(node.right==null))
result = null;
else if ((node.left != null)&&(node.right==null))
result = node.left;
else if ((node.left == null)&&(node.right != null))
result = node.right;
1-22
© 2010 Pearson Addison-Wesley. All rights reserved. 1-22
LinkedBinarySearchTree –
replacement (continued)
else
{
BinaryTreeNode<T> current = node.right;
BinaryTreeNode<T> parent = node;
while (current.left != null)
{
parent = current;
current = current.left;
}
if (node.right == current)
current.left = node.left;
else
{
parent.left = current.right;
current.right = node.right;
current.left = node.left;
}
result = current;
}
return result;
}
1-23
© 2010 Pearson Addison-Wesley. All rights reserved. 1-23
Removing elements from a binary tree
1-24
© 2010 Pearson Addison-Wesley. All rights reserved. 1-24
Removing All Occurrences
• The removeAllOccurrences method removes all occurrences of an element from the tree
• This method uses the removeElement method
• This method makes a distinction between the first call and successive calls to the removeElement method
1-25
© 2010 Pearson Addison-Wesley. All rights reserved. 1-25
LinkedBinarySearchTree -
removeAllOccurrences
/**
* Removes elements that match the specified target element from
* the binary search tree. Throws a ElementNotFoundException if
* the sepcified target element is not found in this tree.
*
* @param targetElement the element being sought in the binary \
* search tree
* @throws ElementNotFoundException if an element not found exception occurs
*/
public void removeAllOccurrences (T targetElement)
throws ElementNotFoundException
{
removeElement(targetElement);
try
{
while (contains( (T) targetElement))
removeElement(targetElement);
}
catch (Exception ElementNotFoundException)
{
}
}
1-26
© 2010 Pearson Addison-Wesley. All rights reserved. 1-26
The removeMin Operation
• There are three cases for the location of the minimum element in a binary search tree: – If the root has no left child, then the root is the
minimum element and the right child of the root becomes the new root
– If the leftmost node of the tree is a leaf, then we set its parent’s left child reference to null
– If the leftmost node of the tree is an internal node, then we set its parent’s left child reference to point to the right child of the node to be removed
1-27
© 2010 Pearson Addison-Wesley. All rights reserved. 1-27
LinkedBinarySearchTree -
removeMin
/**
* Removes the node with the least value from the binary search
* tree and returns a reference to its element. Throws an
* EmptyBinarySearchTreeException if this tree is empty.
*
* @return a reference to the node with the least
* value
* @throws EmptyCollectionException if an empty collection exception occurs
*/
public T removeMin() throws EmptyCollectionException
{
T result = null;
if (isEmpty())
throw new EmptyCollectionException ("binary search tree");
else
{
if (root.left == null)
{
result = root.element;
root = root.right;
}
1-28
© 2010 Pearson Addison-Wesley. All rights reserved. 1-28
LinkedBinarySearchTree –
removeMin (continued)
else
{
BinaryTreeNode<T> parent = root;
BinaryTreeNode<T> current = root.left;
while (current.left != null)
{
parent = current;
current = current.left;
}
result = current.element;
parent.left = current.right;
}
count--;
}
return result;
}
1-29
© 2010 Pearson Addison-Wesley. All rights reserved. 1-29
Removing the minimum element from a binary
search tree
1-30
© 2010 Pearson Addison-Wesley. All rights reserved. 1-30
Implementing Binary Search Trees
with Arrays
• Just as we have done with the LinkedBinarySearchTree we can extend our ArrayBinaryTree from chapter 9 to create an ArrayBinarySearchTree
1-31
© 2010 Pearson Addison-Wesley. All rights reserved. 1-31
ArrayBinarySearchTree
/**
* ArrayBinarySearchTree implements a binary search tree using an array.
*
* @author Dr. Lewis
* @author Dr. Chase
* @version 1.0, 8/19/08
*/
package jss2;
import java.util.Iterator;
import jss2.exceptions.*;
import jss2.*;
public class ArrayBinarySearchTree<T> extends ArrayBinaryTree<T>
implements BinarySearchTreeADT<T>
{
protected int height;
protected int maxIndex;
1-32
© 2010 Pearson Addison-Wesley. All rights reserved. 1-32
ArrayBinarySearchTree (continued)
/**
* Creates an empty binary search tree.
*/
public ArrayBinarySearchTree()
{
super();
height = 0;
maxIndex = -1;
}
/**
* Creates a binary search with the specified element as its
* root.
*
* @param element the element that will become the root of the new tree
*/
public ArrayBinarySearchTree (T element)
{
super(element);
height = 1;
maxIndex = 0;
}
1-33
© 2010 Pearson Addison-Wesley. All rights reserved. 1-33
ArrayBinarySearchTree - addElement
/**
* Adds the specified object to this binary search tree in the
* appropriate position according to its key value. Note that
* equal elements are added to the right. Also note that the
* index of the left child of the current index can be found by
* doubling the current index and adding 1. Finding the index
* of the right child can be calculated by doubling the current
* index and adding 2.
*
* @param element the element to be added to the search tree
*/
public void addElement (T element)
{
if (tree.length < maxIndex*2+3)
expandCapacity();
Comparable<T> tempelement = (Comparable<T>)element;
if (isEmpty())
{
tree[0] = element;
maxIndex = 0;
}
else
1-34
© 2010 Pearson Addison-Wesley. All rights reserved. 1-34
ArrayBinarySearchTree - addElement
{
boolean added = false;
int currentIndex = 0;
while (!added)
{
if (tempelement.compareTo((tree[currentIndex]) ) < 0)
{
/** go left */
if (tree[currentIndex*2+1] == null)
{
tree[currentIndex*2+1] = element;
added = true;
if (currentIndex*2+1 > maxIndex)
maxIndex = currentIndex*2+1;
}
else
currentIndex = currentIndex*2+1;
}
1-35
© 2010 Pearson Addison-Wesley. All rights reserved. 1-35
ArrayBinarySearchTree - addElement
else
{
/** go right */
if (tree[currentIndex*2+2] == null)
{
tree[currentIndex*2+2] = element;
added = true;
if (currentIndex*2+2 > maxIndex)
maxIndex = currentIndex*2+2;
}
else
currentIndex = currentIndex*2+2;
}
}
}
height = (int)(Math.log(maxIndex + 1) / Math.log(2)) + 1;
count++;
}
1-36
© 2010 Pearson Addison-Wesley. All rights reserved. 1-36
Using Binary Search Trees:
Implementing Ordered Lists
• Lets look at an example using a binary
search tree to provide an efficient
implementation of an ordered list
• For simplicity, we will implement both the
ListADT and the OrderedListADT in the
BinarySearchTreeList class
1-37
© 2010 Pearson Addison-Wesley. All rights reserved. 1-37
The common operations on a list
1-38
© 2010 Pearson Addison-Wesley. All rights reserved. 1-38
The operation particular to an ordered list
1-39
© 2010 Pearson Addison-Wesley. All rights reserved. 1-39
The BinarySearchTreeList class
/**
* BinarySearchTreeList represents an ordered list implemented using a binary
* search tree.
*
* @author Dr. Lewis
* @author Dr. Chase
* @version 1.0, 8/19/08
*/
package jss2;
import jss2.exceptions.*;
import java.util.Iterator;
public class BinarySearchTreeList<T> extends LinkedBinarySearchTree<T>
implements ListADT<T>, OrderedListADT<T>, Iterable<T>
{
/**
* Creates an empty BinarySearchTreeList.
*/
public BinarySearchTreeList()
{
super();
}
1-40
© 2010 Pearson Addison-Wesley. All rights reserved. 1-40
The BinarySearchTreeList class (cont.)
/**
* Adds the given element to this list.
*
* @param element the element to be added to this list
*/
public void add (T element)
{
addElement(element);
}
/**
* Removes and returns the first element from this list.
*
* @return the first element in this list
*/
public T removeFirst ()
{
return removeMin();
}
1-41
© 2010 Pearson Addison-Wesley. All rights reserved. 1-41
The BinarySearchTreeList class (cont.)
/**
* Removes and returns the last element from this list.
*
* @return the last element from this list
*/
public T removeLast ()
{
return removeMax();
}
/**
* Removes and returns the specified element from this list.
*
* @param element the element being sought in this list
* @return the element from the list that matches the target
*/
public T remove (T element)
{
return removeElement(element);
}
1-42
© 2010 Pearson Addison-Wesley. All rights reserved. 1-42
The BinarySearchTreeList class (cont.)
/**
* Returns a reference to the first element on this list.
*
* @return a reference to the first element in this list
*/
public T first ()
{
return findMin();
}
/**
* Returns a reference to the last element on this list.
*
* @return a reference to the last element in this list
*/
public T last ()
{
return findMax();
}
1-43
© 2010 Pearson Addison-Wesley. All rights reserved. 1-43
The BinarySearchTreeList class (cont.)
/**
* Returns an iterator for the list.
*
* @return an iterator over the elements in this list
*/
public Iterator<T> iterator()
{
return iteratorInOrder();
}
}
1-44
© 2010 Pearson Addison-Wesley. All rights reserved. 1-44
Analysis of linked list and binary search tree
implementations of an ordered list
1-45
© 2010 Pearson Addison-Wesley. All rights reserved. 1-45
Balanced Binary Search Trees
• Why is our balance assumption so
important?
• Lets look at what happens if we insert the
following numbers in order without
rebalancing the tree: 3 5 9 12 18 20
1-46
© 2010 Pearson Addison-Wesley. All rights reserved. 1-46
A degenerate binary tree
1-47
© 2010 Pearson Addison-Wesley. All rights reserved. 1-47
Degenerate Binary Trees
• The resulting tree is called a degenerate
binary tree
• Degenerate binary search trees are far
less efficient than balanced binary search
trees (O(n) on find as opposed to O(logn))
1-48
© 2010 Pearson Addison-Wesley. All rights reserved. 1-48
Balancing Binary Trees
• There are many approaches to balancing
binary trees
• One method is brute force
– Write an inorder traversal to a file
– Use a recursive binary search of the file to
rebuild the tree
1-49
© 2010 Pearson Addison-Wesley. All rights reserved. 1-49
Balancing Binary Trees
• Better solutions involve algorithms such as red-black trees and AVL trees that persistently maintain the balance of the tree
• Most all of these algorithms make use of rotations to balance the tree
• Lets examine each of the possible rotations
1-50
© 2010 Pearson Addison-Wesley. All rights reserved. 1-50
Right Rotation
• Right rotation will solve an imbalance if it is caused by a long path in the left sub-tree of the left child of the root
– Make the left child element of the root the new root
element.
– Make the former root element the right child element of the new root.
– Make the right child of what was the left child of the former root the new left child of the former root.
1-51
© 2010 Pearson Addison-Wesley. All rights reserved. 1-51
Unbalanced tree and balanced tree after a right
rotation
1-52
© 2010 Pearson Addison-Wesley. All rights reserved. 1-52
Left Rotation
• Left rotation will solve an imbalance if it is caused by a long path in the right sub-tree of the right child of the root
– Make the right child element of the root the new root element.
– Make the former root element the left child element of the new root.
– Make the left child of what was the right child of the former root the new right child of the former root.
1-53
© 2010 Pearson Addison-Wesley. All rights reserved. 1-53
Unbalanced tree and balanced tree after a left
rotation
1-54
© 2010 Pearson Addison-Wesley. All rights reserved. 1-54
Rightleft Rotation
• Rightleft rotation will solve an imbalance if it is caused by a long path in the left sub-tree of the right child of the root
• Perform a right rotation of the left child of the right child of the root around the right child of the root, and then perform a left rotation of the resulting right child of the root around the root
1-55
© 2010 Pearson Addison-Wesley. All rights reserved. 1-55
A rightleft rotation
1-56
© 2010 Pearson Addison-Wesley. All rights reserved. 1-56
Leftright Rotation
• Leftright rotation will solve an imbalance if it is caused by a long path in the right sub-tree of the left child of the root
• Perform a left rotation of the right child of the left child of the root around the left child of the root, and then perform a right rotation of the resulting left child of the root around the root
1-57
© 2010 Pearson Addison-Wesley. All rights reserved. 1-57
A leftright rotation
1-58
© 2010 Pearson Addison-Wesley. All rights reserved. 1-58
AVL Trees
• AVL trees keep track of the difference in height between the right and left sub-trees for each node
• This difference is called the balance factor
• If the balance factor of any node is less than -1 or greater than 1, then that sub-tree needs to be rebalanced
• The balance factor of any node can only be changed through either insertion or deletion of nodes in the tree
1-59
© 2010 Pearson Addison-Wesley. All rights reserved. 1-59
AVL Trees
• If the balance factor of a node is -2, this means the left sub-tree has a path that is too long
• If the balance factor of the left child is -1, this means that the long path is the left sub-tree of the left child
• In this case, a simple right rotation of the left child around the original node will solve the imbalance
1-60
© 2010 Pearson Addison-Wesley. All rights reserved. 1-60
A right rotation in an AVL tree
1-61
© 2010 Pearson Addison-Wesley. All rights reserved. 1-61
AVL Trees
• If the balance factor of a node is +2, this means the right sub-tree has a path that is too long
• Then if the balance factor of the right child is +1, this means that the long path is the right sub-tree of the right child
• In this case, a simple left rotation of the right child around the original node will solve the imbalance
1-62
© 2010 Pearson Addison-Wesley. All rights reserved. 1-62
AVL Trees
• If the balance factor of a node is +2, this means the right sub-tree has a path that is too long
• Then if the balance factor of the right child is -1, this means that the long path is the left sub-tree of the right child
• In this case, a rightleft double rotation will solve the imbalance
1-63
© 2010 Pearson Addison-Wesley. All rights reserved. 1-63
A rightleft
rotation in an
AVL tree
1-64
© 2010 Pearson Addison-Wesley. All rights reserved. 1-64
AVL Trees
• If the balance factor of a node is -2, this means the left sub-tree has a path that is too long
• Then if the balance factor of the left child is +1, this means that the long path is the right sub-tree of the left child
• In this case, a leftright double rotation will solve the imbalance
1-65
© 2010 Pearson Addison-Wesley. All rights reserved. 1-65
Red/Black Trees
• Red/Black trees provide another alternative implementation of balanced binary search trees
• A red/black tree is a balanced binary search tree where each node stores a color (usually implemented as a boolean)
• The following rules govern the color of a node: – The root is black
– All children of a red node are black
– Every path from the root to a leaf contains the same number of black nodes
1-66
© 2010 Pearson Addison-Wesley. All rights reserved. 1-66
Valid red/black trees
1-67
© 2010 Pearson Addison-Wesley. All rights reserved. 1-67
Insertion into Red/Black Trees
• The color of a new element is set to red
• Once the new element has been inserted, the tree is rebalanced/recolored as needed to to maintain the properties of a red/black tree
• This process is iterative beginning at the point of insertion and working up the tree toward the root
• The process terminates when we reach the root or when the parent of the current element is black
1-68
© 2010 Pearson Addison-Wesley. All rights reserved. 1-68
Insertion into Red/Black Trees
• In each iteration of the rebalancing process, we will focus on the color of the sibling of the parent of the current node
• There are two possibilities for the parent of the current node: – The parent could be a left child
– The parent could be a right child
• The color of a null node is considered to be black
1-69
© 2010 Pearson Addison-Wesley. All rights reserved. 1-69
Insertion into Red/Black Trees
• In the case where the parent of the current node is a right child, there are two cases
– parentsleftsibling.color == red
– parentsleftsibling.color == black
• If parentsleftsibling.color is red then the processing steps are: – Set the color of current’s parent to black.
– Set the color of parentsleftsibling to black.
– Set the color of current’s grandparent to red.
– Set current to point to the grandparent of current
1-70
© 2010 Pearson Addison-Wesley. All rights reserved. 1-70
Red/black tree after insertion
1-71
© 2010 Pearson Addison-Wesley. All rights reserved. 1-71
Insertion into Red/Black Trees
• If parentsleftsibling.color is black, we first must check to see if current is a left child or a right child
• If current is is a left child, then we must set current equal to current.parent and then rotate current.left to the right
• The we continue as if current were a right child to begin with: – Set the color of current’s parent to black.
– Set the color of current’s grandparent to red.
– If current’s grandparent does not equal null, then rotate current’s parent to the left around current’s grandparent
1-72
© 2010 Pearson Addison-Wesley. All rights reserved. 1-72
Insertion into Red/Black Trees
• In the case where the parent of current is a left child, there are two cases: either parentsrightsibling.color == red or parentsrightsibling.color == black
• If parentsrightsibling.color == red then the processing steps are: – Set the color of current’s parent to black.
– Set the color of parentsrightsibling to black.
– Set the color of current’s grandparent to red.
– Set current to point to the grandparent of current
1-73
© 2010 Pearson Addison-Wesley. All rights reserved. 1-73
Red/black tree after insertion
1-74
© 2010 Pearson Addison-Wesley. All rights reserved. 1-74
Insertion into Red/Black Trees
• If parentsrightsibling.color == black then we first need to check to see if current is a left or right child
• If current is a right child then we set current equal to current.parent then rotate current.right to the left around current
• We then continue as if current was left child to begin with: – Set the color of current’s parent to black.
– Set the color of current’s grandparent to red.
– If current’s grandparent does not equal null, then rotate current’s parent to the right around current’s grandparent
1-75
© 2010 Pearson Addison-Wesley. All rights reserved. 1-75
Element Removal from Red/Black
Trees
• As with insertion, the tree will need to be rebalanced/recolored after the removal of an element
• Again, the process is an iterative one beginning at the point of removal and continuing up the tree toward the root
• This process terminates when we reach the root or when current.color == red
• Like insertion, the cases for removal are symmetrical depending upon whether current is a left or right child
• In insertion, we focused on the color of the sibling of the parent
• In removal, we focus on the color of the sibling of current keeping in mind that a null node is considered to be black
1-76
© 2010 Pearson Addison-Wesley. All rights reserved. 1-76
Element Removal from Red/Black
Trees
• We will only examine the cases where current is a right child, the other cases are easily derived
• If the sibling’s color is red then we begin with the following steps: – Set the color of the sibling to black.
– Set the color of current’s parent to red.
– Rotate the sibling right around current’s parent.
– Set the sibling equal to the left child of current’s parent
1-77
© 2010 Pearson Addison-Wesley. All rights reserved. 1-77
Red/black tree
after removal
1-78
© 2010 Pearson Addison-Wesley. All rights reserved. 1-78
Element Removal from Red/Black
Trees
• Next our processing continues regardless of whether the original sibling was red or black
• Now our processing is divided into two cases based upon the color of the children of the sibling
• If both of the children of the sibling are black then: – Set the color of the sibling to red.
– Set current equal to current’s parent
1-79
© 2010 Pearson Addison-Wesley. All rights reserved. 1-79
Element Removal from Red/Black
Trees
• If the children of the sibling are not both black, then we check to see if the left child of the sibling is black
• If it is, then we must complete the following steps before continuing: – Set the color of the sibling’s right child to black.
– Set the color of the sibling to red.
– Rotate the sibling’s right child left around the sibling.
– Set the sibling equal to the left child of current’s parent
1-80
© 2010 Pearson Addison-Wesley. All rights reserved. 1-80
Element Removal from Red/Black
Trees
• Then to complete the process in the case when both of the children of the sibling are not black: – Set the color of the sibling to the color of current’s parent.
– Set the color of current’s parent to black.
– Set the color of the sibling’s left child to black.
– Rotate the sibling right around current’s parent.
– Set current equal to the root
1-81
© 2010 Pearson Addison-Wesley. All rights reserved. 1-81
Binary Search Trees in the Java
Collections API
• Java provides two implementations of balanced binary search trees
– TreeSet
– TreeMap
• In order to understand the difference between these two, we must first discuss the difference between a set and a map
1-82
© 2010 Pearson Addison-Wesley. All rights reserved. 1-82
Sets and Maps
• In the terminology of the Java Collections API, all of the collections we have discussed thus far would be considered sets
• A set is a collection where all of the data associated with an object is stored in the collection
• A map is a collection where keys that reference an object are stored in the collection but the remaining data is stored separately
1-83
© 2010 Pearson Addison-Wesley. All rights reserved. 1-83
Sets and Maps
• Maps are useful because they allow us to manipulate keys within a collection rather than the entire object
• This allows collections to be smaller, more efficient, and easier to manage
• This also allows for the same object to be part of multiple collections by having keys in each
1-84
© 2010 Pearson Addison-Wesley. All rights reserved. 1-84
The TreeSet and TreeMap Classes
• Both the TreeSet and TreeMap classes are red/black tree implementations of a balanced binary search tree