Title: Searching: Binary Trees
1Searching Binary Trees
2Review of Linear Search
- Collection of data items to be searched is
organized in a list x1, x2, xn - Assume and lt operators defined for the type
- Linear search begins with item 1
- continue through the list until target found
- or reach end of list
3Linear Search
- Vector based search function
- template lttypename tgt
- void LinearSearch (const vectorlttgt v,
const t item, boolean found, int
loc) -
- found false loc 0 for ( )
- if (found loc v.size()) return if
(item vloc) found true else loc -
4Linear Search
- Singly-linked list based search function
- template lttypename tgt
- void LinearSearch (NodePointer first, const
t item, bool found, int loc) - NodePointer locptrfirst forloc0 !found
locptr!NULL - locptrlocptr-gtnext) if (item
locptr-gtdata) found true - else loc
-
5Linear Search
Iterator-based linear search
- template lttypename tgt
- void LinearSearch (const vectorlttgt v , const t
item, bool found, int loc) - found false loc 0
- for (vectorlttgtiterator itv.begin() !found
it ! v.end() it) -
- if (it item) found true
- else loc
-
6Binary Search
7Binary Search
- Two requirements
- The data items are in ascending order (can they
be in decreasing order?? ?) - Direct access of each data item for efficiency
(why linked-list is not good!)
8Binary Search
- Binary search function for vector
- template lttypename tgt
- void LinearSearch (const vectorlttgt v,
const t item, bool found, int
loc) - found false loc 0
- int first 0 last v.size() - 1 for (
) - if (found first gt last) return loc
(first last) / 2 if (item lt vloc)
last loc - 1 else if (item gt vloc)
first loc 1 else found true // item
found -
9Binary Search vs. Linear Search
- Usually outperforms Linear search O(logn) vs.
O(n) - Disadvantages
- Sorted list of data items
- Direct access of storage structure, not good for
linked-list - Good news It is possible to use a linked
structure which can be searched in a binary-like
manner
10Binary Search Tree
- Consider the following ordered list of integers
- Examine middle element
- Examine left, right sublist (maintain pointers)
- (Recursively) examine left, right sublists
11Binary Search Tree
- Redraw the previous structure so that it has a
treelike shape a binary tree
12Trees
- 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 (or paths)
13Trees
14Binary 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
15Array Representation of Binary Trees
- Store the ith node in the ith location of the
array
16Array Representation of Binary Trees
- Works OK for complete trees, not for sparse trees
17Some Tree Definition, p656
- Complete trees
- Each level is completely filled except the bottom
level - The leftmost positions are filled at the bottom
level - Array storage is perfect for them
- Balanced trees
- Binary trees
- left_subtree right_subtreelt1
- Tree Height/Depth of levels
18Tree Question?
- A complete tree must be a balanced tree?
- Give a node with position i in a complete tree,
what are the positions of its child nodes?
19Linked 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
20Linked Representation of Binary Trees
21Binary 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
Which is either empty or
Which is either empty or
22Tree Traversal is Recursive
- If the binary tree is empty thendo nothing
- Else N Visit the root, process dataL Traverse
the left subtreeR Traverse the right subtree
If the binary tree is empty thendo nothing Else
N Visit the root, process dataL Traverse the
left subtreeR Traverse the right subtree
23Traversal Order
- Three possibilities for inductive step
- Left subtree, Node, Right subtreethe inorder
traversal - Node, Left subtree, Right subtreethe preorder
traversal - Left subtree, Right subtree, Nodethe postorder
traversal
24ADT Binary Search Tree (BST)
- Collection of Data Elements
- binary tree
- BST property for each node x,
- value in left child of x lt value in x lt in
right child of x - Basic operations
- Construct an empty BST
- Determine if BST is empty
- Search BST for given item
25ADT 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
26BST
- template lttypename Tgt
- class BST public BST() myRoot(0)
bool empty() return myRootNULL private
class BinNode public T
data BinNode left, right
BinNode() left(0), right(0)
BinNode(T item) data(item), left(0), right(0)
//end of BinNode typedef BinNode
BinNodePtr - BinNodePtr myRoot
-
27BST operations
- Inorder, preorder and postorder traverasl
(recursive) - Non-recursive traversal
28BST Traversals, p.670
- Why do we need two functions?
- Public void inorder(ostream out)
- Private inorderAux()
- Do the actual job
- To the left subtree and then right subtree
- Can we just use one function?
- Probably NO
29Non-recursive traversals
- Lets try non-recusive inorder
- Any idea to implement non-recursive traversals?
What ADT can be used as an aid tool?
30Non-recursive traversals
- Basic idea
- Use LIFO data structure stack
- include ltstackgt (provided by STL)
- Chapter 9, google stack in C for more details,
members and functions - Useful in your advanced programming
31Non-recursive inorder
- Lets see how it works given a tree
- Step by step
32Non-recursive inorder
- 1. Set current node pointer ptr myRoot
- 2. Push current node pointer ptr and all the
leftmost nodes on its subtree into a stack until
meeting a NULL pointer - 3. Check if the stack is empty or not. If yes,
goto 5, otherwise goto 4 - 4. Take the top element in stack and assign it to
ptr, print our ptr-gtdata, pop the top element,
and set ptr ptr-gtright (visit right subtree),
goto 2 - 5. Done
33Non-recursive inorder
- template lttypename DataTypegt
- void non_recur_inorder(ostream out)
- if (!myRoot) return // empty BST
- BinNodePointer ptr myRoot
- stackltBSTltDataTypegtBinNodePointergt s //
empty stack - for ( )
- while (ptr) s.push(ptr) ptr
ptr-gtleft // leftmost nodes - if (s.empty()) break // done
- ptr s.top() s.pop()
- out ltlt ptr-gtdata ltlt
- ptr ptr-gtright // right substree
-
-
34Non-recursive traversals
- Can you do it yourself?
- Preorder?
- Postorder?
35BST Searches
- Search begins at root
- If that is desired item, done
- If item is less, move downleft subtree
- If item searched for is greater, move down right
subtree - If item is not found, we will run into an empty
subtree
36BST Searches
- Write recursive search
- Write Non-recursive search algorithm
- bool search(const T item) const
37Insertion Operation
- Basic idea
- Use search operation to locate the insertion
position or already existing item - Use a parent point pointing to the parent of the
node currently being examined as descending the
tree
38Insertion Operation
- Non-recursive insertion
- Recursive insertion
- Go through insertion illustration p.677
- Initially parent NULL, locptr root
- Location termination at NULL pointer or
encountering the item - Parent-gtleft/right item
39Recursive Insertion
- See p. 681
- Thinking!
- Why using at subtreeroot
40Deletion Operation
- Three possible cases to delete a node, x, from a
BST - 1. The node, x, is a leaf
41Deletion Operation
- 2. The node, x has one child
42Deletion Operation
View remove() function
43Question?
- Why do we choose inorder predecessor/successor to
replace the node to be deleted in case 3?
44Implement Delete Operation
- void delete(const T item) //remove the specified
item if it exists - Assume you have this function
- template lttypename Tgt
- void BSTltTgtsearch2(const T item, bool
found, BSTltTgtBinNodePtr locptr,
BSTltTgtBinNodePtr parent) const - locptr myRoot parent NULL
found false - while(!found locptr)
- if (item lt locptr-gtdata)
- parent locptr
locptr locptr-gtleft - else if (item gt locptr-gtdata)
- parent locptr
locptr loc-gtright - else
- found true
- //end while
-
45Implement Delete Operation
- Search the specified item on the tree. If not
found, then return otherwise go to 2. - Check if the node to be deleted has two child
nodes (case 3). If so, find the inorder
successor/predecessor, replace the data, and then
make the successor/predecessor node the one to be
deleted - In order to delete the node, you should keep
track of its parent node in step 1 and 2. - Delete the node according to the first two simple
cases. Be careful with parent - Release the memory of the node deleted
46delete(const T item)
- BinNodePtr parent, x
- bool found
- search2(item, found, x, parent) //search
item on the tree - if (!found) return
- if (x-gtleft x-gtright) //the case 3 with
two child nodes - BinNodePtr xsucc x-gtright
- parent x
- while (xsucc-gtleft) //find inorder
successor - parent xsucc xsucc
xsucc-gtleft - x-gtdata xsucc-gtdata
- x xsucc
- //end if
- BinNodePtr subtree x-gtleft
- if (!subtree) subtree x-gtright
- if (!parent)
- myRoot subtree
- else
- if (x parent-gtleft)
- parent-gtleft subtree
47BST Class Template
- View complete binary search tree template, Fig.
12.7 - View test program for BST, Fig. 12.8
- No such functions
- Copy constructor, assignment operator
- So we can NOT do what?
48In-class Exercises 1
- Write a recursive member function height() for
the BST class template to return the height of
the BST - int height()
- // See how concise your implementation could be?
49In-class Exercises 2
- Write a recursive member function leafCount() for
the BST class template to return the number of
leaf nodes of the BST - int leafCount()
- // See how concise your implementation could be?
50Questions?
- What is T(n) of search algorithm in a BST? Why?
- What is T(n) of insert algorithm in a BST?
- Other operations?
51Problem of Lopsidedness
- The order in which items are inserted into a BST
determines the shape of the BST - Result in Balanced or Unbalanced trees
- Insert O, E, T, C, U, M, P
- Insert C, O, M, P, U, T, E
52Balanced
53Unbalanced
54Problem of Lopsidedness
- Trees can be totally lopsided
- Suppose each node has a right child only
- Degenerates into a linked list
Processing time affected by "shape" of tree