A Binary Search Tree Implementation
Chapter 26
Chapter Contents
Getting Started
• An Interface for the Binary Search Tree
• Duplicate Entries
• Beginning the Class Definition
Searching and Retrieving Traversing
Adding an Entry
• Iterative Implementation
• Whose Node Has One Child
• Whose Node has Two Children
• In the Root
• Iterative Implementation
• Recursive Implementation
Efficiency of Operations
• Importance of Balance
• Order in Which Nodes Are Added
Getting Started
A binary search tree is a binary tree
• Nodes contain Comparable objects
For each node in the tree
• The data in a node is greater than the data in the node's left subtree
• The data in a node is less than the data in the node's right subtree
Getting Started
An Interface for the Binary Search Tree
import java.util.Iterator;
public interface SearchTreeInterface extends TreeInterface { public boolean contains(Comparable entry);
public Comparable getEntry(Comparable entry);
public Comparable add(Comparable newEntry);
public Comparable remove(Comparable entry);
public Iterator getInorderIterator();
} // end SearchTreeInterface
An Interface for the
Binary Search Tree
An Interface for the Binary Search Tree
Fig. 26-2 (ctd.) Adding an entry that matches an entry already in a binary tree.
Duplicate Entries
If duplicates are allowed, place the
duplicate in the entry's right subtree.
If duplicates are allowed, place the
duplicate in the entry's right subtree.
Beginning the Class Definition
import java.util.Iterator;
public class BinarySearchTree extends BinaryTree implements SearchTreeInterface
{ public BinarySearchTree() { super();
} // end default constructor
public BinarySearchTree(Comparable rootEntry) { super();
setRootNode(new BinaryNode(rootEntry));
} // end constructor
. . . Note that it is serializable because its base class BinaryTree is serializable.
Note that it is serializable because its base class BinaryTree is serializable.
Searching and Retrieving
Like performing a binary search of an array For a binary array
• Search one of two halves of the array
For the binary search tree
• You search one of two subtrees of the binary search tree
Searching and Retrieving
The search algorithm
Algorithm bstSearch(binarySearchTree, desiredObject) // Searches a binary search tree for a given object.
// Returns true if the object is found.
if (binarySearchTree is empty) return false
else if (desiredObject == object in the root of binarySearchTree) return true
else if (desiredObject < object in the root of binarySearchTree)
return bstSearch(left subtree of binarySearchTree, desiredObject) else
return bstSearch(right subtree of binarySearchTree, desiredObject)
Traversing
The SearchTreeInterface provides the method getInorderIterator
• Returns an inorder iterator
Our class is a subclass of BinaryTree
• It inherits getInorderIterator
• This iterator traverses entries in ascending order
• Uses the entries' method compareTo
Adding an Entry
Fig. 26-4 (a) A binary search tree;
(b) the same tree after adding Chad.
Adding an Entry Recursively
Adding an Entry Recursively
Fig. 26-5 (ctd.) Recursively adding
Chad to smaller subtrees of a binary
search tree.
Adding an Entry Recursively
Fig. 26-6 (a) The method addNode copies its argument
Adding an Entry Recursively
Fig. 26-7 After adding a node to the subtree passed to it,
addNode returns a reference to the subtree so it can be attached to the rest of the original tree.
Removing an Entry
The remove method must receive an entry to be matched in the tree
• If found, it is removed
• Otherwise the method returns null
Three cases
• The node has no children, it is a leaf (simplest case)
• The node has one child
19
Removing an Entry, Node a Leaf
Fig. 26-8 (a) Two possible configurations of leaf node N; (b) the resulting two possible
configurations after removing node N.
Removing an Entry,
Node Has One Child
Removing an Entry, Node Has Two Children
Fig. 26-10 Two possible configurations of node N that has two children.
Removing an Entry, Node Has Two Children
Fig. 26-11 Node N and its subtrees; (a) entry a is
Removing an Entry, Node Has Two Children
Fig. 26-12 The largest entry a in node N's left subtree occurs in the subtree's rightmost node R.
Removing an Entry,
Node Has Two Children
25
Removing an Entry, Node Has Two Children
Fig. 26-13 (c) after removing Sean;
(d) after removing Kathy.
Removing an Entry in the Root
Iterative Implementation
To locate the desired entry
• The remove method given entry to be matched
• If remove finds the entry, it returns the entry
• If not, it returns null
The compareTo method used to make comparisons with the entries in the tree
Recursive Implementation
Details similar to adding an entry
The public remove method calls a private recursive remove method
• The public remove returns removed entry
• Private remove must return root of revised tree
• Thus use parameter that is an instance of
ReturnObject to return the value the public
Efficiency of Operations
Operations add, remove, getEntry require a search that begins at the root
Maximum number of comparisons is
directly proportional to the height, h of the tree
These operations are O(h)
Thus we desire the shortest binary search tree we can create from the data
Efficiency of Operations
Fig. 26-15 Two binary search trees
that contain the same data.
Importance of Balance
Completely balanced
• Subtrees of each node have exactly same height
Height balanced
• Subtrees of each node in the tree differ in height by no more than 1
Completely balanced or height balanced trees are balanced
Importance of Balance
Importance of Balance
The order in which entries are added affect the shape of the tree
If entries are added to an empty binary tree
• Best not to have them sorted first
• Tree is more balanced if entries are in random order
Implementation of the ADT Dictionary
Interface for a dictionary
import java.util.Iterator;
public interface DictionaryInterface
{ public Object add(Object key, Object value);
public Object remove(Object key);
public Object getValue(Object key);
public boolean contains(Object key);
public Iterator getKeyIterator();
public Iterator getValueIterator();
public boolean isEmpty();
public int getSize();
35
Implementation of the ADT Dictionary
Class of data entries (can be private, internal to class Dictionary)
private class Entry implements Comparable, java.io.Serializable { private Object key;
private Object value;
private Entry(Object searchKey, Object dataValue) { key = searchKey;
value = dataValue; } // end constructor public int compareTo(Object other)
{ Comparable cKey = (Comparable)key;
return cKey.compareTo(((Entry)other).key); } // end compareTo
< The class also defines the methods getKey, getValue, and setValue;
no setKey method is provided. >
. . .
} // end Entry
Implementation of the ADT Dictionary
Beginning of class Dictionary
import java.util.Iterator;
public class Dictionary implements DictionaryInterface, java.io.Serializable
{ private SearchTreeInterface bst;
public Dictionary()
{ bst = new BinarySearchTree();|
} // end default constructor . . .