即散列值的范围在0-M,把大小为M的数组中每一个索引下都对应一个链表

然后依次把键值放在对应散列值的链表中,一个链表中可以存在多个键值对

图片

链表的平均长度为N/M

简单的实现代码如下

public class SeparateChainingHashST <Key,Value>{

private int N;//键值对数量

private int M;//散列表的大小

private SequentialSearchST <Key,Value>[] st;//数组

public SeparateChainingHashST() {

this(997);//默认997个

}

public SeparateChainingHashST(int i) {//创建链表

this.M = i;

st = (SequentialSearchST <Key,Value>[])new  SequentialSearchST[i];

//创建一个链表数组

for(int j =0;j<st.length;j++) {

st[j] = new SequentialSearchST();//对应创建链表

}

}

private int hash(Key key) {//hash值计算

return ((key.hashCode()&0x7fffffff)%M);

}

private Value get(Key key) {//获取值

return (st[hash(key)].get(key));//调用链表查找

}

private void put(Key key,Value val) {//输入

st[hash(key)].put(key, val);

}

}

还有着改进方式,就是增加为动态数组的方式,进行动态的扩容

从算法上我们可以看出来,这个算法极其依赖散列函数是否是均匀的

但是在实际应用中,散列表中的高性能并不需要散列函数完全符合均匀性,依旧能够高效的提高性能

对应的删除操作

要删除一个键值对,先使用散列值找到含有含有该键的链表对象

然后直接调用对象的delete对象

但是因为散列表的格式,所以对于有序性来说,他不是一个好选择

(比如,快速找到最大,最小键,查找范围的键)

但刨去有序性,只要是键的顺序不重要的应用中,其可能是最快的(也是应用范围最广的)

发表评论

邮箱地址不会被公开。 必填项已用*标注