This repository acts as a personal archive for my solutions to EdX course *Data Structures and Software Design* from PennX.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

190 lines
5.0 KiB

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;
}
}