import java.util.LinkedList; import java.util.NoSuchElementException; import java.util.Queue; public class BST { private IntTreeNode root; private int size; /** * This function returns true if this is a BST containing value and false * otherwise. * pre: this is a BST post: this is an unchanged BST */ public boolean contains(int value) { return contains(this.root, value); } /** * This function returns true if the BST current contains value and false * otherwise. pre: current is a BST post: current is an unchanged BST */ private boolean contains(IntTreeNode current, int value) { assert this.isBST() : "contains only works on BSTs"; if (current == null) { return false; } else if (current.data == value) { return true; } else if (current.data < value) { return contains(current.right, value); } else { return contains(current.left, value); } } /** This function prints the in-order traversal of this tree. */ public void print() { print(this.root); System.out.println(); } /** * This function prints the in-order traversal of the tree rooted at current */ private void print(IntTreeNode current) { if (current != null) { print(current.left); System.out.print(current.data + " "); print(current.right); } } /** This function returns the height of this tree */ public int height() { return height(this.root); } /** This function returns the height of the tree rooted at current */ private int height(IntTreeNode current) { if (current == null) { return 0; } else { return 1 + Math.max(height(current.left), height(current.right)); } } /** * This function returns true if this is a BST and false otherwise. */ public boolean isBST() { return isBST(this.root, null, null); } /** * This function returns true if the tree rooted at current is a BST that * only contains values between min and max. */ private boolean isBST(IntTreeNode current, Integer min, Integer max) { if (current == null) { return true; } else { if ((min != null && min > current.data) || (max != null && max < current.data)) { return false; } return isBST(current.left, min, current.data) && isBST(current.right, current.data, max); } } /** * This function adds value to this tree. pre: this is a BST post: this is a * BST with all the nodes it started with plus a node containing value */ public void add(int value) { assert this.isBST() : "add only works on BSTs"; this.root = add(this.root, value); assert this.isBST() : "add should result in a BST"; } /** * This function adds value to the tree rooted at current. pre: current is a * BST post: current is a BST with all the nodes it started with plus a node * containing value */ private IntTreeNode add(IntTreeNode current, int value) { if (current == null) { this.size++; current = new IntTreeNode(value); } else if (current.data < value) { current.right = add(current.right, value); } else if (current.data > value) { current.left = add(current.left, value); } return current; } public int size() { return this.size; } public boolean isEmpty() { return this.size == 0; } public int first() { return -1; } private int first(IntTreeNode current) { return -1; } public void removeLeaves() { this.root = removeLeaves(this.root); } private IntTreeNode removeLeaves(IntTreeNode current) { if (current != null) { if (current.left == null && current.right == null) { current = null; } else { current.left = removeLeaves(current.left); current.right = removeLeaves(current.right); } } return current; } public void remove(int value) { } private IntTreeNode remove(IntTreeNode current, int value) { return current; } /** This function returns a string made up of n spaces */ private String getSpaces(int n) { String result = ""; for (int i = 0; i < n; i++) { result += " "; } return result; } /** This function prints an ASCII art picture of this tree */ public void printTree() { Queue q = new LinkedList(); q.add(this.root); printTree(q, height()); } /** * This function prints an ASCII art picture of the tree made up of nodes in * q. */ private void printTree(Queue q, int height) { int size = q.size(); String tree = ""; String branches = ""; boolean hasNonNull = false; /* For each node we haven't explored... */ for (int i = 0; i < size; i++) { /* Explore the next node. */ IntTreeNode current = q.remove(); /* Figure out how many spaces should go before and after it */ String before = getSpaces((int) Math.pow(2, height - 1) - 1); String after = getSpaces((int) Math.pow(2, height - 1)); /* * Construct the next part of the line of the actual tree (e.g. the * values in the tree) */ tree += before; if (current != null) { hasNonNull = true; tree += current.data; q.add(current.left); q.add(current.right); } else { tree += " "; q.add(null); q.add(null); } tree += after; /* * Construct the diagonal lines connecting the different rows of the * tree. */ if (before.length() > 0) { branches += before.substring(1); if (current != null && current.left != null) { branches += "/ "; } else { branches += " "; } if (current != null && current.right != null) { branches += "\\"; } else { branches += " "; } } if (after.length() > 0) { branches += after.substring(1); } } /* Print the row we constructed above. */ if (tree.length() > 0) { System.out.println(tree); } if (branches.length() > 0) { System.out.println(branches); } /* * If there are more nodes to explore (and they aren't all null, explore * the rest of the tree recursively. */ if (!q.isEmpty() && hasNonNull) { printTree(q, height - 1); } } }