Created
December 24, 2015 17:47
-
-
Save allanx2000/b38a02326760a59556de to your computer and use it in GitHub Desktop.
Tested. got OutOfMemory with 100k entries but not really optimized. Sequential crashes at 10k
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class LinearProbingHT<T1, T2> extends HashTable<T1, T2> { | |
private int size = 0; | |
private Object[] nodes; | |
public LinearProbingHT(int initSize) { | |
nodes = new Object[initSize]; | |
} | |
private int getIndexFromHash(T1 key) { | |
int hash = key.hashCode(); | |
hash = hash % nodes.length; | |
return hash; | |
} | |
private final double ALPHA_LEVEL = .5; | |
@Override | |
public void delete(T1 key) { | |
Integer idx = find(key); | |
if (idx != null) { | |
Node n = getNode(idx); | |
n.key = null; | |
n.value = null; | |
size--; | |
} | |
} | |
private Integer IndexForPut(T1 key) { | |
int hashIdx = getIndexFromHash(key); | |
if (isEmpty(hashIdx)) | |
return hashIdx; | |
int idx = hashIdx + 1; | |
while (idx < nodes.length) { | |
if (!isEmpty(idx)) | |
idx++; | |
else | |
return idx; | |
} | |
// Reached end | |
idx = 0; | |
while (!isEmpty(idx) && idx < hashIdx) { | |
idx++; | |
} | |
if (idx == hashIdx) | |
return null; | |
else | |
return idx; | |
} | |
private Integer find(T1 key) { | |
int hashIdx = getIndexFromHash(key); | |
if (matches(hashIdx, key)) | |
return hashIdx; | |
int idx = hashIdx + 1; | |
while (idx < nodes.length) { | |
if (isEmpty(idx)) | |
return null; | |
if (matches(hashIdx, key)) | |
return idx; | |
else | |
idx++; | |
} | |
// Reached end | |
idx = 0; | |
while (idx < hashIdx) { | |
if (isEmpty(idx)) | |
return null; | |
if (matches(hashIdx, key)) | |
return idx; | |
else | |
idx++; | |
} | |
return null; | |
} | |
private boolean matches(int index, T1 key) { | |
if (isEmpty(index)) | |
return false; | |
else | |
return getNode(index).key.equals(key); | |
} | |
@Override | |
public void put(T1 key, T2 value) throws Exception { | |
double alpha = getAlpha(size, nodes.length); | |
if (alpha >= ALPHA_LEVEL) | |
{ | |
double newSize = ((double)nodes.length)/(ALPHA_LEVEL) * 2; | |
resize(nodes.length, (int) newSize); | |
} | |
Integer idx = IndexForPut(key); | |
if (idx == null) | |
throw new Exception("Table full"); | |
else | |
put(idx, key, value); | |
} | |
private void resize(int oldSize, int newSize) throws Exception { | |
double alpha = getAlpha(oldSize, newSize); | |
if (alpha >= ALPHA_LEVEL) | |
throw new Exception("New size is not big enough. Alpha = " + alpha); | |
Object[] old = nodes; | |
nodes = new Object[newSize]; | |
size = 0; | |
for (int i = 0; i < oldSize; i++) | |
{ | |
if (!isEmpty(old[i])) | |
{ | |
Node n = ((Node) old[i]); | |
put(n.key,n.value); | |
} | |
} | |
} | |
private double getAlpha(int oldSize, int newSize) { | |
double alpha = ((double)oldSize/(double)newSize); | |
return alpha; | |
} | |
private boolean isEmpty(Object node) { | |
return node == null || ((Node) node).key == null; | |
} | |
private boolean isEmpty(int idx) { | |
return nodes[idx] == null || getNode(idx).key == null; | |
} | |
private void put(int idx, T1 key, T2 value) { | |
if (nodes[idx] == null) { | |
Node n = new Node(key, value); | |
nodes[idx] = n; | |
} else { | |
Node n = getNode(idx); | |
n.key = key; | |
n.value = value; | |
} | |
size++; | |
} | |
private Node getNode(int idx) { | |
return (Node) nodes[idx]; | |
} | |
@Override | |
public T2 get(T1 key) { | |
Integer idx = find(key); | |
if (idx == null) | |
return null; | |
else | |
return getNode(idx).value; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment