Extract Map interfaces
This commit is contained in:
parent
52033d8547
commit
b179302265
@ -6,7 +6,7 @@ import java.util.NoSuchElementException;
|
||||
import java.util.Optional;
|
||||
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;
|
||||
|
||||
@ -14,30 +14,37 @@ public class AVLTree<K extends Comparable<K>,V> implements Iterable<AVLTree.Entr
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<V> get(K key) {
|
||||
return this.root.get(key);
|
||||
}
|
||||
|
||||
public void delete(K key) {
|
||||
@Override
|
||||
public void remove(K key) {
|
||||
this.root = this.root.delete(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<K> minimum() {
|
||||
return this.root.minimum();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<K> maximum() {
|
||||
return this.root.maximum();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<K> successor(K key) {
|
||||
return this.root.successor(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<K> predecessor(K 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("├ ");
|
||||
}
|
||||
|
||||
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 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
|
||||
{
|
||||
AVLTree<String, String> bst = new AVLTree<>(true);
|
||||
bst.insert("a", "barista");
|
||||
bst.insert("b", "duck");
|
||||
bst.insert("c", "carpool");
|
||||
bst.insert("d", "duck");
|
||||
bst.insert("e", "carpool");
|
||||
bst.insert("f", "barista");
|
||||
bst.insert("g", "duck");
|
||||
bst.insert("h", "abhinav");
|
||||
bst.insert("i", "abhinav");
|
||||
bst.insert("j", "duck");
|
||||
bst.insert("k", "carpool");
|
||||
bst.insert("l", "carpool");
|
||||
bst.insert("m", "abhinav");
|
||||
bst.insert("n", "duck");
|
||||
bst.insert("o", "abhinav");
|
||||
bst.insert("p", "abhinav");
|
||||
bst.insert("q", "carpool");
|
||||
bst.insert("r", "barista");
|
||||
bst.insert("s", "duck");
|
||||
bst.insert("t", "barista");
|
||||
bst.insert("u", "carpool");
|
||||
bst.insert("v", "abhinav");
|
||||
bst.insert("w", "duck");
|
||||
bst.insert("x", "barista");
|
||||
bst.insert("y", "barista");
|
||||
bst.insert("z", "duck");
|
||||
bst.put("a", "barista");
|
||||
bst.put("b", "duck");
|
||||
bst.put("c", "carpool");
|
||||
bst.put("d", "duck");
|
||||
bst.put("e", "carpool");
|
||||
bst.put("f", "barista");
|
||||
bst.put("g", "duck");
|
||||
bst.put("h", "abhinav");
|
||||
bst.put("i", "abhinav");
|
||||
bst.put("j", "duck");
|
||||
bst.put("k", "carpool");
|
||||
bst.put("l", "carpool");
|
||||
bst.put("m", "abhinav");
|
||||
bst.put("n", "duck");
|
||||
bst.put("o", "abhinav");
|
||||
bst.put("p", "abhinav");
|
||||
bst.put("q", "carpool");
|
||||
bst.put("r", "barista");
|
||||
bst.put("s", "duck");
|
||||
bst.put("t", "barista");
|
||||
bst.put("u", "carpool");
|
||||
bst.put("v", "abhinav");
|
||||
bst.put("w", "duck");
|
||||
bst.put("x", "barista");
|
||||
bst.put("y", "barista");
|
||||
bst.put("z", "duck");
|
||||
|
||||
System.out.println(bst);
|
||||
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("A"));
|
||||
|
||||
bst.delete("q");
|
||||
bst.remove("q");
|
||||
System.out.println(bst.root.checkIfBST());
|
||||
System.out.println(bst.root.checkIfAVLT());
|
||||
bst.delete("r");
|
||||
bst.remove("r");
|
||||
System.out.println(bst.root.checkIfBST());
|
||||
System.out.println(bst.root.checkIfAVLT());
|
||||
bst.delete("k");
|
||||
bst.remove("k");
|
||||
System.out.println(bst.root.checkIfBST());
|
||||
System.out.println(bst.root.checkIfAVLT());
|
||||
bst.delete("c");
|
||||
bst.remove("c");
|
||||
System.out.println(bst.root.checkIfBST());
|
||||
System.out.println(bst.root.checkIfAVLT());
|
||||
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"));
|
||||
|
||||
for (Entry<String,String> entry: bst) {
|
||||
System.out.println(entry.key);
|
||||
System.out.println(entry.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,11 +6,11 @@ import java.util.NoSuchElementException;
|
||||
import java.util.Optional;
|
||||
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();
|
||||
|
||||
public void insert(K key, V val) {
|
||||
public void put(K key, V 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);
|
||||
}
|
||||
|
||||
public void delete(K key) {
|
||||
public void remove(K 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("├ ");
|
||||
}
|
||||
|
||||
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 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
|
||||
{
|
||||
BinarySearchTree<String, String> bst = new BinarySearchTree<>();
|
||||
bst.insert("q", "barista");
|
||||
bst.insert("y", "duck");
|
||||
bst.insert("k", "carpool");
|
||||
bst.insert("p", "duck");
|
||||
bst.insert("c", "carpool");
|
||||
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");
|
||||
bst.put("q", "barista");
|
||||
bst.put("y", "duck");
|
||||
bst.put("k", "carpool");
|
||||
bst.put("p", "duck");
|
||||
bst.put("c", "carpool");
|
||||
bst.put("e", "barista");
|
||||
bst.put("d", "duck");
|
||||
bst.put("f", "abhinav");
|
||||
bst.put("j", "abhinav");
|
||||
bst.put("t", "duck");
|
||||
bst.put("s", "carpool");
|
||||
bst.put("g", "carpool");
|
||||
bst.put("v", "abhinav");
|
||||
bst.put("h", "duck");
|
||||
bst.put("r", "abhinav");
|
||||
bst.put("n", "abhinav");
|
||||
bst.put("w", "carpool");
|
||||
bst.put("u", "barista");
|
||||
bst.put("z", "duck");
|
||||
bst.put("b", "barista");
|
||||
bst.put("o", "carpool");
|
||||
bst.put("a", "abhinav");
|
||||
bst.put("l", "duck");
|
||||
bst.put("m", "barista");
|
||||
bst.put("i", "barista");
|
||||
bst.put("x", "duck");
|
||||
|
||||
System.out.println(bst);
|
||||
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("A"));
|
||||
|
||||
bst.delete("q");
|
||||
bst.delete("r");
|
||||
bst.delete("c");
|
||||
bst.remove("q");
|
||||
bst.remove("r");
|
||||
bst.remove("c");
|
||||
System.out.println(bst);
|
||||
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"));
|
||||
|
||||
for (Entry<String,String> entry: bst) {
|
||||
System.out.println(entry.key);
|
||||
System.out.println(entry.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ public class LRWCache<K, V> implements Iterable<K>
|
||||
public void put(K key, V val) {
|
||||
store.put(key, val);
|
||||
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>()
|
||||
{
|
||||
private final Iterator<OpenAddressingHashTable.Entry<K,V>> it = store.iterator();
|
||||
private final Iterator<Map.Entry<K,V>> it = store.iterator();
|
||||
|
||||
@Override
|
||||
public boolean hasNext()
|
||||
@ -49,7 +49,7 @@ public class LRWCache<K, V> implements Iterable<K>
|
||||
@Override
|
||||
public K next()
|
||||
{
|
||||
return it.next().key();
|
||||
return it.next().getKey();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
36
src/main/java/net/abhinavsarkar/algorist/Map.java
Normal file
36
src/main/java/net/abhinavsarkar/algorist/Map.java
Normal 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 + ">";
|
||||
}
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@ import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
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);
|
||||
@ -40,6 +40,7 @@ public class OpenAddressingHashTable<K, V> implements Iterable<OpenAddressingHas
|
||||
return num == 1 ? 1 : Integer.highestOneBit(num - 1) * 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<V> get(K key) {
|
||||
int trial = 0;
|
||||
int baseIndex = calcIndex(key, store.length);
|
||||
@ -55,19 +56,20 @@ public class OpenAddressingHashTable<K, V> implements Iterable<OpenAddressingHas
|
||||
else if (entry == REMOVED && firstRemovedIndex == -1) {
|
||||
firstRemovedIndex = index;
|
||||
}
|
||||
else if (entry.key.equals(key))
|
||||
else if (entry.getKey().equals(key))
|
||||
{
|
||||
if (firstRemovedIndex != -1) {
|
||||
store[firstRemovedIndex] = entry;
|
||||
store[index] = REMOVED;
|
||||
}
|
||||
return Optional.of(entry.val);
|
||||
return Optional.of(entry.getVal());
|
||||
}
|
||||
trial++;
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(K key, V val) {
|
||||
if (actualSize >= loadFactor * store.length) {
|
||||
resize();
|
||||
@ -77,8 +79,9 @@ public class OpenAddressingHashTable<K, V> implements Iterable<OpenAddressingHas
|
||||
|
||||
private void resize() {
|
||||
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);
|
||||
}
|
||||
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) {
|
||||
int trial = 0;
|
||||
int baseIndex = calcIndex(nEntry.key, store.length);
|
||||
int baseIndex = calcIndex(nEntry.getKey(), store.length);
|
||||
while (trial < store.length) {
|
||||
int index = probingStrategy.nextIndex(baseIndex, trial, store.length);
|
||||
Entry<K,V> entry = (Entry<K,V>) store[index];
|
||||
@ -105,12 +108,14 @@ public class OpenAddressingHashTable<K, V> implements Iterable<OpenAddressingHas
|
||||
store[index] = nEntry;
|
||||
return;
|
||||
}
|
||||
else if (entry.key.equals(nEntry.key))
|
||||
else if (entry.getKey().equals(nEntry.getKey()))
|
||||
{
|
||||
if (!resize) {
|
||||
linkUpdatedEntry(entry);
|
||||
}
|
||||
entry.val = nEntry.val;
|
||||
nEntry.next = entry.next;
|
||||
nEntry.prev = entry.prev;
|
||||
store[index] = nEntry;
|
||||
return;
|
||||
}
|
||||
trial++;
|
||||
@ -154,6 +159,7 @@ public class OpenAddressingHashTable<K, V> implements Iterable<OpenAddressingHas
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(K key) {
|
||||
int trial = 0;
|
||||
int baseIndex = calcIndex(key, store.length);
|
||||
@ -165,7 +171,7 @@ public class OpenAddressingHashTable<K, V> implements Iterable<OpenAddressingHas
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (entry.key.equals(key))
|
||||
else if (entry.getKey().equals(key))
|
||||
{
|
||||
unlinkEntry(entry);
|
||||
store[index] = REMOVED;
|
||||
@ -200,14 +206,15 @@ public class OpenAddressingHashTable<K, V> implements Iterable<OpenAddressingHas
|
||||
return key.hashCode() % size;
|
||||
}
|
||||
|
||||
public Iterator<Entry<K,V>> iterator() {
|
||||
public Iterator<Map.Entry<K,V>> iterator() {
|
||||
return new LinkedHashTableIterator();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
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 + ", ");
|
||||
}
|
||||
|
||||
@ -232,27 +239,12 @@ public class OpenAddressingHashTable<K, V> implements Iterable<OpenAddressingHas
|
||||
}
|
||||
}
|
||||
|
||||
public static class Entry<K, V> {
|
||||
private K key;
|
||||
private V val;
|
||||
public static class Entry<K, V> extends Map.Entry<K, V> {
|
||||
private Entry<K, V> prev;
|
||||
private Entry<K, V> next;
|
||||
|
||||
public Entry(K key, V val) {
|
||||
this.key = key;
|
||||
this.val = val;
|
||||
}
|
||||
|
||||
public K key()
|
||||
{
|
||||
return key;
|
||||
}
|
||||
public V val()
|
||||
{
|
||||
return val;
|
||||
}
|
||||
public String toString() {
|
||||
return "<" + key + "," + val + ">";
|
||||
super(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;
|
||||
|
||||
public boolean hasNext() {
|
||||
|
16
src/main/java/net/abhinavsarkar/algorist/SortedMap.java
Normal file
16
src/main/java/net/abhinavsarkar/algorist/SortedMap.java
Normal 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);
|
||||
|
||||
}
|
@ -24,7 +24,7 @@ public class TreeGraphvizVisitor implements AVLTree.Visitor, BinarySearchTree.Vi
|
||||
{
|
||||
MutableNode gNode = mutNode(nodeName);
|
||||
graph.add(gNode);
|
||||
index.insert(nodeName, gNode);
|
||||
index.put(nodeName, gNode);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Loading…
Reference in New Issue
Block a user