Review_ Binary Search Tree - UCO Department of Computer Science.ppt by pptfiles


									A Review of Binary Search

    Dr. Gang Qian

    Department of Computer Science
    University of Central Oklahoma
Objectives (Sections 10.1 and 10.2)

n   Binary tree
    q   Definition
    q   Traversal
n   Binary search tree
    q   Definition
    q   Tree search
    q   Insertion
    q   Deletion
Binary Tree

n   Definition (Mathematical Structure)
    q   A binary tree is either empty, or it consists of a
        node called the root together with two binary trees
        called the left subtree and the right subtree of the
n   Note
    q   Linked implementation is natural
    q   Other implementation is also possible
n   The concept of left and right is important for
    binary trees
    q   Binary trees with two nodes

                  ¹                     Not a binary

    q   Binary trees with three nodes
Traversal of Binary Trees

n   Traversal
    q   Moving through all nodes of the binary tree,
        visiting each node in turn
    q   The order of traversal should be logical
n   At any given node in a binary tree, there are
    three tasks to do:
    q   Visit the node itself (V)
    q   Traverse its left subtree (L)
    q   Traverse its right subtree (R)
n   There are six ways to arrange the three
    q   V L R; L V R; L R V; V R L; R V L; R L V
n   They are reduced to three if we always
    consider the left subtree before the right
    q   Preorder: V L R
    q   Inorder: L V R
    q   Postorder: L R V
n   Example
    (Expression Trees)
    q   Preorder traversal
        n   -axbc
    q   Inorder traversal
        n   a–bxc
    q   Postorder traversal
        n   abcx–
Linked Implementation of Binary Tree
n   Binary tree node class
    template <class Entry>
    struct Binary_node {
       // data members:
       Entry data;
       Binary_node<Entry> *left;
       Binary_node<Entry> *right;
       // constructors:
       Binary_node( );
       Binary_node(const Entry &x);
n   Binary Tree Class Specification
    template <class Entry>
    class Binary_tree {
       Binary_tree( );
       bool empty( ) const;
       void preorder(void (*visit)(Entry &));
       void inorder(void (*visit)(Entry &));
       void postorder(void (*visit)(Entry &));

       int size( ) const;
       void clear( );
       int height( ) const;
                                                 (continued on next slide)
     Binary_tree (const Binary_tree <Entry> &original);
     Binary_tree & operator = (const Binary_tree <Entry> &original);
     ~Binary_tree( );

  // Add auxiliary function prototypes here.

     Binary_node<Entry> *root;
n   Implementation of inorder traversal
    q   Use an auxiliary recursive function that applies to subtrees
    template <class Entry>
    void Binary_tree<Entry> :: inorder(void (*visit)(Entry &))
    /* Post: The tree has been traversed in inorder sequence.
    Uses: The function recursive_inorder */
       recursive_inorder(root, visit);
template <class Entry>
void Binary tree<Entry> ::
       recursive_inorder(Binary_node<Entry> *sub_root,
                          void (*visit)(Entry &))
/* Pre: sub_root is either NULL or points to a subtree of the
   Post: The subtree has been traversed in inorder sequence
   Uses: The function recursive_inorder recursively */
   if (sub_root != NULL) {
      recursive_inorder(sub_root->left, visit);
      recursive_inorder(sub_root->right, visit);
Binary Search Tree

n   Motivation
    q   Binary search O(log n) is much more efficient than
        sequential search O(n)
        n   We can use a contiguous implementation
        n   We cannot use linked list implementation
        n   What if the data needs frequent updates
    q   Need an implementation for ordered lists that
        n   searches quickly (as with binary search on a contiguous
        n   makes insertions and deletions quickly (as with a linked
n   Definition
    q   A binary search tree is a binary tree that is either empty or
        in which the data entry of every node has a key and
        satisfies the following conditions:
        n The key of the left child of a node is less than the key of
            its parent node
        n   The key of the right child of a node is greater than the key of
            its parent node
        n   The left and right subtrees of the root are also binary search
    q   Additional requirements
        n   No two entries in a binary search tree may have equal keys
Binary Search Tree Class

n   The binary search tree class is derived from the
    binary tree class
    q   All binary tree methods are inherited
        template <class Record>
        class Search_tree: public Binary_tree<Record> {
           Error_code insert(const Record &new_data);
           Error_code remove(const Record &old_data);
           Error_code tree_search(Record &target) const;
        private: // Add auxiliary function prototypes here.
n   The inherited methods include the constructors, the
    destructor, clear, empty, size, height, and the
    traversals preorder, inorder, and postorder
n   Record class
    q   Each record is associated with a Key
    q   The keys can be compared with the usual comparison
    q   By casting records to their corresponding keys, the
        comparison operators apply to records as well as to keys
Tree Search

n   To search for the target, first compare it with
    the entry at the root of the tree.
    q   If their keys match, then search finishes
    q   Otherwise, depending on whether the target is
        smaller than or greater than the root, search goes
        to the left subtree or the right subtree as
        appropriate and repeat the search in that subtree
n   The process is implemented by calling an
    auxiliary recursive function
n   Recursive auxiliary function
    template <class Record>
    Binary_node<Record> *Search_tree<Record> ::
      search_for_node(Binary_node<Record>* sub_root,
                         const Record &target) const
      if (sub_root == NULL || sub_root->data == target)
          return sub_root;
      else if (sub_root->data < target)
          return search_for_node(sub_root->right, target);
      else return search_for_node(sub_root->left, target);
    q Tail Recursion

    q Recursion tree will be a chain
n   Non-recursive version
    template <class Record>
    Binary_node<Record> *Search_tree<Record> ::
      search_for_node(Binary_node<Record>* sub_root,
                         const Record &target) const
      while (sub_root != NULL && sub_root->data != target)
         if (sub_root->data < target) sub_root = sub_root->right;
         else sub_root = sub_root->left;
      return sub_root;
n   Public method tree_search
    template <class Record>
    Error_code Search_tree<Record> ::
                  tree_search(Record &target) const
    /* Post: If there is an entry in the tree whose key matches that in
       target , the parameter target is replaced by the corresponding
       record from the tree and a code of success is returned.
       Otherwise a code of not_present is returned.
       Uses: function search_for_node */
       Error_code result = success;
       Binary_node<Record> *found = search_for_node(root, target);
       if (found == NULL) result = not_present;
       else target = found->data;
       return result;
n   Analysis of tree search
    q   The same keys may be built into binary search
        trees of many different shapes
q   If a binary search tree is nearly balanced (“bushy”),
    then search on a tree with n vertices will do O(log n)
    comparisons of keys
q   The bushier the tree, the smaller the number of
    n   The number of vertices between the root and the
        target, inclusive, is the number of comparisons needed
        to find the target
q   If the tree degenerates into a chain, then tree search
    becomes the same as sequential search, doing O(n)
    comparisons on n vertices
    n   The worst case for tree search
q   Often impossible to predict the shape of the
q   If the keys are inserted in random order,
    then tree search usually performs almost
    as well as binary search
q   If the keys are inserted in sorted order into
    an empty tree, the degenerate case will
Insertion into A Binary Search Tree
n   Find the location in the tree suitable to the
    new record
n   Insertion method
    q   Call an auxiliary recursive function
    template <class Record>
    Error_code Search_tree<Record> :: search_and_insert(
      Binary_node<Record> * &sub_root, const Record
      if (sub_root == NULL) {
         sub_root = new Binary_node<Record>(new_data);
         return success;
      else if (new_data < sub_root->data)
         return search_and_insert(sub_root->left, new_data);
      else if (new_data > sub_root->data)
         return search_and_insert(sub_root->right, new_data);
      else return duplicate_error;
q   Public method: insert
    template <class Record>
    Error_code Search_tree<Record> :: insert(
      const Record &new_data)
      return search_and_insert(root, new_data);
q   The method insert can usually insert a new node
    into a random binary search tree with n nodes in
    O(log n) steps
Removal from A Binary Search Tree
n   Key Issue:
    q   The integrity of the tree has to be kept after
n   Auxiliary recursive function
    template <class Record>
    Error_code Search_tree<Record> :: search_and_delete(
         Binary_node<Record>* &sub_root, const Record &target)
    /* Pre: sub_root is either NULL or points to a subtree
       Post: If the key of target is not in the subtree, a code of not present is
         returned. Otherwise, a code of success is returned and the subtree
         node containing target has been removed in such a way that the
         properties of a binary search tree is preserved.
       Uses: Functions search_and_delete recursively */
       if (sub_root == NULL)
          return not_present;
       else if (sub_root->data == target) {
          if (sub_root->right == NULL) { // No right child
             Binary_node<Record> *to_delete = sub_root;
             sub_root = sub_root->left;
             delete to_delete;
                                                        (continued on next slide)
    else if (sub_root->left == NULL) { // No left child
      Binary_node<Record> *to_delete = sub_root;
      sub_root = sub_root->right;
      delete to_delete;
    } else { // subroot has two children
      // search for the immediate predecessor
      Binary_node<Record> * predecessor_node = sub_root->left;
      while (predecessor_node->right != NULL) {
         predecessor_node = predecessor_node->right;
      // replace the target with the immediate predecessor
      sub_root->data = predecessor_node->data;
      // delete the redundant immediate predecessor
      search_and_delete(sub_root->left, sub_root->data);
                                             (continued on next slide)
    else if (target < sub_root->data)
      return search_and_delete(sub_root->left, target);
      return search_and_delete(sub_root->right, target);
    return success;
n   Public remove method
    template <class Record>
    Error_code Search_tree<Record> :: remove(
       const Record &target)
    /* Post: If a Record with a key matching that of target belongs
       to the Search_tree, a code of success is returned and the
       corresponding node is removed from the tree. Otherwise, a
       code of not_present is returned
       Uses: Function search_and_delete */
       return search_and_delete(root, target);
    q Uses an auxiliary recursive function that refers to the actual
       nodes in the tree
Building a Binary Search Tree

n   Build a bushy binary search tree from sorted
n   Textbook: pp. 463 -- 470
Random Search Trees and Optimality

n   The average binary search tree requires
    approximately 1.39 times as many
    comparisons as a completely balanced tree.

To top