CHAPTER 10: Binary Search...

Preview:

Citation preview

© 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

Recommended