Adds BST delete

master
Abhinav Sarkar 2019-06-29 18:52:15 +05:30
parent 9173f20491
commit 12edd9e409
1 changed files with 184 additions and 22 deletions

View File

@ -4,7 +4,7 @@ import java.util.Optional;
public class BinarySearchTree<K extends Comparable<K>,V>
{
private Node<K,V> root = (Node<K,V>) EmptyNode.INSTANCE;
private Node<K,V> root = EmptyNode.instance();
public void insert(K key, V val) {
this.root = this.root.insert(key, val);
@ -14,23 +14,31 @@ public class BinarySearchTree<K extends Comparable<K>,V>
return this.root.get(key);
}
public void delete(K key) {
this.root.delete(key);
}
public String toString() {
return this.root.toStringBuilder(0).toString();
}
public interface Node<K extends Comparable<K>, V>
private interface Node<K extends Comparable<K>, V>
{
Node<K,V> insert(K key, V val);
Optional<V> get(K key);
Node<K,V> delete(K key);
boolean isEmpty();
ValueNode<K,V> toValueNode();
StringBuilder toStringBuilder(int level);
boolean checkIfBST();
}
private static class ValueNode<K extends Comparable<K>,V> implements Node<K, V>
{
private K key;
private V val;
private Node<K,V> left = (Node<K,V>) EmptyNode.INSTANCE;
private Node<K,V> right = (Node<K,V>) EmptyNode.INSTANCE;
private Node<K,V> left = EmptyNode.instance();
private Node<K,V> right = EmptyNode.instance();
ValueNode(K key, V val) {
if (key == null) {
@ -44,10 +52,22 @@ public class BinarySearchTree<K extends Comparable<K>,V>
this.val = val;
}
@Override
public boolean isEmpty()
{
return false;
}
@Override
public ValueNode<K, V> toValueNode()
{
return this;
}
@Override
public Node<K, V> insert(K key, V val)
{
if (this.key == key) {
if (this.key.equals(key)) {
this.val = val;
} else if (this.key.compareTo(key) > 0) {
this.left = this.left.insert(key, val);
@ -60,7 +80,7 @@ public class BinarySearchTree<K extends Comparable<K>,V>
@Override
public Optional<V> get(K key)
{
if (this.key == key) {
if (this.key.equals(key)) {
return Optional.of(val);
} else if (this.key.compareTo(key) > 0) {
return this.left.get(key);
@ -69,62 +89,204 @@ public class BinarySearchTree<K extends Comparable<K>,V>
}
}
@Override
public Node<K,V> delete(K key)
{
if (this.key.equals(key)) {
return doDelete();
} else if (this.key.compareTo(key) > 0) {
this.left = this.left.delete(key);
} else {
this.right = this.right.delete(key);
}
return this;
}
private Node<K, V> doDelete()
{
if (this.left.isEmpty())
{
return this.right.isEmpty() ? EmptyNode.instance() : this.right;
}
else if (this.right.isEmpty())
{
return this.left;
}
else
{
ValueNode<K, V> node = deleteSuccessor();
this.key = node.key;
this.val = node.val;
return this;
}
}
private ValueNode<K, V> deleteSuccessor()
{
Node<K,V> current = this.right;
ValueNode<K,V> successor = this.right.toValueNode();
ValueNode<K,V> successorParent = this.right.toValueNode();
do
{
ValueNode<K, V> cur = current.toValueNode();
Node<K, V> curLeft = cur.left;
if (!curLeft.isEmpty()) {
successor = curLeft.toValueNode();
successorParent = cur;
}
current = curLeft;
} while (!current.isEmpty());
successorParent.left = EmptyNode.instance();
return successor;
}
@Override
public boolean checkIfBST()
{
return this.left.checkIfBST() && this.right.checkIfBST()
&& isKeyMoreThanLeftKey() && isKeyLessThanRightKey();
}
private boolean isKeyLessThanRightKey()
{
return this.right.isEmpty() || this.key.compareTo(this.right.toValueNode().key) < 0;
}
private boolean isKeyMoreThanLeftKey()
{
return this.left.isEmpty() || this.key.compareTo(this.left.toValueNode().key) > 0;
}
@Override
public StringBuilder toStringBuilder(int level) {
return new StringBuilder()
.append(gutter(level))
.append("<" + key + ':' + val + ">\n")
return new StringBuilder().append(gutter(level))
.append('<')
.append(key)
.append(':')
.append(val)
.append(">\n")
.append(this.left.toStringBuilder(level + 1))
.append(this.right.toStringBuilder(level + 1));
}
private static StringBuilder gutter(int times) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < times; i++)
{
sb.append(' ');
}
return sb.append("|— ");
@Override
public String toString()
{
return "{" + key + ':' + val + '}';
}
}
private static class EmptyNode<K extends Comparable<K>,V> implements Node<K,V> {
private static class EmptyNode<K extends Comparable<K>,V> implements Node<K,V>
{
@SuppressWarnings("rawtypes")
private static final EmptyNode INSTANCE = new EmptyNode();
public static <K extends Comparable<K>,V> EmptyNode<K,V> instance() {
return INSTANCE;
}
@Override
public Node<K, V> insert(K key, V val)
{
return new ValueNode<>(key, val);
}
@Override
public boolean isEmpty()
{
return true;
}
@Override
public ValueNode<K, V> toValueNode()
{
throw new UnsupportedOperationException();
}
@Override
public Optional<V> get(K key)
{
return Optional.empty();
}
@Override
public Node<K, V> delete(K key) {
return this;
}
@Override
public boolean checkIfBST()
{
return true;
}
@Override
public StringBuilder toStringBuilder(int level)
{
return new StringBuilder(0);
return new StringBuilder().append(gutter(level)).append("<NULL>\n");
}
@Override
public String toString()
{
return "<NULL>";
}
}
private static StringBuilder gutter(int times) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < times; i++)
{
sb.append('│');
}
return sb.append("├ ");
}
public static void main(String[] args)
{
BinarySearchTree<String, String> bst = new BinarySearchTree<>();
bst.insert("b", "barista");
bst.insert("a", "abhinav");
bst.insert("q", "barista");
bst.insert("y", "duck");
bst.insert("k", "carpool");
bst.insert("p", "duck");
bst.insert("c", "carpool");
bst.insert("d", "carl");
bst.insert("e", "barista");
bst.insert("d", "duck");
bst.insert("f", "abhinav");
bst.insert("j", "abhinav");
bst.insert("t", "duck");
bst.insert("s", "carpool");
bst.insert("g", "carpool");
bst.insert("v", "abhinav");
bst.insert("h", "duck");
bst.insert("r", "abhinav");
bst.insert("n", "abhinav");
bst.insert("w", "carpool");
bst.insert("u", "barista");
bst.insert("z", "duck");
bst.insert("b", "barista");
bst.insert("o", "carpool");
bst.insert("a", "abhinav");
bst.insert("l", "duck");
bst.insert("m", "barista");
bst.insert("i", "barista");
bst.insert("x", "duck");
System.out.println(bst);
System.out.println(bst.root.checkIfBST());
System.out.println(bst.get("a"));
System.out.println(bst.get("b"));
System.out.println(bst.get("c"));
System.out.println(bst.get("d"));
System.out.println(bst.get("z"));
System.out.println(bst.get("A"));
bst.delete("q");
bst.delete("r");
bst.delete("c");
System.out.println(bst);
System.out.println(bst.root.checkIfBST());
}
}