// Erika Wolfe, CSE 143 // This class represents a binary search tree of integers // A binary search tree is one that every value to the left of a value is less // than it, and every value to the right is greater than it. Duplicates are not allowed. public class IntSearchTree { private IntTreeNode overallRoot; // Constructs an empty tree public IntSearchTree() { overallRoot = null; } // Returns true if the value is in this tree, false otherwise public boolean contains(int value) { return contains(overallRoot, value); } // Returns true if the given value is contained in the tree // rooted at the given root, false otherwise private boolean contains(IntTreeNode root, int value) { if (root == null) { return false; } else if (root.data == value) { return true; } else if (value < root.data) { return contains(root.left, value); } else { // value > root.data return contains(root.right, value); } } // pre: This is a binary search tree // post: Adds the value to the tree such that // it maintains the binary search tree property public void add(int value) { overallRoot = add(overallRoot, value); } // pre: the subtree rooted at `root` is a binary search tree // post: adds the given value to the subtree rooted at // `root` such that it preserves the binary search tree // property private IntTreeNode add(IntTreeNode root, int value) { // remember to use x = change(x) pattern! // rewatch the lecture on panopto for full explanation if (root == null) { root = new IntTreeNode(value); } else if (value < root.data) { root.left = add(root.left, value); } else if (value > root.data) { root.right = add(root.right, value); } return root; } /* This version of add tries to look ahead instead of using the x = change(x) pattern like above private void add(IntTreeNode root, int value) { // this doesn't work if overallRoot is null, // need to add a special case in the public method too :'( if (root.left == null && root.right == null) { if (value < root.data) { root.left = new IntTreeNode(value); } else if (value > root.data) { root.right = new IntTreeNode(value); } } else if (value < root.data) { if (root.left == null) { root.left = new IntTreeNode(value); } else { add(root.left, value); } } else if (value > root.data) { if (root.right == null) { root.right = new IntTreeNode(value); } else { add(root.right, value); } } } */ // post: prints the tree contents using a preorder traversal public void printPreorder() { System.out.print("preorder:"); printPreorder(overallRoot); System.out.println(); } // post: prints in preorder the tree with given root private void printPreorder(IntTreeNode root) { if (root != null) { System.out.print(" " + root.data); printPreorder(root.left); printPreorder(root.right); } } // post: prints the tree contents using an inorder traversal public void printInorder() { System.out.print("inorder:"); printInorder(overallRoot); System.out.println(); } // post: prints in inorder the tree with given root private void printInorder(IntTreeNode root) { if (root != null) { printInorder(root.left); System.out.print(" " + root.data); printInorder(root.right); } } // post: prints the tree contents using a postorder traversal public void printPostorder() { System.out.print("postorder:"); printPostorder(overallRoot); System.out.println(); } // post: prints in postorder the tree with given root private void printPostorder(IntTreeNode root) { if (root != null) { printPostorder(root.left); printPostorder(root.right); System.out.print(" " + root.data); } } // Returns the number of numbers in this tree. public int size() { return size(overallRoot); } // Returns the number of nodes in the tree starting at root. private int size(IntTreeNode root) { if (root == null) { return 0; } else { int leftSize = size(root.left); int rightSize = size(root.right); return 1 + leftSize + rightSize; } } }