11.07.2015 Views

Data Structures and Algorithm Analysis - Computer Science at ...

Data Structures and Algorithm Analysis - Computer Science at ...

Data Structures and Algorithm Analysis - Computer Science at ...

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

152 Chap. 5 Binary Treestends to be error prone. While preorder2 insures th<strong>at</strong> no recursive calls willbe made on empty subtrees, it will fail if the initial call passes in a null pointer.This would occur if the original tree is empty. To avoid the bug, either preorder2needs an additional test for a null pointer <strong>at</strong> the beginning (making the subsequenttests redundant after all), or the caller of preorder2 has a hidden oblig<strong>at</strong>ion topass in a non-empty tree, which is unreliable design. The net result is th<strong>at</strong> manyprogrammers forget to test for the possibility th<strong>at</strong> the empty tree is being traversed.By using the first design, which explicitly supports processing of empty subtrees,the problem is avoided.Another issue to consider when designing a traversal is how to define the visitorfunction th<strong>at</strong> is to be executed on every node. One approach is simply to write anew version of the traversal for each such visitor function as needed. The disadvantageto this is th<strong>at</strong> wh<strong>at</strong>ever function does the traversal must have access to theBinNode class. It is probably better design to permit only the tree class to haveaccess to the BinNode class.Another approach is for the tree class to supply a generic traversal functionwhich takes the visitor as a function parameter. This is known as the visitor designp<strong>at</strong>tern. A major constraint on this approach is th<strong>at</strong> the sign<strong>at</strong>ure for all visitorfunctions, th<strong>at</strong> is, their return type <strong>and</strong> parameters, must be fixed in advance. Thus,the designer of the generic traversal function must be able to adequ<strong>at</strong>ely judge wh<strong>at</strong>parameters <strong>and</strong> return type will likely be needed by potential visitor functions.H<strong>and</strong>ling inform<strong>at</strong>ion flow between parts of a program can be a significantdesign challenge, especially when dealing with recursive functions such as treetraversals. In general, we can run into trouble either with passing in the correctinform<strong>at</strong>ion needed by the function to do its work, or with returning inform<strong>at</strong>ionto the recursive function’s caller. We will see many examples throughout the bookth<strong>at</strong> illustr<strong>at</strong>e methods for passing inform<strong>at</strong>ion in <strong>and</strong> out of recursive functions asthey traverse a tree structure. Here are a few simple examples.First we consider the simple case where a comput<strong>at</strong>ion requires th<strong>at</strong> we communic<strong>at</strong>einform<strong>at</strong>ion back up the tree to the end user.Example 5.4 We wish to count the number of nodes in a binary tree. Thekey insight is th<strong>at</strong> the total count for any (non-empty) subtree is one for theroot plus the counts for the left <strong>and</strong> right subtrees. Where do left <strong>and</strong> rightsubtree counts come from? Calls to function count on the subtrees willcompute this for us. Thus, we can implement count as follows.int count(BinNode rt) {if (rt == null) return 0; // Nothing to countreturn 1 + count(rt.left()) + count(rt.right());}

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!