Deduped images

This commit is contained in:
James Gregory 2013-12-30 12:25:34 +11:00
commit 9e52de9586
233 changed files with 128 additions and 128 deletions

View file

@ -40,7 +40,7 @@
</P>
<P>Let&#146;s look at it another way. All the code in Listing 59.2 does is say: &#147;Here I am at a node. First I&#146;ll visit the left subtree if there is one, then I&#146;ll visit this node, then I&#146;ll visit the right subtree if there is one. While I&#146;m visiting the left subtree, I&#146;ll just push a marker on a stack that tells me to come back here when the left subtree is done. If, after visiting a node, there are no right children to visit and nothing left on the stack, I&#146;m finished. The code does this at each node&#151;and that&#146;s <I>all</I> it does. That&#146;s all Listing 59.4 does, too, but people tend to get tangled up in pushes and pops and <B>while</B> loops when they use data recursion. When the implementation model changes to one with which they are unfamiliar, they abandon the perfectly good model they used before and try to rederive it in the new context by the seat of their pants.</P>
<TABLE WIDTH="100%"><TR>
<TD VALIGN="TOP" ALIGN="LEFT" WIDTH="5%"><IMG SRC="images/59-02i.jpg"><TD VALIGN="TOP" ALIGN="LEFT" WIDTH="95%"><SMALL><I>Here&#146;s a secret when you&#146;re faced with a situation like this: Step back and get a clear picture of what your code has to do. Omit no steps. You should build a model that is so consistent and solid that you can instantly answer any question about how the code should behave in any situation. For example, my interviewees often decide, by trial and error, that there are two distinct types of right children: Right children visited after popping back to visit a node after the left subtree has been visited, and right children visited after descending to a node that has no left child. This makes the traversal code a mass of special cases, each of which has to be detected by the programmer by trying out scenarios. Worse, you can never be sure with this approach that you&#146;ve caught all the special cases.</I></SMALL>
<TD VALIGN="TOP" ALIGN="LEFT" WIDTH="5%"><IMG SRC="images/i.jpg"><TD VALIGN="TOP" ALIGN="LEFT" WIDTH="95%"><SMALL><I>Here&#146;s a secret when you&#146;re faced with a situation like this: Step back and get a clear picture of what your code has to do. Omit no steps. You should build a model that is so consistent and solid that you can instantly answer any question about how the code should behave in any situation. For example, my interviewees often decide, by trial and error, that there are two distinct types of right children: Right children visited after popping back to visit a node after the left subtree has been visited, and right children visited after descending to a node that has no left child. This makes the traversal code a mass of special cases, each of which has to be detected by the programmer by trying out scenarios. Worse, you can never be sure with this approach that you&#146;ve caught all the special cases.</I></SMALL>
<TR>
<TD>
<TD><SMALL><I>The alternative is to develop and apply a unifying model. There aren&#146;t really two types of right children; the rule is that all right children are visited after their parents are visited, period. The presence or absence of a left child is irrelevant. The possibility that a right child may be reached via different code paths depending on the presence of a left child does not affect the overall model. While this distinction may seem trivial it is in fact crucial, because if you have the model down cold, you can always tell if the implementation is correct by comparing it with the model.</I></SMALL>