Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
1 CS 122 – Lab 14 – April 17, 2012 – Tree Traversals The purpose of today’s lab is to look at a simple implementation of a binary tree, and make iterators that enable us to traverse the tree. The files you need for lab are contained in the on-line directory lab14 located on the class Web site. In the directory you will find several Java files: Tree.java – implementation of (binary) tree Node.java – specifies what each node of a tree contains (data plus pointers) Item.java – same as in our linked list example, basically holds a string Driver.java – main function You will be making modifications to Tree.java. If you run the program now, you’ll notice that it will print an expression using a preorder traversal. This is because the toString method in the Tree class automatically uses a preorderIterator object. Look at how the PreorderIterator class was implemented. It has a similar structure to other iterators we’ve written in class. What’s distinctive about this iterator is that it is recursive – it makes use of an addNext() method that calls itself on each of its children. The base case of the recursion occurs when the node is null. How can we tell that the PreorderIterator really performs a preorder traversal? _______________ ______________________________________________________________________________ We need to add 2 more iterators – one for an inorder traversal, and another for a postorder traversal. These 2 iterators are similar to the existing one for the preorder traversal. So similar, in fact, that it would be a good idea to employ some inheritance. Implement the following inner classes and methods… I have inserted comments in Tree.java to guide you. Step 1: Write a GeneralIterator class which contains declarations for the 2 attributes (the ArrayList and its index), as well as the 3 methods required by the Iterator interface. Hint – you can copy this stuff from the existing PreorderIterator class. Step 2: Change the declaration of PreorderIterator to say that it extends GeneralIterator. Take out the attributes and functions that you incorporated into GeneralIterator. What you’ll notice is that inheritance will make your code less repetitive. For example, the PreorderIterator constructor just needs two statements: a call to the parent constructor, and a call to addNext() to begin the recursion. And addNext() is the only other method that needs to be implemented in the inner class. Step 3: Create analogous inner classes for InorderIterator and PostorderIterator – these classes will be similar to PreorderIterator except for how they handle addNext(). Step 4: Finally, we need functions that will call the appropriate inner class constructors so that we can create iterator objects. preorderIterator(Node start) – this method is given. inorderIterator(Node start), and postorderIterator(Node start) – write these analogous functions. Also implement 3 more methods: preorderIterator() – this method is given. inorderIterator() postorderIterator() 2 that take no parameter. The intent here is that if the user doesn’t specify where to start, then we begin at the root. Modify the main() function in Driver.java so that we can see the output of these 3 traversals. Your output should look like the following: Preorder: + - 1 2 * 3 4 Inorder: 1 - 2 + 3 * 4 Postorder: 1 2 – 3 4 * + * * * * * * * * * * * * * * * * * * * * * * * * Finally, let’s make our Tree implementation a little more flexible. Up until now we have been using the Tree to model a mathematical expression. And in this case, every interior node has exactly two children. But in general, a binary tree could allow for a node to have just one child, either a left child or a right child. In other words, one of the two children could be null. If you compile and run Driver2.java, you will see a problem at the point where we try to add Q. The current implementation of Tree.java does not handle the case of inserting a subtree with just one child. This will be the last thing you need to modify today. Based on the logic given in Driver2.java, draw what you think the tree should “look like” when the program is finished. Also, for practice, write down its preorder, inorder and postorder traversals. Now, modify the 2nd Tree constructor in Tree.java, so that it can handle these situations: The left subtree could be null. The right subtree could be null. In these cases, we need to set the appropriate root’s child to null, and make sure that some of the existing statements are avoided. When you are done fixing the Tree constructor, run Driver2 again. Verify that the 3 traversals of the tree are correct.