|
|
- import java.util.Stack;
- import java.util.List;
-
-
- public class BinarySearchTree<E extends Comparable<E>> {
- class Node {
- E value;
- Node leftChild = null;
- Node rightChild = null;
- Node(E value) {
- this.value = value;
- }
- @Override
- public boolean equals(Object obj) {
- if ((obj instanceof BinarySearchTree.Node) == false)
- return false;
- @SuppressWarnings("unchecked")
- Node other = (BinarySearchTree<E>.Node)obj;
- return other.value.compareTo(value) == 0 &&
- other.leftChild == leftChild && other.rightChild == rightChild;
- }
- }
-
- protected Node root = null;
-
- protected void visit(Node n) {
- System.out.println(n.value);
- }
-
- public boolean contains(E val) {
- return contains(root, val);
- }
-
- protected boolean contains(Node n, E val) {
- if (n == null) return false;
-
- if (n.value.equals(val)) {
- return true;
- } else if (n.value.compareTo(val) > 0) {
- return contains(n.leftChild, val);
- } else {
- return contains(n.rightChild, val);
- }
- }
-
- public boolean add(E val) {
- if (root == null) {
- root = new Node(val);
- return true;
- }
- return add(root, val);
- }
-
- protected boolean add(Node n, E val) {
- if (n == null) {
- return false;
- }
- int cmp = val.compareTo(n.value);
- if (cmp == 0) {
- return false; // this ensures that the same value does not appear more than once
- } else if (cmp < 0) {
- if (n.leftChild == null) {
- n.leftChild = new Node(val);
- return true;
- } else {
- return add(n.leftChild, val);
- }
- } else {
- if (n.rightChild == null) {
- n.rightChild = new Node(val);
- return true;
- } else {
- return add(n.rightChild, val);
- }
- }
- }
-
- public boolean remove(E val) {
- return remove(root, null, val);
- }
-
- protected boolean remove(Node n, Node parent, E val) {
- if (n == null) return false;
-
- if (val.compareTo(n.value) == -1) {
- return remove(n.leftChild, n, val);
- } else if (val.compareTo(n.value) == 1) {
- return remove(n.rightChild, n, val);
- } else {
- if (n.leftChild != null && n.rightChild != null){
- n.value = maxValue(n.leftChild);
- remove(n.leftChild, n, n.value);
- } else if (parent == null) {
- root = n.leftChild != null ? n.leftChild : n.rightChild;
- } else if (parent.leftChild == n){
- parent.leftChild = n.leftChild != null ? n.leftChild : n.rightChild;
- } else {
- parent.rightChild = n.leftChild != null ? n.leftChild : n.rightChild;
- }
- return true;
- }
- }
-
- protected E maxValue(Node n) {
- if (n.rightChild == null) {
- return n.value;
- } else {
- return maxValue(n.rightChild);
- }
- }
-
-
- /*********************************************
- *
- * IMPLEMENT THE METHODS BELOW!
- *
- *********************************************/
-
-
- // Method #1.
- public Node findNode(E val) {
- Node node = this.root;
- if(val == null) return null;
- while(!node.value.equals(val)){
- if(node.value.compareTo(val) > 0) node = node.leftChild;
- else node = node.rightChild;
- if(node == null) return null;
- }
- return node;
-
- }
-
- // Method #2.
- protected int depth(E val) { // Basically the same method as findNode
- int depth = 0;
- Node node = this.root;
- if(val == null) return -1;
- while(!node.value.equals(val)){
- if(node.value.compareTo(val) > 0) node = node.leftChild;
- else node = node.rightChild;
- if(node == null) return -1;
- depth++;
- }
- return depth;
- }
-
- // Method #3.
- protected int height(E val) {
- int leftHeight, rightHeight;
- Node node = this.findNode(val);
- if(val == null) return -1;
- if(node == null) return -1;
-
- if(node.leftChild == null && node.rightChild == null) return 0;
-
- leftHeight = node.leftChild == null ? 0 : this.height(node.leftChild.value);
- rightHeight = node.rightChild == null ? 0 : this.height(node.rightChild.value);
- return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;
- }
-
- // Method #4.
- protected boolean isBalanced(Node n) {
-
- if(n == null) return false;
- if(this.findNode(n.value) == null) return false;
-
- int diff = Math.abs(this.height(n.leftChild == null ? null : n.leftChild.value) - this.height(n.rightChild == null ? null : n.rightChild.value));
- return diff == 0 || diff == 1;
- }
-
- // Method #5. .
- public boolean isBalanced() {
- Stack<Node> explored = new Stack<Node>();
-
- explored.push(this.root);
- Node node;
- while(!explored.isEmpty()){
- node = explored.pop();
- if(!this.isBalanced(node)) return false;
- if(node.leftChild != null){
- explored.push(node.leftChild);
- }
- if(node.rightChild != null){
- explored.push(node.rightChild);
- }
- }
- return true;
- }
-
- }
|