Adds BST delete
This commit is contained in:
parent
9173f20491
commit
12edd9e409
@ -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());
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user