// Simple binary tree class that includes methods to construct a tree of ints, // to print the structure, and to print the data using a preorder, inorder or // postorder traversal. The trees built have nodes numbered starting with 1 // and numbered sequentially level by level with no gaps in the tree. The // documentation refers to these as "sequential trees." public class IntTree { // TreeSet --> sorted, pretty fast, not as fast as HashSet // don't need to know that TreeSet is a binary tree. private IntTreeNode overallRoot; // pre : max >= 0 (throws IllegalArgumentException if not) // post: constructs a sequential tree with given number of nodes public IntTree(int max) { if (max < 0) { throw new IllegalArgumentException("max: " + max); } overallRoot = buildTree(1, max); } // post: returns a sequential tree with n as its root unless n is greater // than max, in which case it returns an empty tree private IntTreeNode buildTree(int n, int max) { if (n > max) { return null; } else { IntTreeNode left = buildTree(2 * n, max); IntTreeNode right = buildTree(2 * n + 1, max); return new IntTreeNode(n, left, right); } } // post: prints the tree contents using a preorder traversal public void printPreorder() { printPreorder(overallRoot); } private void printPreorder(IntTreeNode root) { if (root != null) { // recursive case System.out.println(root.data); // root.left AND root.right ARE binary trees // process left printPreorder(root.left); // process right printPreorder(root.right); } // base case; do nothing } // post: prints the tree contents using an inorder traversal public void printInorder() { printInorder(overallRoot); System.out.println(); } private void printInorder(IntTreeNode root) { // notice how similar all traversals look // however, when the root is processed says a lot if (root != null) { printInorder(root.left); System.out.print(root.data + ", "); printInorder(root.right); } // base case; do nothing } // post: prints the tree contents using a postorder traversal public void printPostorder() { printPostorder(overallRoot); System.out.println(); } private void printPostorder(IntTreeNode root) { if (root != null) { printPostorder(root.left); printPostorder(root.right); System.out.print(root.data + ", "); } // base case; do nothing } // post: prints the tree contents, one per line, following an inorder // traversal and using indentation to indicate node depth; prints // right to left so that it looks correct when the output is rotated. public void printSideways() { printSideways(overallRoot, 0); } // post: prints in reversed preorder the tree with given root, indenting // each line to the given level private void printSideways(IntTreeNode root, int level) { if (root != null) { printSideways(root.right, level + 1); for (int i = 0; i < level; i++) { System.out.print(" "); } System.out.println(root.data); printSideways(root.left, level + 1); } } private class IntTreeNode { public int data; public IntTreeNode left; public IntTreeNode right; public IntTreeNode(int data) { this.data = data; } // binary tree -> root node, with a left and right binary tree. public IntTreeNode(int data, IntTreeNode left, IntTreeNode right) { this.data = data; this.left = left; this.right = right; } } }