// CSE 143, Autumn 2013 // An IntTree object represents an entire binary tree of ints. public class BinarySearchTree { private IntTreeNode overallRoot; // Constructs an empty binary tree public BinarySearchTree() { overallRoot = null; } // Constructs a binary tree with the given node as its root. public BinarySearchTree(IntTreeNode overallRoot) { this.overallRoot = overallRoot; } // Prints all elements of this tree in left to right order. public void print() { print(overallRoot); } // Prints a portion of the overall tree private void print(IntTreeNode root) { // implicit base case: if null, do nothing if(root != null) { print(root.left); // print my left sub-tree System.out.print(root.data + " "); // print myself print(root.right); // print my right sub-tree } } // Returns true if the overall tree contains the given target value, // false otherwise public boolean contains(int target) { return contains(overallRoot, target); } // Returns true if a portion of the overall tree contains the given // target value, false otherwise. private boolean contains(IntTreeNode root, int target) { if(root == null) { return false; } else if(root.data == target) { return true; } else if (root.data > target) { return contains(root.left, target); } else { return contains(root.right, target); } } // Adds the value to the tree such that sorted BST order is maintained public void add(int value) { overallRoot = add(overallRoot, value); } // Adds the value to the given subtree. Does not add duplicates. // A node's initial state is passed in and it modified // state is returned. This is the x = change(x) pattern and // it allows attaching new nodes to the tree. private IntTreeNode add(IntTreeNode root, int value) { if(root == null) { root = new IntTreeNode(value); } else if (root.data > value) { root.left = add(root.left, value); } else if (root.data < value) { root.right = add(root.right, value); } return root; } }