散列是一种用于以常数平均时间执行插入、删除和查找的技术。但是,那些需要元素间任何排序信息的树操作将不会得到有效的支持。因此,诸如findMin、findMax以及以线性时间将排过序的整个表进行打印的操作都是散列所不支持的。
每个关键字被映射到从0到TableSize - 1这个范围中的某个数,并且被放到适当的单元中。这个映射就叫做散列函数。因为单元的数目是有限的,而关键字实际上是用不完的。因此,我们寻找一个散列函数,该函数要在单元之间均匀地分配关键字。剩下的问题就是要选择一个函数,决定到两个关键字散列到同一个值的时候(冲突)应该做什么以及如何确定散列表的大小。
散列函数
public static int hash(String key, int tableSize)
{
int hashVal = 0;
for(int i = 0; i < key.length(); i++)
{
hashVal = 37 * hashVal + key.charAt(i);
}
hashVal %= tableSize;
if(hashVal < 0)
{
hashVal += tableSize;
}
return hashVal;
}
解决冲突
分离链接法
将散列到同一个值的所有元素保留到一个表中。
开放定址法
另有一种不使用链表解决冲突的方法是尝试另外一些单元,直到找出空的单元为止。更常见的是,单元h0(x),h1(x),h2(x),...相继被试选,其中hi(x) = (hash(x) + f(i)) mod tableSize,且f(0) = 0。函数f是冲突解决方法。因为所有数据都要置入表内,所以这种解决方案所需要的表要比分离链接散列的表大。