update impl
This commit is contained in:
parent
f471ca702e
commit
c86f29ccc1
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
package be.brainbaking.datastructures.hashtable;
|
||||
|
||||
public interface IAmBucketable<Key, Value> {
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue