在检查负载因子是否表示要调整后备阵列的大小后,如何使用二次探测实际调整大小?
这是代码。 它只是课堂的一部分。另外,您能否检查我是否正确实施了添加方法?
import java.util.*;
public class HashMap<K, V> implements HashMapInterface<K, V> {
// Do not make any new instance variables.
private MapEntry<K, V>[] table;
private int size;
/**
* Create a hash map with no entries.
*/
public HashMap() {
table = new MapEntry[STARTING_SIZE];
size = 0;
}
@Override
public V add(K key, V value) {
if (key == null || value == null) {
throw new IllegalArgumentException("Passed in null arguments.");
}
if (getNextLoadFactor() > MAX_LOAD_FACTOR) {
resize();
}
MapEntry<K, V> entry = new MapEntry<>(key, value);
V val = null;
int index = Math.abs(key.hashCode()) % table.length;
int temp = index;
int q = 1;
do {
if (table[index] == null) {
table[index] = entry;
} else if (table[index].getKey().equals(key)) {
val = table[index].getValue();
table[index].setValue(value);
}
index = index + q*q % table.length;
q++;
} while (temp != index);
size++;
return val;
}
private double getNextLoadFactor() {
return (double) size / (double) table.length;
}
private void resize() {
MapEntry<K, V>[] temp = table;
table = new MapEntry[table.length * 2 + 1];
for (int i = 0; i < table.length; i++) {
}
}
答案 0 :(得分:1)
从wiki执行以下操作:
1. Get the key k
2. Set counter j = 0
3. Compute hash function h[k] = k % SIZE
4. If hashtable[h[k]] is empty
(4.1) Insert key k at hashtable[h[k]]
(4.2) Stop
Else
(4.3) The key space at hashtable[h[k]] is occupied, so we need to find the next available key space
(4.4) Increment j
(4.5) Compute new hash function h[k] = ( k + j * j ) % SIZE
(4.6) Repeat Step 4 till j is equal to the SIZE of hash table
5. The hash table is full
6. Stop
根据以上所述,我认为您的add
方法存在问题。注意步骤(4.1)和(4.2):如果table[index] == null
,找到了钥匙的位置,你可以停下来。您的do
将再次执行,因为在插入之后,您更新了索引,因此temp != index
将为真。
您还在错误地计算下一个索引,请更改
index = index + q*q % table.length;
到
index = (Math.abs(key.hashCode()) + q*q) % table.length;
add
因此将变为:
MapEntry<K, V> entry = new MapEntry<>(key, value);
V val = null;
int index = Math.abs(key.hashCode()) % table.length;
int q = 0;
while (table[(index = (Math.abs(key.hashCode()) + q*q++) % table.length)] != null);
table[index] = entry;
size++;
return val;
可以证明,如果b
个b > 3
位置的表格大小b/2
将是唯一的,那么可以安全地假设如果表格小于一半完整(b/2 - 1)
,你会发现一个空位。这取决于您的MAX_LOAD_FACTOR
。
要调整大小,您需要将每个值重新分配到新表中。这是由于您的哈希函数使用表的大小作为模数。您的哈希函数已基本更改,因此您需要创建size + 1
的新数组,并将每个元素读取到新数组。
private void resize() {
MapEntry<K, V>[] temp = table;
table = new MapEntry[table.length * 2 + 1];
for (MapEntry<K, V> entry:temp) {
this.add(entry.getKey(), entry.getValue());
}
}
注意:我没有对此进行测试,只使用动态探测和哈希表背后的理论来调试代码。希望它有所帮助!