import java.util.*; public class BinaryTree { private TreeNode myRoot; public BinaryTree ( ) { myRoot = null; } public BinaryTree (TreeNode t) { myRoot = t; } /** Print the values in the tree in preorder: root value first, * then values in the left subtree (in preorder), then values * in the right subtree (in preorder). */ public void printPreorder ( ) { printPreorder (myRoot); System.out.println ( ); } // We'll discuss the peculiar syntax below in a future lecture. The // type parameter Item must be passed in as a "parameter" to each // static method, and this is how you do that. private static void printPreorder (TreeNode t) { if (t != null) { System.out.print (t.myItem + " "); printPreorder (t.left); printPreorder (t.right); } } /** Print the values in the tree in inorder: values in the left * subtree first (in inorder), then the root value, then values * in the right subtree (in inorder). */ public void printInorder ( ) { printInorder (myRoot); System.out.println ( ); } private static void printInorder (TreeNode t) { if (t != null) { printInorder (t.left); System.out.print (t.myItem + " "); printInorder (t.right); } } public static BinaryTree sampleTree1 ( ) { return new BinaryTree (new TreeNode ("a", new TreeNode ("b"), new TreeNode ("c"))); } public static BinaryTree sampleTree2 ( ) { return new BinaryTree (new TreeNode ("a", new TreeNode ("b", new TreeNode ("d", new TreeNode ("e"), new TreeNode ("f")), null), new TreeNode ("c"))); } public static void main (String [ ] args) { print (new BinaryTree ( ), "the empty tree"); print (sampleTree1 ( ), "sample tree 1"); print (sampleTree2 ( ), "sample tree 2"); } private static void print (BinaryTree t, String description) { System.out.println (description + " in preorder"); t.printPreorder ( ); System.out.println (description + " in inorder"); t.printInorder ( ); System.out.println ( ); } static class TreeNode { public Item myItem; public TreeNode left; public TreeNode right; public TreeNode (Item obj) { myItem = obj; left = right = null; } public TreeNode (Item obj, TreeNode left, TreeNode right) { myItem = obj; this.left = left; this.right = right; } } /** Iterates through all my TreeNodes in (depth-first) preorder. */ // See lab section 8.3.1. public class DepthFirstIterator implements Iterator> { private Stack> fringe = new Stack> ( ); public DepthFirstIterator ( ) { // Java fact. Since DepthFirstIterator is an inner class of // BinaryTree, and has no "myRoot" member itself, // "myRoot" here is shorthand for "BinaryTree.this.myRoot". if (myRoot != null) { fringe.push (myRoot); } } public boolean hasNext ( ) { return !fringe.empty ( ); } public TreeNode next ( ) { if (!hasNext ( )) { throw new NoSuchElementException ("tree ran out of elements"); } TreeNode node = fringe.pop ( ); if (node.right != null) { fringe.push (node.right); } if (node.left != null) { fringe.push (node.left); } return node; } public void remove () { throw new UnsupportedOperationException (); } } }