与前一个HashTable 基本相同(方法说明请参照它),只是当发生Hash冲突时,采用再用哈希法探测步长。
前面当发生Hash冲突时,直接看当前位置下一个有没有空位,这相当于步长为一,但这容易产生聚集,大的聚集产成后Hash的效率会下降,采用Hash法采用的是使用不同的Hash函数来产生一个新的步长。
新的hash有以下要求
非0
与第一个Hash函数不同
除此之外:
这个HashTable的size要求是质数,因此是靠程序自己计算出来的。
基于链表的HashTable请参见HashTable
public class Item {
private int key;
private Object value;
public Item(int key, Object value) {
this.key = key;
this.value = value;
}
public int key() { return key; }
public Object value() { return value; }
}
public class HashTable {
private Item noItem = new Item(-1,null);
private Item[] array;
private int size;
public HashTable(int size) {
assert size > 5;
array = new Item[findPrimeMoreThan(size * 2 + 1)];
}
private int findPrimeMoreThan(int size) {
while(true) {
if(isPrime(size)) return size;
size ++;
}
}
private boolean isPrime(int value) {
for(int i=2; i<value/2; i++) {
if(value%i == 0) return false;
}
return true;
}
private int getStep(int key) {
return 5 - (key%5);
}
public void add(Item item) {
assert size < array.length ;
int keyHash = getKeyHash(item.key());
while(array[keyHash] != null && array[keyHash].key() == -1) {
keyHash += getStep(item.key());
keyHash %= array.length;
}
array[keyHash] = item;
size++;
}
private int getKeyHash(int value) {
return value%array.length;
}
public Item find(int key) {
int keyHash = getKeyHash(key);
while(array[keyHash] != null) {
if(array[keyHash].key() == key) return array[keyHash];
keyHash += getStep(key);
keyHash %= array.length;
}
return null;
}
public Item remove(int key) {
int keyHash = getKeyHash(key);
while(array[keyHash] != null) {
if(array[keyHash].key() == key) {
Item result = array[keyHash];
array[keyHash] = noItem;
return result;
}
keyHash += getStep(key);
keyHash %= array.length;
}
return null;
}
public static void main(String[] args) {
HashTable t = new HashTable(10);
t.add(new Item(1,"hello"));
t.add(new Item(6,"world"));
t.add(new Item(3,"jason"));
t.add(new Item(104,"orange"));
t.add(new Item(9,"peter"));
assert t.find(6).value().equals("world");
assert t.find(104).value().equals("orange");
assert t.find(9).value().equals("peter");
assert t.find(87) == null;
assert t.remove(3).value().equals("jason");
assert t.find(3) == null;
assert t.remove(6).value().equals("world");
assert t.find(6) == null;
t.add(new Item(6,"temp"));
assert t.find(6).value().equals("temp");
}
}