Use backtick code blocks for syntax highlighting
This commit is contained in:
parent
8ed9dea394
commit
f658bfbb40
203 changed files with 26546 additions and 25801 deletions
202
59-04.md
202
59-04.md
|
|
@ -43,38 +43,42 @@ unhesitatingly writes something like the perfectly good code in Listings
|
|||
|
||||
**Listing 59.2 L59\_2.C**
|
||||
|
||||
// Function to inorder walk a tree, using code recursion.
|
||||
// Tested with 32-bit Visual C++ 1.10.
|
||||
#include <stdlib.h>
|
||||
#include "tree.h"
|
||||
extern void Visit(NODE *pNode);
|
||||
void WalkTree(NODE *pNode)
|
||||
{
|
||||
// Make sure the tree isn't empty
|
||||
if (pNode != NULL)
|
||||
{
|
||||
// Traverse the left subtree, if there is one
|
||||
if (pNode->pLeftChild != NULL)
|
||||
{
|
||||
WalkTree(pNode->pLeftChild);
|
||||
}
|
||||
// Visit this node
|
||||
Visit(pNode);
|
||||
// Traverse the right subtree, if there is one
|
||||
if (pNode->pRightChild != NULL)
|
||||
{
|
||||
WalkTree(pNode->pRightChild);
|
||||
}
|
||||
}
|
||||
}
|
||||
```c
|
||||
// Function to inorder walk a tree, using code recursion.
|
||||
// Tested with 32-bit Visual C++ 1.10.
|
||||
#include <stdlib.h>
|
||||
#include "tree.h"
|
||||
extern void Visit(NODE *pNode);
|
||||
void WalkTree(NODE *pNode)
|
||||
{
|
||||
// Make sure the tree isn't empty
|
||||
if (pNode != NULL)
|
||||
{
|
||||
// Traverse the left subtree, if there is one
|
||||
if (pNode->pLeftChild != NULL)
|
||||
{
|
||||
WalkTree(pNode->pLeftChild);
|
||||
}
|
||||
// Visit this node
|
||||
Visit(pNode);
|
||||
// Traverse the right subtree, if there is one
|
||||
if (pNode->pRightChild != NULL)
|
||||
{
|
||||
WalkTree(pNode->pRightChild);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Listing 59.3 L59\_3.H**
|
||||
|
||||
// Header file TREE.H for tree-walking code.
|
||||
typedef struct _NODE {
|
||||
struct _NODE *pLeftChild;
|
||||
struct _NODE *pRightChild;
|
||||
} NODE;
|
||||
```c
|
||||
// Header file TREE.H for tree-walking code.
|
||||
typedef struct _NODE {
|
||||
struct _NODE *pLeftChild;
|
||||
struct _NODE *pRightChild;
|
||||
} NODE;
|
||||
```
|
||||
|
||||
Then I ask if they have any idea how to make the code faster; some
|
||||
don't, but most point out that function calls are pretty expensive.
|
||||
|
|
@ -113,72 +117,74 @@ Listing 59.4, working with the code-recursive version as a model.
|
|||
|
||||
**Listing 59.4 L59\_4.C**
|
||||
|
||||
// Function to inorder walk a tree, using data recursion.
|
||||
// No stack overflow testing is performed.
|
||||
// Tested with 32-bit Visual C++ 1.10.
|
||||
#include <stdlib.h>
|
||||
#include "tree.h"
|
||||
#define MAX_PUSHED_NODES 100
|
||||
extern void Visit(NODE *pNode);
|
||||
void WalkTree(NODE *pNode)
|
||||
{
|
||||
NODE *NodeStack[MAX_PUSHED_NODES];
|
||||
NODE **pNodeStack;
|
||||
// Make sure the tree isn't empty
|
||||
if (pNode != NULL)
|
||||
{
|
||||
NodeStack[0] = NULL; // push "stack empty" value
|
||||
pNodeStack = NodeStack + 1;
|
||||
for (;;)
|
||||
{
|
||||
// If the current node has a left child, push
|
||||
// the current node and descend to the left
|
||||
// child to start traversing the left subtree.
|
||||
// Keep doing this until we come to a node
|
||||
// with no left child; that's the next node to
|
||||
// visit in inorder sequence
|
||||
while (pNode->pLeftChild != NULL)
|
||||
{
|
||||
*pNodeStack++ = pNode;
|
||||
pNode = pNode->pLeftChild;
|
||||
}
|
||||
// We're at a node that has no left child, so
|
||||
// visit the node, then visit the right
|
||||
// subtree if there is one, or the last-
|
||||
// pushed node otherwise; repeat for each
|
||||
// popped node until one with a right
|
||||
// subtree is found or we run out of pushed
|
||||
// nodes (note that the left subtrees of
|
||||
// pushed nodes have already been visited, so
|
||||
// they're equivalent at this point to nodes
|
||||
// with no left children)
|
||||
for (;;)
|
||||
{
|
||||
Visit(pNode);
|
||||
// If the node has a right child, make
|
||||
// the child the current node and start
|
||||
// traversing that subtree; otherwise, pop
|
||||
// back up the tree, visiting nodes we
|
||||
// passed on the way down, until we find a
|
||||
// node with a right subtree to traverse
|
||||
// or run out of pushed nodes and are done
|
||||
if (pNode->pRightChild != NULL)
|
||||
{
|
||||
// Current node has a right child;
|
||||
// traverse the right subtree
|
||||
pNode = pNode->pRightChild;
|
||||
break;
|
||||
}
|
||||
// Pop the next node from the stack so
|
||||
// we can visit it and see if it has a
|
||||
// right subtree to be traversed
|
||||
if ((pNode = *—pNodeStack) == NULL)
|
||||
{
|
||||
// Stack is empty and the current node
|
||||
// has no right child; we're done
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```c
|
||||
// Function to inorder walk a tree, using data recursion.
|
||||
// No stack overflow testing is performed.
|
||||
// Tested with 32-bit Visual C++ 1.10.
|
||||
#include <stdlib.h>
|
||||
#include "tree.h"
|
||||
#define MAX_PUSHED_NODES 100
|
||||
extern void Visit(NODE *pNode);
|
||||
void WalkTree(NODE *pNode)
|
||||
{
|
||||
NODE *NodeStack[MAX_PUSHED_NODES];
|
||||
NODE **pNodeStack;
|
||||
// Make sure the tree isn't empty
|
||||
if (pNode != NULL)
|
||||
{
|
||||
NodeStack[0] = NULL; // push "stack empty" value
|
||||
pNodeStack = NodeStack + 1;
|
||||
for (;;)
|
||||
{
|
||||
// If the current node has a left child, push
|
||||
// the current node and descend to the left
|
||||
// child to start traversing the left subtree.
|
||||
// Keep doing this until we come to a node
|
||||
// with no left child; that's the next node to
|
||||
// visit in inorder sequence
|
||||
while (pNode->pLeftChild != NULL)
|
||||
{
|
||||
*pNodeStack++ = pNode;
|
||||
pNode = pNode->pLeftChild;
|
||||
}
|
||||
// We're at a node that has no left child, so
|
||||
// visit the node, then visit the right
|
||||
// subtree if there is one, or the last-
|
||||
// pushed node otherwise; repeat for each
|
||||
// popped node until one with a right
|
||||
// subtree is found or we run out of pushed
|
||||
// nodes (note that the left subtrees of
|
||||
// pushed nodes have already been visited, so
|
||||
// they're equivalent at this point to nodes
|
||||
// with no left children)
|
||||
for (;;)
|
||||
{
|
||||
Visit(pNode);
|
||||
// If the node has a right child, make
|
||||
// the child the current node and start
|
||||
// traversing that subtree; otherwise, pop
|
||||
// back up the tree, visiting nodes we
|
||||
// passed on the way down, until we find a
|
||||
// node with a right subtree to traverse
|
||||
// or run out of pushed nodes and are done
|
||||
if (pNode->pRightChild != NULL)
|
||||
{
|
||||
// Current node has a right child;
|
||||
// traverse the right subtree
|
||||
pNode = pNode->pRightChild;
|
||||
break;
|
||||
}
|
||||
// Pop the next node from the stack so
|
||||
// we can visit it and see if it has a
|
||||
// right subtree to be traversed
|
||||
if ((pNode = *—pNodeStack) == NULL)
|
||||
{
|
||||
// Stack is empty and the current node
|
||||
// has no right child; we're done
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
|
|||
Loading…
Reference in a new issue