CMSC 341 Binary Search Trees.

Slides:



Advertisements
Similar presentations
Binary Trees, Binary Search Trees CMPS 2133 Spring 2008.
Advertisements

1 Jake’s Pizza Shop Owner Jake Manager Chef Brad Carol Waitress Waiter Cook Helper Joyce Chris Max Len.
Binary Trees, Binary Search Trees COMP171 Fall 2006.
Trees, Binary Trees, and Binary Search Trees COMP171.
Trees, Binary Trees, and Binary Search Trees. 2 Trees * Linear access time of linked lists is prohibitive n Does there exist any simple data structure.
Lec 15 April 9 Topics: l binary Trees l expression trees Binary Search Trees (Chapter 5 of text)
1 BST Trees A binary search tree is a binary tree in which every node satisfies the following: the key of every node in the left subtree is.
More Trees COL 106 Amit Kumar and Shweta Agrawal Most slides courtesy : Douglas Wilhelm Harder, MMath, UWaterloo
CS 146: Data Structures and Algorithms June 18 Class Meeting Department of Computer Science San Jose State University Summer 2015 Instructor: Ron Mak
Lecture Objectives  To learn how to use a tree to represent a hierarchical organization of information  To learn how to use recursion to process trees.
Recursion Bryce Boe 2013/11/18 CS24, Fall Outline Wednesday Recap Lab 7 Iterative Solution Recursion Binary Tree Traversals Lab 7 Recursive Solution.
Tree. Basic characteristic Top node = root Left and right subtree Node 1 is a parent of node 2,5,6. –Node 2 is a parent of node.
1 Trees A tree is a data structure used to represent different kinds of data and help solve a number of algorithmic problems Game trees (i.e., chess ),
CMSC 341 Introduction to Trees. 8/3/2007 UMBC CMSC 341 TreeIntro 2 Tree ADT Tree definition  A tree is a set of nodes which may be empty  If not empty,
DATA STRUCTURES AND ALGORITHMS Lecture Notes 5 Prepared by İnanç TAHRALI.
BINARY SEARCH TREE. Binary Trees A binary tree is a tree in which no node can have more than two children. In this case we can keep direct links to the.
Tree (new ADT) Terminology:  A tree is a collection of elements (nodes)  Each node may have 0 or more successors (called children)  How many does a.
Binary Trees, Binary Search Trees RIZWAN REHMAN CENTRE FOR COMPUTER STUDIES DIBRUGARH UNIVERSITY.
Binary Search Trees Binary Search Trees (BST)  the tree from the previous slide is a special kind of binary tree called a binary.
1 Chapter 10 Trees. 2 Definition of Tree A tree is a set of linked nodes, such that there is one and only one path from a unique node (called the root.
Trees, Binary Trees, and Binary Search Trees COMP171.
Topic 15 The Binary Search Tree ADT Binary Search Tree A binary search tree (BST) is a binary tree with an ordering property of its elements, such.
Lec 15 Oct 18 Binary Search Trees (Chapter 5 of text)
Starting Out with C++ Early Objects Seventh Edition by Tony Gaddis, Judy Walters, and Godfrey Muganda Modified for use at Midwestern State University Chapter.
Binary Trees Chapter 10. Introduction Previous chapter considered linked lists –nodes connected by two or more links We seek to organize data in a linked.
CSCS-200 Data Structure and Algorithms Lecture
ADT Binary Search Tree Ellen Walker CPSC 201 Data Structures Hiram College.
CMSC 341 Binary Heaps Priority Queues. 2 Priority: some property of an object that allows it to be prioritized WRT other objects (of the same type) Priority.
Copyright © 2012 Pearson Education, Inc. Chapter 20: Binary Trees.
CMSC 341 Binary Search Trees. 8/3/2007 UMBC CMSC 341 BST 2 Binary Search Tree A Binary Search Tree is a Binary Tree in which, at every node v, the values.
CMSC 202, Version 5/02 1 Trees. CMSC 202, Version 5/02 2 Tree Basics 1.A tree is a set of nodes. 2.A tree may be empty (i.e., contain no nodes). 3.If.
Copyright © 2009 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Chapter 20: Binary Trees.
1 Trees 3: The Binary Search Tree Reading: Sections 4.3 and 4.6.
Data Structure and Algorithms
BST Trees
Binary Search Tree (BST)
Trees.
CSE 373 Data Structures Lecture 7
CMSC 341 Lecture 13 Leftist Heaps
Data Structures Using C++ 2E
Binary Trees, Binary Search Trees
Chapter 20: Binary Trees.
Binary Search Trees.
Map interface Empty() - return true if the map is empty; else return false Size() - return the number of elements in the map Find(key) - if there is an.
CMSC 341 Lecture 10 Binary Search Trees
Trees 3: The Binary Search Tree
Chapter 21: Binary Trees.
Trees, Binary Trees, and Binary Search Trees
Lec 12 March 9, 11 Mid-term # 1 (March 21?)
CMSC 341 Binary Search Trees 11/19/2018.
Find in a linked list? first last 7  4  3  8 NULL
CMSC 341 Introduction to Trees.
CMSC 341 Introduction to Trees.
Lecture No.16 Data Structures Dr. Sohail Aslam.
CMSC 341 Binary Search Trees.
Trees CMSC 202, Version 5/02.
CMSC 341 Binary Search Trees 1/3/2019.
CMSC 202 Trees.
Binary Trees, Binary Search Trees
CMSC 341 Binary Search Trees 2/23/2019.
Tree.
CMSC 341 Binary Search Trees 5/8/2019.
Trees.
Trees CSE 373 Data Structures.
CMSC 341 Binary Search Trees 5/28/2019.
CMSC 341 Binary Search Trees 8/3/2007 CMSC 341 BST.
CMSC 341 Binary Search Trees 2/21/2006.
Binary Trees, Binary Search Trees
Data Structures Using C++ 2E
Tree (new ADT) Terminology: A tree is a collection of elements (nodes)
Presentation transcript:

CMSC 341 Binary Search Trees

Binary Search Tree A Binary Search Tree is a Binary Tree in which, at every node v, the values stored in the left subtree of v are less than the value at v and the values stored in the right subtree are greater. The elements in the BST must be comparable. Duplicates are not allowed in our discussion. Note that each subtree of a BST is also a BST. 2/21/2006

A BST of integers 42 20 50 60 99 35 32 27 25 A B C D A = all values less than 20 B = values less than 32, but larger than 27. Eg 28 – 31 C = values larger than 60, but less than 99 D = values larger than 99 Describe the values which might appear in the subtrees labeled A, B, C, and D 2/21/2006

BST Implementation The SearchTree ADT A search tree is a binary search tree which stores homogeneous elements with no duplicates. It is dynamic. The elements are ordered in the following ways inorder -- as dictated by operator< preorder, postorder, levelorder -- as dictated by the structure of the trer 2/21/2006

BST Implementation template <typename Comparable> class BinarySearchTree { public: BinarySearchTree( ); BinarySearchTree( const BinarySearchTree & rhs ); ~BinarySearchTree( ); const Comparable & findMin( ) const; const Comparable & findMax( ) const; bool contains( const Comparable & x ) const; bool isEmpty( ) const; void printTree( ) const; void makeEmpty( ); void insert( const Comparable & x ); void remove( const Comparable & x ); 2/21/2006

BST Implementation (2) const BinarySearchTree & operator=( const BinarySearchTree & rhs ); private: struct BinaryNode { Comparable element; BinaryNode *left; BinaryNode *right; BinaryNode( const Comparable & theElement, BinaryNode *lt, BinaryNode *rt ) :element( theElement ), left( lt ), right( rt) { } }; 2/21/2006

BST Implementation (3) // private data BinaryNode *root; // private recursive functions void insert( const Comparable & x, BinaryNode * & t ) const; void remove(const Comparable & x, BinaryNode * & t ) const; BinaryNode * findMin( BinaryNode *t ) const; BinaryNode * findMax( BinaryNode *t ) const; bool contains( const Comparable & x, BinaryNode *t ) const; void makeEmpty( BinaryNode * & t ); void printTree( BinaryNode *t ) const; BinaryNode * clone( BinaryNode *t ) const; }; 2/21/2006

BST “contains” method // Returns true if x is found (contained) in the tree. bool contains( const Comparable & x ) const { return contains( x, root ); } // Internal (private) method to test if an item is in a subtree. // x is item to search for. // t is the node that roots the subtree. bool contains( const Comparable & x, BinaryNode *t ) const if( t == NULL ) return false; else if( x < t->element ) return contains( x, t->left ); else if( t->element < x ) return contains( x, t->right ); else return true; // Match 2/21/2006

Performance of “contains” Searching in randomly built BST is O(lg n) on average but generally, a BST is not randomly built Asymptotic performance is O(height) in all cases Elements inserted in the order: 50,40,30,20,10 avg search time: 0+1+2+3+4+5 = 10 Elements inserted in order: 30,20,10,40,50 avg search time: 0+1+2+1+2=6 How many permutations of 5 things? 5! = 120 must look at average IPL of the120 trees 2/21/2006

The insert Operation // Internal method to insert into a subtree. // x is the item to insert. // t is the node that roots the subtree. // Set the new root of the subtree. void insert( const Comparable & x, BinaryNode * & t ) { if( t == NULL ) t = new BinaryNode( x, NULL, NULL ); else if( x < t->element ) insert( x, t->left ); else if( t->element < x ) insert( x, t->right ); else ; // Duplicate; do nothing } Method: recursively traverses the tree looking for a null pointer at the point of insertion. If found, constructs a new node and stitches it into the tree. If duplicate found, simply returns with no insertion done. Question: Suppose Item_Not_Found object is inserted? The insert code allows it. This would mean the find operation could no longer indicate an unsuccessful search. Esoteric but possible -- and a reason not to use the text’s approach to indicating unsuccessful search. Asymptotic performance of insert = O(n) as usual. 2/21/2006

Predecessor in BST Predecessor of a node v in a BST is the node that holds the data value that immediately precedes the data at v in order. Finding predecessor v has a left subtree then predecessor must be the largest value in the left subtree (the rightmost node in the left subtree) v does not have a left subtree predecessor is the first node on path back to root that does not have v in its left subtree 2/21/2006

Successor in BST Successor of a node v in a BST is the node that holds the data value that immediately follows the data at v in order. Finding Successor v has right subtree successor is smallest value in right subtree (the leftmost node in the right subtree) v does not have right subtree successor is first node on path back to root that does not have v in its right subtree 2/21/2006

The remove Operation // Internal (private) method to remove from a subtree. // x is the item to remove. // t is the node that roots the subtree. // Set the new root of the subtree. void remove( const Comparable & x, BinaryNode * & t ) { if( t == NULL ) return; // x not found; do nothing if( x < t->element ) remove( x, t->left ); else if( t->element < x ) remove( x, t->right ); else if( t->left != NULL && t->right != NULL ) // two children t->element = findMin( t->right )->element; remove( t->element, t->right ); } else // zero or one child BinaryNode *oldNode = t; t = ( t->left != NULL ) ? t->left : t->right; delete oldNode; Constraint: delete a node, maintain BST property 1. Deleting a leaf. Easy. Just do it. BST property is not affected. 2. Deleting a non-leaf node v a. v has no left child -- replace v by its right child b. v has no right child -- replace v by its left child c. v has both left and right children, either: 1. Replace data in v by data of predecessor and delete predecessor 2. Replace data in v by data in successor and delete successor Note that private remove method takes a reference to a pointer to a node. This allows the pointer to be changed to point to another node. If this were not a reference to a pointer, the pointer would be passed by value and could not be changed inside the method ie the last else clause t = (t->left != NULL) ? T->left : t->right; would change to t inside the method, but not cause any change after the method returns. Asymptotic performance of remove is similar to that for find. It’s O(n) worst case and O(lg n) best/average case. Remove traverses tree from root to some leaf.

Implementation of makeEmpty template <typename Comparable> void BinarySearchTree<Comparable>:: makeEmpty( ) // public makeEmpty ( ) { makeEmpty( root ); // calls private makeEmpty ( ) } makeEmpty( BinaryNode<Comparable> *& t ) const if ( t != NULL ) { // post order traversal makeEmpty ( t->left ); makeEmpty ( t->right ); delete t; t = NULL; Must hang onto each node until its children are deleted Postorder traversal is used in makeEmpty Asymptotic performance = O(n) Traversals of theentire tree (pre, post, in, level) require that each node be visited. Since n nodes are visited, operation is O(n) 2/21/2006

Implementation of Assignment Operator // operator= makes a deep copy via cloning const BinarySearchTree & operator=( const BinarySearchTree & rhs ) { if( this != &rhs ) makeEmpty( ); // free LHS nodes first root = clone( rhs.root ); // make a copy of rhs } return *this; //Internal method to clone subtree -- note the recursion BinaryNode * clone( BinaryNode *t ) const if( t == NULL ) return NULL; return new BinaryNode(t->element, clone(t->left), clone(t->right); 2/21/2006

Performance of BST methods What is the asymptotic performance of each of the BST methods? Best Case Worst Case Average Case contains insert remove findMin/Max makeEmpty assignment 2/21/2006

Building a BST Given an array/vector of elements, what is the performance (best/worst/average) of building a BST from scratch? 2/21/2006

Tree Iterators As we know there are several ways to traverse through a BST. For the user to do so, we must supply different kind of iterators. The iterator type defines how the elements are traversed. InOrderIterator<T> *InOrderBegin( ); PerOrderIterator<T> *PreOrderBegin( ); PostOrderIterator<T> *PostOrderBegin ( ); LevelOrderIterator<T> *LevelOrderBegin( ); Approach 1: Easy to code using existing list iterators. But: O(n) storage for the list (can do better) Difficult to free list storage when iterator is deleted (memory leak) 2/21/2006

Using Tree Iterator main ( ) { BST<int> tree; // store some ints into the tree BST<int>::InOrderIterator<int> itr = tree.InOrderBegin( ); while ( itr != tree.InOrderEnd( ) ) int x = *itr; // do something with x ++itr; } 12/19/2006 – add ++itr; 12/19/2006

BST begin( ) and end( ) // BST InOrderBegin( ) to create an InOrderIterator template <typename T> InOrderIterator<T> BST<T>::InOrderBegin( ) { return InOrderIterator( m_root ); } // BST InOrderEnd( ) to signal “end” of the tree return InOrderIterator( NULL ); 10/4/2006

Iterator Class with a List The InOrderIterator is a disguised List Iterator // An InOrderIterator that uses a list to store // the complete in-order traversal template < typename T > class InOrderIterator { public: InOrderIterator( ); InOrderIterator operator++ ( ); T operator* ( ) const; bool operator != (const InOrderIterator& rhs) const; private: InOrderIterator( BinaryNode<T> * root); typename List<T>::iterator m_listIter; List<T> m_theList; }; 10/4/2006

// InOrderIterator constructor // if root == NULL, an empty list is created template <typename T> InOrderIterator<T>::InOrderIterator( BinaryNode<T> * root ) { FillListInorder( m_theList, root ); m_listIter = m_theList.begin( ); } // constructor helper function void FillListInorder(List<T>& list, BinaryNode<T> *node) if (node == NULL) return; FillListInorder( list, node->left ); list.push_back( node->data ); FillListInorder( list, node->right ); 10/4/2006

List-based InOrderIterator Operators Call List Iterator operators template <typename T> T InOrderIterator<T>::operator++ ( ) { ++m_listIter; } T InOrderIterator<T>::operator* ( ) const return *m_listIter; bool InOrderIterator<T>:: operator!= (const InorderIterator& rhs ) const return m_ListIter != rhs.m_listIter; 10/8/2006

InOrderIterator Class with a Stack // An InOrderIterator that uses a stack to mimic recursive traversal // InOrderEnd( ) creates a stack containing only a NULL point // InOrderBegin( ) pushes a NULL onto the stack so that iterators // can be compared template < typename T > class InOrderIterator { public: InOrderIterator( ); InOrderIterator operator++ ( ); T operator* ( ) const; bool operator== (const InOrderIterator& rhs) const; private: InOrderIterator( BinaryNode<T>* root ); Stack<BinaryNode<T> *> m_theStack; }; 10/8/2006

Stack-Based InOrderIterator Constructor template< typename T > // default constructor InOrderIterator<T>::InOrderIterator ( ) { m_theStack.Push(NULL); } // if t is null, an empty stack is created template <typename T> InOrderIterator<T>::InOrderIterator( BinaryNode<T> *t ) // push a NULL as "end" of traversal m_theStack.Push( NULL ); BinaryNode *v = t; // root while (v != NULL) { m_theStack.Push(v); // push root v = v->left; // and all left descendants Example: 50 30 80 20 40 70 90 O(h) stoarage (=O(lg n) in best and avg cases) Easy to free stack (destroyed when iterator is destroyed) More difficult to code Similar code for re-order and post-order

Stack-Based InOrderIterator Operators template <typename T> InOrderIterator<T> InOrderIterator<T>::operator++( ) { if (m_theStack.IsEmpty( ) || m_theStack.Top() == NULL) throw StackException( ); BinaryNode *v = (m_theStack.Top( ))->right; m_theStack.Pop(); while ( v != NULL ) m_theStack.Push( v ); // push right child v = v->left; // and all left descendants } return *this; 10/8/2006

// operator* -- return data from node on top of stack template< typename T > T InOrderIterator<T>::operator*( ) const { if (m_theStack.IsEmpty( )) throw StackException(); return (m_theStack.Top())->element; } // operator == template< typename T> bool InOrderIterator<T>:: operator== (const InOrderIterator& rhs) const return m_theStack.Top( ) == rhs.m_theStack.Top( ); 10/8/2006

More Recursive Binary (Search) Tree Functions bool isBST ( BinaryNode<T> *t ) returns true if the Binary tree is a BST const T& findMin( BinaryNode<T> *t ) returns the minimum value in a BST int CountFullNodes ( BinaryNode<T> *t ) returns the number of full nodes (those with 2 children) in a binary tree int CountLeaves( BinaryNode<T> *t ) counts the number of leaves in a Binary Tree 2/21/2006