- Summary
- We consider the basic approaches to visiting or processing all of the nodes in a tree.
- Prerequisites
- Trees.

Just as we iterate the elements of a list, so may we want to traverse all of the elements in a tree. Sometimes, we traverse a tree just to print it out. Sometimes we traverse a tree to look for a particular value. Sometimes we traverse a tree to compute a value based on the tree.

What values might we compute from a tree? We might simply compute the size of the tree, or the depth of the tree, or the number of times a value appears in the tree. If the tree is not in any particular order, we might also search a tree for a value that meets particular criteria.

At first glance, traversing trees seems straightforward: You simply visit each node in the tree, processing the node as you go. But behind the obvious “process each node” strategy, there are a wide variety of options.

Most nodes have more than one child. Do you process the children
in order from *left to right*, *right to left*, or leave the order
unspecified? The client of your traversal algorithm will want to
know (and may even want to choose).

When we think recursively, we think about processing all of one
subtree before processing the next subtree. That means we traverse
down to a leaf in one subtree before we look at even the topmost
node in the other subtree. However, there are times that it makes
sense to process all of the nodes at one level before going on to
the next level. An algorithm that goes across each level, one at
a time, is called a *breadth-first* algorithm. A traversal algorithm
that goes deep into one subtree before processing the next subtree
is called a *depth-first* algorithm. Once again, a client may want
to know which approach you will use or choose which approach you
will use.

We usually have to *visit* a node before we visit its children -
after all, in many implementations we get the information on the
children from the node. However, we can choose different orders
in which to *process* nodes. Two general approaches are *preorder*,
in which we process a node before processing its children and
*postorder*, in which we process a node after processing its children.
Preorder processing is also called *top-down* and postorder processing
is also called *bottom-up*. For binary trees with a depth-first
approach, it is also possible to support *inorder* processing -
process the left subtree, process the node, then process the right
subtree.

So, when we write algorithms that process trees, we have three decisions to make:

- Do we visit subtrees left-to-right or right-to-left?
- Do we visit nodes breadth-first or depth-first?
- Do we visit notes in preorder, postorder, or (if appropriate), inorder?

That gives about ten different traversals. Why ten and not twelve? Because inorder breadth-first traversal doesn’t make a lot of sense, given that subtrees are on different levels.

Do these different approaches visit nodes in different orders? Certainly. Let’s look at a simple binary search tree.

```
e
/ \
c h
/ \ / \
a d f j
```

Before you read on, make a note to yourself how you’d visit the tree in each of the orders given above.

Ready? Fill in the following table.

Policy | Order Elements are Processed |
---|---|

Depth first, Preorder, Left to right | |

Depth first, Preorder, Right to left | |

Depth first, Postorder, Left to right | |

Depth first, Postorder, Right to left | |

Depth first, Inorder, Left to right | |

Depth first, Inorder, Right to left | |

Breadth first, Preorder, Left to right | |

Breadth first, Preorder, Right to left | |

Breadth first, Postorder, Left to right | |

Breadth first, Postorder, Right to left |

Are you done? Here’s what we get.

Policy | Order Elements are Processed |
---|---|

Depth first, Preorder, Left to right | e c a d h f j |

Depth first, Preorder, Right to left | e h j f c d a |

Depth first, Postorder, Left to right | a d c f j h e |

Depth first, Postorder, Right to left | j f h d a c e |

Depth first, Inorder, Left to right | a c d e f h j |

Depth first, Inorder, Right to left | j h f e d c a |

Breadth first, Preorder, Left to right | e c h a d f j |

Breadth first, Preorder, Right to left | e h c j f d a |

Breadth first, Postorder, Left to right | a d f j c h e |

Breadth first, Postorder, Right to left | j f d a h c e |

Wasn’t that fun? Surprisingly, there are use cases for each of the traversal orders.

We indicated that there are some times that it’s useful to use
trees to compute a value. Here’s one of the most common: Computer
scientists often use trees to represent arithmetic expressions.
For example, consider the following might represent the expression
`(3+4)*(-(5+6))`

.

```
*
/ \
/ \
+ -
/ \ |
/ \ |
3 4 +
/ \
/ \
5 6
```

To evaluate this tree, we need to evaluate both subtrees and then
combine them using the operation. So we evaluate the `3+4`

subtree and the `-(5+6)`

and multiply them together. Arithmetic
evaluation normally requires depth-first, postorder evaluation.