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 structure such that –it can be searched more efficiently –it can be used in new ways We begin with a review of search algorithms
Linear Search Collection of data items to be searched is organized in a list x 1, x 2, … x n –Assume = = and < operators defined for the type Linear search begins with item 1 –continue through the list until target found –or reach end of list
Linear Search Vector based search function template void LinearSearch (const vector &v, const t &item, boolean &found, int &loc) { found = false; loc = 0; for ( ; ; ) { if (found || loc == v.size()) return; if (item == x[loc]) found = true; else loc++; } }
Linear Search Singly-linked list based search function template void LinearSearch (NodePointer first, const t &item, boolean &found, int &loc) { found = false; locptr = first; for ( ; ; ) { if (found || locptr ==) return; if (item == locptr->data) found = true; else loc++; } } In both cases, the worst case computing time is still O(n)
Binary Search Binary search function for vector template void LinearSearch (const vector &v, const t &item, boolean &found, int &loc) { found = false; int first = 0; last – v.size() - 1; for ( ; ; ) { if (found || first > last) return; loc = (first + last) / 2; if (item v[loc]) first = loc + 1; else /* item == v[loc] */ found = true; } }
Binary Search Usually outperforms a linear search Disadvantage: –Requires a sequential storage –Not appropriate for linked lists (Why?) It is possible to use a linked structure which can be searched in a binary-like manner
Binary Search Tree Consider the following ordered list of integers 1.Examine middle element 2.Examine left, right sublist (maintain pointers) 3.(Recursively) examine left, right sublists
Binary Search Tree Redraw the previous structure so that it has a treelike shape – a binary tree
Trees A data structure which consists of –a finite set of elements called nodes or vertices –a finite set of directed arcs which connect the nodes If the tree is nonempty –one of the nodes (the root) has no incoming arc –every other node can be reached by following a unique sequence of consecutive arcs
Trees Root node Children of the parent (66) Siblings to each other Leaf nodes
Binary Trees Each node has at most two children Useful in modeling processes where –a comparison or experiment has exactly two possible outcomes –the test is performed repeatedly Example –multiple coin tosses –encoding/decoding messages in dots and dashes such as Mores code
Array Representation of Binary Trees Store the i th node in the i th location of the array Works OK for complete trees, not for sparse trees U T P O E M C
Linked Representation of Binary Trees Uses space more efficiently Provides additional flexibility Each node has two links –one to the left child of the node –one to the right child of the node –if no child node exists for a node, the link is set to NULL data leftright left child right child
ADT Binary Search Tree (BST) Collection of Data Elements –binary tree –each node x, value in left child of x value in x in right child of x Basic operations –Construct an empty BST –Determine if BST is empty –Search BST for given item
ADT Binary Search Tree (BST) Basic operations (ctd) –Insert a new item in the BST Maintain the BST property –Delete an item from the BST Maintain the BST property –Traverse the BST Visit each node exactly once The inorder traversal must visit the values in the nodes in ascending order
BST Class Template template class BST { private: /* Node structure */ class BinNode { public: t data; BinNode *left, *right; BinNode() { left = right = 0; } BinNode (t item) { data = item; left = right = 0; } }; // end of class BinNode // ctd ->
BST Class Template... typedef BinNode *BinNodePointer; public: // for BST BST(); // construct an empty BST bool Empty() const; private: BinNodePointer root; }; // end of class template declaration
BST Class Template Definition of constructor template BST ::BST() { root = 0; } Definition of Empty() template bool BST ::Empty() { return root == 0; }
Searching a BST template bool BST ::Search(const t &item) const { BinNodePointer locptr = root; bool found = false; for ( ; ; ) { if found || locptr == 0) break; if (item data) locptr = locptr->left;// descend left else if (item > locptr->data) locptr = locptr->right;// descend right else found = true; } return found; } Reached a leaf node without finding a match
Inserting an Item into a BST template void BST ::Insert (const t &item) { BinNodePointer locptr = root; parent =0; bool found = false; for ( ; ; ) { if found || locptr == 0) break; if (item data) locptr = locptr->left;// descend left else if (item > locptr->data) locptr = locptr->right;// descend right else found = true; } if (found) cerr << "Item already in the tree\n";...
Inserting an Item into a BST else { locptr = new BinNode (item); // construct node containing item if (parent == 0) // empty tree root = locptr; else if (item data) // insert left of parent parent->left = locptr else // insert right of parent parent->right = locptr; } // end of the else } end of the Insert
Problem of Lopsidedness Tree can be balanced –each node except leaves has exactly 2 child nodes Trees can be unbalanced –not all nodes have exactly 2 child nodes Trees can be totally lopsided –each node has a right child only –degenerates into a linked list
Problem of Lopsidedness Balanced tree search has O(log 2 n) –best case Tree degenerated into linked list has search O(n) –worst case Other unbalanced trees somewhere in between In general –Not possible to predict how to insert to create balanced tree –May require rebalancing algorithm
Binary Trees as Recursive Data Structures A binary tree is either empty … or Consists of –a node called the root –root has pointers to two disjoint binary (sub)trees called … right (sub)tree left (sub)tree Anchor Inductive step Which is either empty … or …
Tree Traversal is Recursive If the binary tree is empty then do nothing Else L: Traverse the left subtree N: Visit the root R: Traverse the right subtree The "anchor" The inductive step
Traversal Order Three possibilities for inductive step … Left subtree, Node, Right subtree the inorder traversal Node, Left subtree, Right subtree the preorder traversal Left subtree, Right subtree, Node the postorder traversal
Traversal Order Given expression A – B * C + D Represent each operand as –the child of a parent node –representing the corresponding operator +-DA*BC
Traversal Order Inorder traversal produces infix expression A – B * C + D Preorder traversal produces the prefix expression + - A * B C D Postorder traversal produces the postfix or RPN expression A B C * - D +
Traversing a Binary Tree template void BST ::Inorder(ostream &out) { InorderAux (out, root); } template void BST ::InorderAux (ostream& out, BinNodePointer ptr) { if (ptr != 0) { InorderAux (opt, ptr->left); out data right); } Two functions needed: We can send a message to a BST object … but … Cannot send a message to its root, required by recursion Inorder sends message to the root Two functions needed: We can send a message to a BST object … but … Cannot send a message to its root, required by recursion Inorder sends message to the root Change order of these three statements for different traversals Change order of these three statements for different traversals
Recursive Searching template bool BST ::Search (const t &item) { SearchAux (root, item); } template void BST ::SearchAux (BinNodePointer locptr, const t &item) { if (locptr == 0) return false; // empty tree if (item data) SearchAux(locptr->left, item); else if (item > locptr->data) SearchAux (locptr->right, item); else return true; } Author suggests iterative approach is easier, just as efficient iterative approach Author suggests iterative approach is easier, just as efficient iterative approach
Recursive Insertion template bool BST ::Insert (const t &item) { InsertAux (root, item); } template (typename t> void BST ::InsertAux (BinNodePointer locptr, const t &item) { if (locptr == 0) root = new BSTNode (item); else if (item data) InsertAux (locptr->left, item); else if (item > locptr->data) InsertAux (locptr->right, item); else cerr << "Item already in tree\n"; }
Recursive Deletion Three possible cases to delete a node, x, from a BST The node, x, is a leaf x has one child x has two children Note the source code for the deletion function, pgs