360 likes | 508 Views
A Binary Search Tree Implementation. Chapter 26. Getting Started An Interface for the Binary Search Tree Duplicate Entries Beginning the Class Definition Searching and Retrieving Traversing Adding an Entry Iterative Implementation Recursive Implementation Removing an Entry
E N D
A Binary Search Tree Implementation Chapter 26
Getting Started An Interface for the Binary Search Tree Duplicate Entries Beginning the Class Definition Searching and Retrieving Traversing Adding an Entry Iterative Implementation Recursive Implementation Removing an Entry Whose Node is a leaf 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 Implementation of the ADT Dictionary Chapter Contents
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 Fig. 26-1 A binary search tree of names.
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 Fig. 26-2 Adding an entry that matches an entry already in a binary tree … continued →
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. Fig. 26-3 A binary search tree with duplicate entries.
Beginning the Class Definition import java.util.Iterator;public class BinarySearchTree extends BinaryTree implements SearchTreeInterface{ public BinarySearchTree() { super(); } // end default constructorpublic BinarySearchTree(Comparable rootEntry) { super(); setRootNode(new BinaryNode(rootEntry)); } // end constructor . . . 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 falseelse if (desiredObject == object in the root of binarySearchTree)return trueelse 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 Fig. 26-5 Recursively adding Chad to smaller subtrees of a binary search tree … continued →
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 (null) to its local parameter rootNode; (b) rootNode references a new node that contains Chad
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 • The node has two children
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 Fig. 26-9 (a) Four possible configurations of node N with one child; (b) resulting two possible configurations after removing node N.
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 immediately before e,b is immediately after e; (b) after deleting the node that contained a and replacing e with a.
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 Fig. 26-13 (a) A binary search tree; (b) after removing Chad;
Removing an Entry, Node Has Two Children Fig. 26-13 (c) after removing Sean; (d) after removing Kathy.
Removing an Entry in the Root Fig. 26-14 (a) Two possible configurations of a root that has one child; (b) after removing 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 remove needs
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. Shorter tree has efficiency O(log n)
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 Fig. 26-16 Some binary trees that are height balanced.
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();public void clear();} // end DictionaryInterface
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 constructorpublic 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 . . .} // end Dictionary