该HashTable基于定常数组的开放地址法,搜索时采用线性探测发
由于删除时使用标志的做法,因此该HashTable常作删除会导致效率的下降。
为了保证此表的操作效率,数组的大小为所需要存储的数据的两倍。如果再细致一些,应该是大于其两倍的的第一个质数,这样可以减小Hash冲突的可能性,不过这里没有这样作,同样是为了代码清晰。
HashTable的遍历不占优势,此处没有实现。
API
find:查找指定键的数据项目
add:添加新数据
remove:删除指定键的数据项目
Item为辅助类,为了简便,关键字使用非负整数,且没有采用标准的set,get方法
HashTable.main提供一个简便的测试。
其他的实现请参见链接表HashTable ,再用Hash探测的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) {
array = new Item[size * 2];
}
public void add(Item item) {
assert size < array.length ;
int keyHash = getKeyHash(item.key());
while(array[keyHash] != null && array[keyHash].key() == -1) {
keyHash++;
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++;
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++;
keyHash %= array.length;
}
return null;
}
public static void main(String[] args) {
HashTable t = new HashTable(5);
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");
}
}