6 Suppose a binary tree. Each node has two pointers to subtrees, like this
12 The tree can be a simple binary search tree, a dynamic binary search tree
13 with auto-balance (described in dbstree.tex), an integer tree (inttree.tex)
14 or any other black-red-whatever tree. To do something for every node of the
15 tree we use a recursive procedure, like below:
17 void do_something (Node *n) {
18 if (n->less) do_something (n->less);
19 /* do something with n ... */
20 if (n->more) do_something (n->more);
23 And the procedure is initiated by calling 'do_something (root_of_the_tree)'.
25 Here is the optimum lwc way of walking a tree with auto functions, compile-time
31 auto void walktree (Node*) = 0;
32 auto void enter (Node*);
35 void foreach_node.enter (Node *n)
44 class foreach_node_IO : foreach_node
46 void walktree (Node*);
49 void foreach_node_IO.walktree (Node *n)
51 if (n->less) walktree (n->less);
53 if (n->more) walktree (n->more);
60 class foreach_node_PO : foreach_node
62 void walktree (Node*);
65 void foreach_node_PO.walktree (Node *n)
67 if (n->less) walktree (n->less);
68 if (n->more) walktree (n->more);
72 Now, suppose we have a tree of strings where the nodes are defined as:
74 class NodeStr : Node {
78 -A] If we want to walk the tree and print all the strings. We only have to
79 define the function 'Do' to print the string of each node. Everything else
80 is already arranged by the auto-functions.
82 class print_tree : foreach_node_IO
86 print_tree (Node *root) { enter (root); }
89 void print_tree.Do (Node *n)
91 NodeStr *s = (NodeStr*) n;
92 printf ("%s\n", s->str);
96 // use it on a tree starting at 'root'
104 -B] If we want to count all the nodes of a tree, we can:
106 class count_nodes : foreach_node_IO
111 count_nodes (Node *root) { cnt = 0; enter (root); }
114 void count_nodes.Do (Node*)
120 // use it on a tree starting at 'root'
124 count_nodes C (root);
125 printf ("tree has %i nodes\n", C.cnt);
128 -C] If we've counted the nodes and we want to store all the strings
129 in an array, sorted, we can:
131 class tree_to_array : foreach_node_IO
136 tree_to_array (char *a[], Node *root) { array = a; enter (root); }
139 void tree_to_array.Do (Node *n)
141 NodeStr *s = (NodeStr*) n;
146 // use it on a tree starting at 'root'
150 count_nodes C (root);
152 tree_to_array A (array, root);
155 NOTES: The member functions of the foreach_node class can be 'modular' in
156 some cases. In case (A), Do() does not use 'this'. Making functions modular
157 will avoid passing the extra argument in walktree() which can't be inlined