update impl

This commit is contained in:
Wouter Groeneveld 2018-03-27 13:03:12 +02:00
parent f471ca702e
commit c86f29ccc1
6 changed files with 107 additions and 19 deletions

View File

@ -0,0 +1,11 @@
package be.brainbaking.datastructures.hashtable;
public class DeletedBucket<Key, Value> implements IAmBucketable<Key, Value> {
private static DeletedBucket bucket = new DeletedBucket();
public static <Key, Value> DeletedBucket<Key, Value> singleton() {
return bucket;
}
}

View File

@ -1,10 +1,27 @@
package be.brainbaking.datastructures.hashtable;
public class HashBucket<T> {
public class HashBucket<Key, Value> implements IAmBucketable<Key, Value> {
private final T key;
/**
* the key of the bucket to store the value in
*/
private final Key key;
public HashBucket(T key) {
/**
* "sattelite" data
*/
private final Value value;
public Value getValue() {
return value;
}
public Key getKey() {
return key;
}
public HashBucket(Key key, Value value) {
this.key = key;
this.value = value;
}
}

View File

@ -3,9 +3,11 @@ package be.brainbaking.datastructures.hashtable;
import be.brainbaking.datastructures.hashing.Hashable;
import be.brainbaking.datastructures.hashing.LinearProbeHash;
public class HashTable<T> {
import java.util.Arrays;
private final HashBucket<T>[] table;
public class HashTable<Key, Value> {
private final HashBucket<Key, Value>[] table;
private final Hashable hasher;
public HashTable() {
@ -17,32 +19,54 @@ public class HashTable<T> {
hasher = new LinearProbeHash(10);
}
public void add(T key) {
add(key, 0);
public void put(Key key, Value value) {
put(key, value, 0);
}
public void remove(T key) {
public Value remove(Key key) {
throw new UnsupportedOperationException();
// TODO "deleted" stuff
// TODO "deleted" stuff (bestaande calls wijzigen)
}
public int search(T key) {
throw new UnsupportedOperationException();
// TODO return key if exists
public Value get(Key key) {
return get(key, 0);
}
private void add(T key, int probeStep) {
if(probeStep > table.length) {
/**
* Géén O(1), maar "gemiddeld" gezien wel, gegeven dat de hash goed gekozen is en we weinig moeten proben.
* @param key key van bucket
* @param probeStep probe start positie
* @return indien niet gevonden, null, anders de bewaarde value
*/
private Value get(Key key, int probeStep) {
int hash = hasher.hash(key, probeStep);
if(hash >= table.length) return null;
if(table[hash].getKey() == key) return table[hash].getValue();
return get(key, probeStep + 1);
}
/**
* table.length is niet de "size". O(n) nodig, alles overlopen om te kijken wat ingevuld is... Kostelijk!
* @return the size
*/
public int size() {
return (int) Arrays.stream(table).filter(entry -> entry != null).count();
}
private void put(Key key, Value value, int probeStep) {
// TODO resizing van tabel indien te groot geworden
int hash = hasher.hash(key, probeStep);
if(hash >= table.length) {
throw new UnsupportedOperationException("unable to add key to table, everything occupied?");
}
int hash = hasher.hash(key, probeStep);
if(table[hash] != null) {
add(key, probeStep + 1);
put(key, value, probeStep + 1);
} else {
table[hash] = new HashBucket<>(key);
table[hash] = new HashBucket<>(key, value);
}
}
}

View File

@ -0,0 +1,5 @@
package be.brainbaking.datastructures.hashtable;
public interface IAmBucketable<Key, Value> {
}

View File

@ -0,0 +1,25 @@
package be.brainbaking.datastructures.hashing;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class LinearProbeHashTest {
@Test
public void shouldHashingBeRecalculated_ifMaximumChanges() {
LinearProbeHash hash10 = new LinearProbeHash(10);
LinearProbeHash hash15 = new LinearProbeHash(15);
int hashed10 = hash10.hash((Integer) 123, 0);
int hashed15 = hash15.hash((Integer) 123, 0);
assertEquals(hashed15, hashed10);
int hashed10Bigger = hash10.hash((Integer) 123456789, 0);
int hashed15Bigger = hash15.hash((Integer) 123456789, 0);
assertEquals(hashed15Bigger, hashed10Bigger);
}
}

View File

@ -2,11 +2,17 @@ package be.brainbaking.datastructures.hashtable;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class HashTableTest {
@Test
public void add() {
public void add_increasesSize_andAbleToGetValue() {
HashTable<Integer, Integer> table = new HashTable<>();
table.put(123, 445);
assertEquals(1, table.size());
assertEquals(445, (int) table.get(123));
}
}