Extract Map interfaces

master
Abhinav Sarkar 2019-07-05 21:27:31 +05:30
parent 52033d8547
commit b179302265
7 changed files with 150 additions and 147 deletions

View File

@ -6,7 +6,7 @@ import java.util.NoSuchElementException;
import java.util.Optional; import java.util.Optional;
import java.util.Stack; import java.util.Stack;
public class AVLTree<K extends Comparable<K>,V> implements Iterable<AVLTree.Entry<K,V>> public class AVLTree<K extends Comparable<K>,V> implements SortedMap<K, V>
{ {
private Node<K,V> root; private Node<K,V> root;
@ -14,30 +14,37 @@ public class AVLTree<K extends Comparable<K>,V> implements Iterable<AVLTree.Entr
root = EmptyNode.instance(rebalance); root = EmptyNode.instance(rebalance);
} }
public void insert(K key, V val) { @Override
public void put(K key, V val) {
this.root = this.root.insert(key, val); this.root = this.root.insert(key, val);
} }
@Override
public Optional<V> get(K key) { public Optional<V> get(K key) {
return this.root.get(key); return this.root.get(key);
} }
public void delete(K key) { @Override
public void remove(K key) {
this.root = this.root.delete(key); this.root = this.root.delete(key);
} }
@Override
public Optional<K> minimum() { public Optional<K> minimum() {
return this.root.minimum(); return this.root.minimum();
} }
@Override
public Optional<K> maximum() { public Optional<K> maximum() {
return this.root.maximum(); return this.root.maximum();
} }
@Override
public Optional<K> successor(K key) { public Optional<K> successor(K key) {
return this.root.successor(key); return this.root.successor(key);
} }
@Override
public Optional<K> predecessor(K key) { public Optional<K> predecessor(K key) {
return this.root.predecessor(key); return this.root.predecessor(key);
} }
@ -462,30 +469,6 @@ public class AVLTree<K extends Comparable<K>,V> implements Iterable<AVLTree.Entr
return sb.append("├ "); return sb.append("├ ");
} }
public static class Entry<K, V> {
private final K key;
private final V val;
public Entry(K key, V val) {
this.key = key;
this.val = val;
}
public K getKey()
{
return key;
}
public V getVal()
{
return val;
}
public String toString() {
return "<" + key + "," + val + ">";
}
}
private static class InOrderIterator<K extends Comparable<K>, V> implements Iterator<Entry<K, V>> private static class InOrderIterator<K extends Comparable<K>, V> implements Iterator<Entry<K, V>>
{ {
private final Stack<Node<K, V>> stack = new Stack<>(); private final Stack<Node<K, V>> stack = new Stack<>();
@ -542,32 +525,32 @@ public class AVLTree<K extends Comparable<K>,V> implements Iterable<AVLTree.Entr
public static void main(String[] args) throws IOException public static void main(String[] args) throws IOException
{ {
AVLTree<String, String> bst = new AVLTree<>(true); AVLTree<String, String> bst = new AVLTree<>(true);
bst.insert("a", "barista"); bst.put("a", "barista");
bst.insert("b", "duck"); bst.put("b", "duck");
bst.insert("c", "carpool"); bst.put("c", "carpool");
bst.insert("d", "duck"); bst.put("d", "duck");
bst.insert("e", "carpool"); bst.put("e", "carpool");
bst.insert("f", "barista"); bst.put("f", "barista");
bst.insert("g", "duck"); bst.put("g", "duck");
bst.insert("h", "abhinav"); bst.put("h", "abhinav");
bst.insert("i", "abhinav"); bst.put("i", "abhinav");
bst.insert("j", "duck"); bst.put("j", "duck");
bst.insert("k", "carpool"); bst.put("k", "carpool");
bst.insert("l", "carpool"); bst.put("l", "carpool");
bst.insert("m", "abhinav"); bst.put("m", "abhinav");
bst.insert("n", "duck"); bst.put("n", "duck");
bst.insert("o", "abhinav"); bst.put("o", "abhinav");
bst.insert("p", "abhinav"); bst.put("p", "abhinav");
bst.insert("q", "carpool"); bst.put("q", "carpool");
bst.insert("r", "barista"); bst.put("r", "barista");
bst.insert("s", "duck"); bst.put("s", "duck");
bst.insert("t", "barista"); bst.put("t", "barista");
bst.insert("u", "carpool"); bst.put("u", "carpool");
bst.insert("v", "abhinav"); bst.put("v", "abhinav");
bst.insert("w", "duck"); bst.put("w", "duck");
bst.insert("x", "barista"); bst.put("x", "barista");
bst.insert("y", "barista"); bst.put("y", "barista");
bst.insert("z", "duck"); bst.put("z", "duck");
System.out.println(bst); System.out.println(bst);
System.out.println(bst.root.checkIfBST()); System.out.println(bst.root.checkIfBST());
@ -580,16 +563,16 @@ public class AVLTree<K extends Comparable<K>,V> implements Iterable<AVLTree.Entr
System.out.println(bst.get("d")); System.out.println(bst.get("d"));
System.out.println(bst.get("A")); System.out.println(bst.get("A"));
bst.delete("q"); bst.remove("q");
System.out.println(bst.root.checkIfBST()); System.out.println(bst.root.checkIfBST());
System.out.println(bst.root.checkIfAVLT()); System.out.println(bst.root.checkIfAVLT());
bst.delete("r"); bst.remove("r");
System.out.println(bst.root.checkIfBST()); System.out.println(bst.root.checkIfBST());
System.out.println(bst.root.checkIfAVLT()); System.out.println(bst.root.checkIfAVLT());
bst.delete("k"); bst.remove("k");
System.out.println(bst.root.checkIfBST()); System.out.println(bst.root.checkIfBST());
System.out.println(bst.root.checkIfAVLT()); System.out.println(bst.root.checkIfAVLT());
bst.delete("c"); bst.remove("c");
System.out.println(bst.root.checkIfBST()); System.out.println(bst.root.checkIfBST());
System.out.println(bst.root.checkIfAVLT()); System.out.println(bst.root.checkIfAVLT());
System.out.println(bst); System.out.println(bst);
@ -605,7 +588,7 @@ public class AVLTree<K extends Comparable<K>,V> implements Iterable<AVLTree.Entr
System.out.println(bst.predecessor("q")); System.out.println(bst.predecessor("q"));
for (Entry<String,String> entry: bst) { for (Entry<String,String> entry: bst) {
System.out.println(entry.key); System.out.println(entry.getKey());
} }
} }
} }

View File

@ -6,11 +6,11 @@ import java.util.NoSuchElementException;
import java.util.Optional; import java.util.Optional;
import java.util.Stack; import java.util.Stack;
public class BinarySearchTree<K extends Comparable<K>,V> implements Iterable<BinarySearchTree.Entry<K,V>> public class BinarySearchTree<K extends Comparable<K>,V> implements SortedMap<K,V>
{ {
private Node<K,V> root = EmptyNode.instance(); private Node<K,V> root = EmptyNode.instance();
public void insert(K key, V val) { public void put(K key, V val) {
this.root = this.root.insert(key, val); this.root = this.root.insert(key, val);
} }
@ -18,7 +18,7 @@ public class BinarySearchTree<K extends Comparable<K>,V> implements Iterable<Bin
return this.root.get(key); return this.root.get(key);
} }
public void delete(K key) { public void remove(K key) {
this.root = this.root.delete(key); this.root = this.root.delete(key);
} }
@ -350,30 +350,6 @@ public class BinarySearchTree<K extends Comparable<K>,V> implements Iterable<Bin
return sb.append("├ "); return sb.append("├ ");
} }
public static class Entry<K, V> {
private K key;
private V val;
public Entry(K key, V val) {
this.key = key;
this.val = val;
}
public K getKey()
{
return key;
}
public V getVal()
{
return val;
}
public String toString() {
return "<" + key + "," + val + ">";
}
}
private static class InOrderIterator<K extends Comparable<K>, V> implements Iterator<Entry<K, V>> private static class InOrderIterator<K extends Comparable<K>, V> implements Iterator<Entry<K, V>>
{ {
private final Stack<Node<K, V>> stack = new Stack<>(); private final Stack<Node<K, V>> stack = new Stack<>();
@ -481,32 +457,32 @@ public class BinarySearchTree<K extends Comparable<K>,V> implements Iterable<Bin
public static void main(String[] args) throws IOException public static void main(String[] args) throws IOException
{ {
BinarySearchTree<String, String> bst = new BinarySearchTree<>(); BinarySearchTree<String, String> bst = new BinarySearchTree<>();
bst.insert("q", "barista"); bst.put("q", "barista");
bst.insert("y", "duck"); bst.put("y", "duck");
bst.insert("k", "carpool"); bst.put("k", "carpool");
bst.insert("p", "duck"); bst.put("p", "duck");
bst.insert("c", "carpool"); bst.put("c", "carpool");
bst.insert("e", "barista"); bst.put("e", "barista");
bst.insert("d", "duck"); bst.put("d", "duck");
bst.insert("f", "abhinav"); bst.put("f", "abhinav");
bst.insert("j", "abhinav"); bst.put("j", "abhinav");
bst.insert("t", "duck"); bst.put("t", "duck");
bst.insert("s", "carpool"); bst.put("s", "carpool");
bst.insert("g", "carpool"); bst.put("g", "carpool");
bst.insert("v", "abhinav"); bst.put("v", "abhinav");
bst.insert("h", "duck"); bst.put("h", "duck");
bst.insert("r", "abhinav"); bst.put("r", "abhinav");
bst.insert("n", "abhinav"); bst.put("n", "abhinav");
bst.insert("w", "carpool"); bst.put("w", "carpool");
bst.insert("u", "barista"); bst.put("u", "barista");
bst.insert("z", "duck"); bst.put("z", "duck");
bst.insert("b", "barista"); bst.put("b", "barista");
bst.insert("o", "carpool"); bst.put("o", "carpool");
bst.insert("a", "abhinav"); bst.put("a", "abhinav");
bst.insert("l", "duck"); bst.put("l", "duck");
bst.insert("m", "barista"); bst.put("m", "barista");
bst.insert("i", "barista"); bst.put("i", "barista");
bst.insert("x", "duck"); bst.put("x", "duck");
System.out.println(bst); System.out.println(bst);
System.out.println(bst.root.checkIfBST()); System.out.println(bst.root.checkIfBST());
@ -518,9 +494,9 @@ public class BinarySearchTree<K extends Comparable<K>,V> implements Iterable<Bin
System.out.println(bst.get("d")); System.out.println(bst.get("d"));
System.out.println(bst.get("A")); System.out.println(bst.get("A"));
bst.delete("q"); bst.remove("q");
bst.delete("r"); bst.remove("r");
bst.delete("c"); bst.remove("c");
System.out.println(bst); System.out.println(bst);
System.out.println(bst.root.checkIfBST()); System.out.println(bst.root.checkIfBST());
@ -535,7 +511,7 @@ public class BinarySearchTree<K extends Comparable<K>,V> implements Iterable<Bin
System.out.println(bst.predecessor("q")); System.out.println(bst.predecessor("q"));
for (Entry<String,String> entry: bst) { for (Entry<String,String> entry: bst) {
System.out.println(entry.key); System.out.println(entry.getKey());
} }
} }
} }

View File

@ -25,7 +25,7 @@ public class LRWCache<K, V> implements Iterable<K>
public void put(K key, V val) { public void put(K key, V val) {
store.put(key, val); store.put(key, val);
if (store.size() > capacity) { if (store.size() > capacity) {
store.remove(store.iterator().next().key()); store.remove(store.iterator().next().getKey());
} }
} }
@ -38,7 +38,7 @@ public class LRWCache<K, V> implements Iterable<K>
{ {
return new Iterator<K>() return new Iterator<K>()
{ {
private final Iterator<OpenAddressingHashTable.Entry<K,V>> it = store.iterator(); private final Iterator<Map.Entry<K,V>> it = store.iterator();
@Override @Override
public boolean hasNext() public boolean hasNext()
@ -49,7 +49,7 @@ public class LRWCache<K, V> implements Iterable<K>
@Override @Override
public K next() public K next()
{ {
return it.next().key(); return it.next().getKey();
} }
}; };
} }

View File

@ -0,0 +1,36 @@
package net.abhinavsarkar.algorist;
import java.util.Optional;
public interface Map<K, V> extends Iterable<Map.Entry<K, V>>
{
void put(K key, V val);
Optional<V> get(K key);
void remove(K key);
class Entry<K2, V2> {
private final K2 key;
private final V2 val;
public Entry(K2 key, V2 val) {
this.key = key;
this.val = val;
}
public K2 getKey()
{
return key;
}
public V2 getVal()
{
return val;
}
public String toString() {
return "<" + key + "," + val + ">";
}
}
}

View File

@ -4,7 +4,7 @@ import java.util.Iterator;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Optional; import java.util.Optional;
public class OpenAddressingHashTable<K, V> implements Iterable<OpenAddressingHashTable.Entry<K, V>> public class OpenAddressingHashTable<K, V> implements Map<K, V>
{ {
private static final Entry REMOVED = new Entry(0,0); private static final Entry REMOVED = new Entry(0,0);
@ -40,6 +40,7 @@ public class OpenAddressingHashTable<K, V> implements Iterable<OpenAddressingHas
return num == 1 ? 1 : Integer.highestOneBit(num - 1) * 2; return num == 1 ? 1 : Integer.highestOneBit(num - 1) * 2;
} }
@Override
public Optional<V> get(K key) { public Optional<V> get(K key) {
int trial = 0; int trial = 0;
int baseIndex = calcIndex(key, store.length); int baseIndex = calcIndex(key, store.length);
@ -55,19 +56,20 @@ public class OpenAddressingHashTable<K, V> implements Iterable<OpenAddressingHas
else if (entry == REMOVED && firstRemovedIndex == -1) { else if (entry == REMOVED && firstRemovedIndex == -1) {
firstRemovedIndex = index; firstRemovedIndex = index;
} }
else if (entry.key.equals(key)) else if (entry.getKey().equals(key))
{ {
if (firstRemovedIndex != -1) { if (firstRemovedIndex != -1) {
store[firstRemovedIndex] = entry; store[firstRemovedIndex] = entry;
store[index] = REMOVED; store[index] = REMOVED;
} }
return Optional.of(entry.val); return Optional.of(entry.getVal());
} }
trial++; trial++;
} }
return Optional.empty(); return Optional.empty();
} }
@Override
public void put(K key, V val) { public void put(K key, V val) {
if (actualSize >= loadFactor * store.length) { if (actualSize >= loadFactor * store.length) {
resize(); resize();
@ -77,8 +79,9 @@ public class OpenAddressingHashTable<K, V> implements Iterable<OpenAddressingHas
private void resize() { private void resize() {
Object[] nStore = new Object[store.length * 2]; Object[] nStore = new Object[store.length * 2];
for (Entry<K, V> entry : this) for (LinkedHashTableIterator iterator = new LinkedHashTableIterator(); iterator.hasNext();)
{ {
Entry<K, V> entry = iterator.next();
doPut(entry, nStore, true); doPut(entry, nStore, true);
} }
store = nStore; store = nStore;
@ -87,7 +90,7 @@ public class OpenAddressingHashTable<K, V> implements Iterable<OpenAddressingHas
private void doPut(Entry<K,V> nEntry, Object[] store, boolean resize) { private void doPut(Entry<K,V> nEntry, Object[] store, boolean resize) {
int trial = 0; int trial = 0;
int baseIndex = calcIndex(nEntry.key, store.length); int baseIndex = calcIndex(nEntry.getKey(), store.length);
while (trial < store.length) { while (trial < store.length) {
int index = probingStrategy.nextIndex(baseIndex, trial, store.length); int index = probingStrategy.nextIndex(baseIndex, trial, store.length);
Entry<K,V> entry = (Entry<K,V>) store[index]; Entry<K,V> entry = (Entry<K,V>) store[index];
@ -105,12 +108,14 @@ public class OpenAddressingHashTable<K, V> implements Iterable<OpenAddressingHas
store[index] = nEntry; store[index] = nEntry;
return; return;
} }
else if (entry.key.equals(nEntry.key)) else if (entry.getKey().equals(nEntry.getKey()))
{ {
if (!resize) { if (!resize) {
linkUpdatedEntry(entry); linkUpdatedEntry(entry);
} }
entry.val = nEntry.val; nEntry.next = entry.next;
nEntry.prev = entry.prev;
store[index] = nEntry;
return; return;
} }
trial++; trial++;
@ -154,6 +159,7 @@ public class OpenAddressingHashTable<K, V> implements Iterable<OpenAddressingHas
} }
} }
@Override
public void remove(K key) { public void remove(K key) {
int trial = 0; int trial = 0;
int baseIndex = calcIndex(key, store.length); int baseIndex = calcIndex(key, store.length);
@ -165,7 +171,7 @@ public class OpenAddressingHashTable<K, V> implements Iterable<OpenAddressingHas
{ {
return; return;
} }
else if (entry.key.equals(key)) else if (entry.getKey().equals(key))
{ {
unlinkEntry(entry); unlinkEntry(entry);
store[index] = REMOVED; store[index] = REMOVED;
@ -200,14 +206,15 @@ public class OpenAddressingHashTable<K, V> implements Iterable<OpenAddressingHas
return key.hashCode() % size; return key.hashCode() % size;
} }
public Iterator<Entry<K,V>> iterator() { public Iterator<Map.Entry<K,V>> iterator() {
return new LinkedHashTableIterator(); return new LinkedHashTableIterator();
} }
public String toString() { public String toString() {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for (Entry<K,V> entry : this) for (LinkedHashTableIterator iterator = new LinkedHashTableIterator(); iterator.hasNext();)
{ {
Entry<K, V> entry = iterator.next();
sb.append(entry + ", "); sb.append(entry + ", ");
} }
@ -232,27 +239,12 @@ public class OpenAddressingHashTable<K, V> implements Iterable<OpenAddressingHas
} }
} }
public static class Entry<K, V> { public static class Entry<K, V> extends Map.Entry<K, V> {
private K key;
private V val;
private Entry<K, V> prev; private Entry<K, V> prev;
private Entry<K, V> next; private Entry<K, V> next;
public Entry(K key, V val) { public Entry(K key, V val) {
this.key = key; super(key, val);
this.val = val;
}
public K key()
{
return key;
}
public V val()
{
return val;
}
public String toString() {
return "<" + key + "," + val + ">";
} }
} }
@ -275,7 +267,7 @@ public class OpenAddressingHashTable<K, V> implements Iterable<OpenAddressingHas
} }
} }
private class LinkedHashTableIterator implements Iterator<Entry<K,V>> { private class LinkedHashTableIterator implements Iterator<Map.Entry<K,V>> {
private Entry<K,V> start = head; private Entry<K,V> start = head;
public boolean hasNext() { public boolean hasNext() {

View File

@ -0,0 +1,16 @@
package net.abhinavsarkar.algorist;
import java.util.Optional;
public interface SortedMap<K extends Comparable<K>, V> extends Map<K, V>
{
Optional<K> minimum();
Optional<K> maximum();
Optional<K> successor(K key);
Optional<K> predecessor(K key);
}

View File

@ -24,7 +24,7 @@ public class TreeGraphvizVisitor implements AVLTree.Visitor, BinarySearchTree.Vi
{ {
MutableNode gNode = mutNode(nodeName); MutableNode gNode = mutNode(nodeName);
graph.add(gNode); graph.add(gNode);
index.insert(nodeName, gNode); index.put(nodeName, gNode);
} }
@Override @Override