Back
to Weiss and general binary trees.
Last time we looked at the mysterious merge operation of BinaryTree (pp 580-581), that devours its arguments to make a bigger tree.
For example, for x a BinaryTree, and a, b, also BinaryTrees, x.merge(label, a, b) replaces any old x contents with a new tree made up of a new root node with payload “label”, and a as its left subtree and b as its right subtree. Trees a and b become empty.
This is a “side effect”, a change to the state of the system other than an expected change (just like with medicines). When we see x.method(a, b), we expect that x may change, but not a and b, even if a and b are of the same type as x. However, the code in a method has the ability to change private fields of any object of its class, and sometimes does. Got to be on your toes.
This means that the BinaryTrees fed to merge as arguments are just “scratch” trees being used to help build bigger trees.
Note that we won’t need merge() for pa6, since we will be building trees with SAXParser.
18.3 Recursion and Trees
Trees are recursive data structures and thus recursion is a natural way to work with them. To do an action on a tree, define a method for it, and implement it by calling the method recursively on the left and right children—they define trees as well. Be sure to handle the base case, no children.
Look at duplicate(), pg. 583, size(), pg. 584, height(), pg. 585.
Traversals
There are three standard traversals of trees: preorder, inorder, and postorder. Preorder is the most basic and important and is used for order of nodes in an XML tree.
Preorder
visit a node
visit the left subtree of the node
visit the right subtree of the node
InOrder
visit the left subtree of the node
visit the node
visit the right subtree of the node
PostOrder
visit the left subtree of the node
visit the right subtree of the node
visit the node
We tried this out on a tree with A as root, B, C, and D as A’s children, E and F as B’s children, and G as D’s child.
The preorder order is: A, B, E, F, C, D, G
The inorder order is E B F A C G D
The postorder order is E F B C G D A
It’s easy to implement traversals recursively, printing out the elements as you go—see printPreOrder, etc., pg. 586.
It’s a little harder to set up an iterator that let’s us do scan through the nodes and do anything we want with them individually. More on this next time.
18.4: Iterators for tree traversals--skipping, but get the idea of it
The idea is that with a tree iterator, it’s just as easy to scan through a tree as scan through a list. For example, we could easily write a program that counted all the “A” labels in a tree by iterating through it. Of course this would be pretty easy by a recursion through the tree too.
Implementing a tree iterator is tricky. We can’t use recursion for this because we can’t return from a couple of function calls down when we find the next node.
Weiss’s iterator for preorder traversal (class PreOrder) does work, although using a different algorithm than I expected.
Chap. 19 Binary Search Trees --> pa06
BST Order property, pg. 630