1 / 15

Binary Search Trees

Binary Search Trees. Wellesley College CS230 Lecture 19 Thursday, April 12 Handout #30. PS5 due 11:59pm Wednesday, April 18 Final Project Phase 2 (Program Outline) due 1:30pm Tuesday, April 24. Overview of Today’s Lecture. Review of Binary Search Trees (BSTs)

merton
Télécharger la présentation

Binary Search Trees

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Binary Search Trees Wellesley College CS230 Lecture 19 Thursday, April 12 Handout #30 PS5 due 11:59pm Wednesday, April 18 Final Project Phase 2 (Program Outline) due 1:30pm Tuesday, April 24

  2. Overview of Today’s Lecture • Review of Binary Search Trees (BSTs) • Searching, Insertion, and Deletion in BSTs • Implementing Sets, Bags, Tables using BSTs

  3. Binary Search Trees To get full advantage of binary trees for data structures, need the values to be ordered. A binary search tree (BST) is a binary tree in which the following BST properties hold at every node:(1) All elements in the left subtree are ≤ the value; (2) All elements in the right subtree are ≥ the value. Here is a sample BST: P • Notes: • A BST may contain duplicates • The in-order traversal of BST elements yields them in sorted order. E.g.: C F F J M P S V • For n > 1, there is more than one BST with n elements. F S C M V F J

  4. Predecessors and Succesors The predecessor of a node N is the node that immediately precedes N in an in-order traversal of the tree (or null if no such node exists). E.g., the predecessor of node P is node M, of node M is node J, and of node J is node F. The successor of a node is the node N that immediately follows N in an in-order traversal of the tree (or null if no such node exists). E.g., the successor of node F is node J, of node J is node M, and of node M is node P. P F S C M V F J

  5. An MBST<T> Class import java.util.*; // import Comparator, Iterator public class MBST<T> { private static MBinTree MBT; // Local abbreviation for MBinTree // Instance Variables private Comparator<T> comp; private MBinTree<T> elts; // Constructor Methods // Constructor that supplies explicit Comparator public MBST (Comparator<T> comp) { this.comp = comp; elts = MBT.<T>leaf(); } // Constructor without an explicit Comparator uses null // as the Comparator. public MBST () { this(null); } … other methods go here … }

  6. Comparisons in MBST<T> // Instance methods public Comparator<T> comparator() { return comp; } // Method uses for all comparisons. Use the explicit Comparator comp // if it's non-null; otherwise, assume T extends Comparable<T> and // use the compareTo method of an element. private int compare (T x, T y) { if (comp != null) { return comp.compare(x,y); } else { // Note: the cast here will generate a warning in Java 1.5 // because the cast can fail at run-time for a non-Comparable x. return ((Comparable<T>) x).compareTo(y); } }

  7. Searching in MBST<T> /** Return true if x is in the tree and false otherwise */ public boolean search (T x) { MBinTree<T> here = elts; while (! MBT.isLeaf(here)) { int c = compare(x, MBT.value(here)); if (c == 0) { return true; } else if (c < 0) { here = MBT.left(here); } else { here = MBT.right(here); } } // Only reach here if got to leaf without finding element: return false; }

  8. Insertion in MBST<T> public void insert (T x) { MBinTree<T> child = elts; MBinTree<T> parent = null; // parent of child boolean isChildToLeft = true; // is child the left of parent? (initialized arbitrarily) while (! MBT.isLeaf(child)) { // search for insertion point int c = compare(x, MBT.value(child)); if (c == 0) throw new MBSTInsertionException(child); // element is already in tree else if (c < 0) { parent = child; child = MBT.left(child); isChildToLeft = true; } else { parent = child; child = MBT.right(child); isChildToLeft = false; } } // Only reach here if got to leaf without finding element: // Replace the leaf in parent by a new node: MBinTree<T> newNode = MBT.node(MBT.<T>leaf(), x, MBT.<T>leaf()); setChild(parent, isChildToLeft, newNode); }

  9. Setting the Child private void setChild (MBinTree<T> parent, boolean isChildToLeft, MBinTree<T> newChild) { if (parent == null) { // special case when no parent elts = newChild; } else if (isChildToLeft) { MBT.setLeft(parent, newChild); } else { MBT.setRight(parent, newChild); } }

  10. Deletion In MBST<T> public boolean delete (T x) { MBinTree<T> child = elts; MBinTree<T> parent = null; // parent of child boolean isChildToLeft = true; // is child the left of parent? (initialized arbitrarily) while (! MBT.isLeaf(child)) { // search for insertion point int c = compare(x, MBT.value(child)); if (c == 0) { deleteNode(parent, child, isChildToLeft); // See next slide return true; // element is in tree. } else if (c < 0) { parent = child; child = MBT.left(child); isChildToLeft = true; } else { parent = child; child = MBT.right(child); isChildToLeft = false; } } // Only reach here if got to leaf without finding element. return false; // element not in tree. }

  11. deleteNode() // Delete a non-leaf child from (possibly null) parent private void deleteNode (MBinTree<T> parent, MBinTree<T> child, boolean isChildToLeft) { // Easy cases are if one subtree of child is a leaf. if (MBT.isLeaf(MBT.left(child))) { setChild(parent, isChildToLeft, MBT.right(child)); } else if (MBT.isLeaf(MBT.right(child))) { setChild(parent, isChildToLeft, MBT.left(child)); } else { // Hard case is if neither subtree of child is a leaf. // In this case delete predecessor and replace // child's value by predecessor's value T predecessorValue = deletePredecessor(child); // See next slide // predecessorValue is guaranteed to be non-null in this case, // since only get here if MBT.left(child) is not a leaf. MBT.setValue(child, predecessorValue); } }

  12. deletePredecessor() // Deletes the predecessor of this node and returns its value. // Returns null if there is no predecessor private T deletePredecessor (MBinTree<T> node) { if (MBT.isLeaf(MBT.left(node))) { return null; // No predecessor; return null } else { MBinTree<T> parent = node; MBinTree<T> child = MBT.left(node); boolean isChildToLeft = true; while (!(MBT.isLeaf(MBT.right(child)))) { // Find the predecessor node = rightmost node to the left of given node parent = child; child = MBT.right(child); isChildToLeft = false; } deleteNode(parent, child, isChildToLeft); // delete predecessor node // Since right of child is a leaf, this will use "easy" case of deleteNode(); return MBT.value(child); // return value in predecessor node } }

  13. Abstracting over BST search: FindInfo public class FindInfo<T> { public MBinTree<T> parent, child; public boolean isChildToLeft; public FindInfo (MBinTree<T> parent, MBinTree<T> child, boolean isChildToLeft) { this.parent = parent; this.child = child; this.isChildToLeft = isChildToLeft; } }

  14. Abstracting over BST search: find() /** If x exists in tree returns a FindInfo fi where: + fi.child is the node containing x; + fi.parent is the parent of child (or null if there is no parent); + fi.isChildToLeft is true if child is to the left of parent (or there is none); else false If x does not exist in the tree, returns a FindInfo fi where: + fi.child is the leaf where x would be inserted into the tree. + fi.parent is the node below which x would be inserted into the tree. + fi.isChildToLeft is true if x would be inserted to the left of fei.parent; else false */ public FindInfo<T> find (T x) { MBinTree<T> child = elts; MBinTree<T> parent = null; // parent of child boolean isChildToLeft = true; // is child the left of parent? (initialized arbitrarily) int c = 0; // result of comparison (initialized arbitrarily) while (!MBT.isLeaf(child) && // stuff result of comparison in variable c !((c = compare(x, MBT.value(child))) == 0)) { if (c < 0) {parent = child; child = MBT.left(child); isChildToLeft = true;} else {parent = child; child = MBT.right(child); isChildToLeft = false;} } return new FindInfo<T>(parent, child, isChildToLeft); }

  15. Abstracted search(), insert(), delete() public boolean search (T x) { return (!MBT.isLeaf(find(x).child)); } public void insert (T x) { FindInfo<T> fi = find(x); if (MBT.isLeaf(fi.child)) { MBinTree<T> newNode = MBT.node(MBT.<T>leaf(), x, MBT.<T>leaf()); setChild(fi.parent, fi.isChildToLeft, newNode); } else { throw new MBSTInsertionException(fi.child); // element is already in tree } } public boolean delete (T x) { FindInfo<T> fi = find(x); if (!MBT.isLeaf(fi.child)) { deleteNode(fi.parent, fi.child, fi.isChildToLeft); return true; // element is in tree } else { return false; // element not in tree. } }

More Related