importjava.io.ObjectInputStream;importjava.util.ArrayList;importjava.util.Iterator;/*** @ClassName SeparateChainHashST
* @Author wangyudi
* @Date 2019/7/2 22:25
* @Version 1.0
* @Description 拉链法散列表(哈希表)*/
public class SeparateChainHashST{private int m;//数组大小
private int n;//键值对数量
private Chain[] st;//存放链表的数组
private ArrayList list; //用于迭代获取键的集合
publicSeparateChainHashST() {this(997);
}public SeparateChainHashST(intm) {this.m =m;
st= (Chain[]) new Chain[m]; //实例化数组
for (int i = 0; i < m; i++) {
st[i]= new Chain(); //数组每个元素都指向一个空链表
}this.n = 0;
}public intgetSize(){returnm;
}/*** 为了保证每条链的大小保持在2~8,调整数组的大小到size
* 将源哈希表中所有键值对插入到新哈希表中;然后将新哈希表中的成员给源哈希表
*@paramsize*/
private void resize(intsize){
SeparateChainHashST keyValueSeparateChainHashST = new SeparateChainHashST<>(size);for(int i=0;i
keyValueSeparateChainHashST.put((Key)o[0],(Value)o[1]);
}
}this.m =keyValueSeparateChainHashST.m;this.st =keyValueSeparateChainHashST.st;
}/*** 返回可迭代的对象
*
*@return
*/
public Iterablekeys() {
list= new ArrayList<>();for (int i = 0; i < m; i++) {for(Object[] o : st[i]) {
list.add((Key)o[0]);
}
}returnlist;
}/*** 根据键的hashcode,计算每个键的索引值
*
*@paramkey
*@return
*/
private inthash(Key key) {return (key.hashCode() & 0x7FFFFFFF) %m;
}/*** 向哈希表中放入一个键值对,如果存在相同的键则更新该键的值
*
*@paramkey
*@paramvalue*/
public voidput(Key key, Value value) {if(n>8*m){
resize(2*m);
}int i = hash(key);//找到键所在的数组索引
st[i].put(key, value);//将插入键值对的问题交给链表
n++;
}/*** 根据键,从哈希表获取相应的值;没有该键则返回null*/
publicValue get(Key key) {int i =hash(key);returnst[i].get(key);
}/*** 从哈希表删除键值对,并返回被删除键的值。
*
*@paramkey
*@return
*/
public voiddelete(Key key) {int i =hash(key);if(st[i].delete(key)){
n--;
}if(n>0&&n<=2*m){
resize(m/2);
}
}
}/*** 链表类
*
*@param
*@param*/
class Chain implements Iterable{privateNode first;private classNode {
Key key;
Value value;
Node next;publicNode(Key key, Value value, Node next) {this.key =key;this.value =value;this.next =next;
}
}publicValue get(Key key) {for (Node i = first; i != null; i =i.next) {if (i.key ==key) {returni.value;
}
}return null;
}public voidput(Key key, Value value) {for (Node i = first; i != null; i =i.next) {if (i.key ==key) {
i.value=value;return; //找到相同的键
}
}
first= new Node(key, value, first);//在头部加入键值队
}/*** 删除单向链表中的某一个结点
*
*@paramkey
*@return
*/
public booleandelete(Key key) {//if (first == null) {//return false;//}//if (first.key == key) {//判断首结点//first = first.next;//return true;//}
Node f = null; //保存前一结点的信息
Node b =first;while (b != null && b.key !=key) {
f=b;
b=b.next;
}if (b != null) { //找到要删除的对象
if(f==null){
first=b.next; //特殊处理
}else{
f.next=b.next;
}
b.next= null;
b= null;return true;
}return false;
}
@Overridepublic Iteratoriterator() {return newIterator() {
Node i=first;
@Overridepublic booleanhasNext() {if (i != null) return true;return false;
}
@OverridepublicObject[] next() {
Key tempkey=i.key;
Value tempValue=i.value;
Object[] info= newObject[]{(Object)tempkey,(Object)tempValue};
i=i.next;returninfo;
}
};
}//public Iterator nodeIterator(){//return new Iterator() {//Node i = first;//@Override//public boolean hasNext() {//if(i!=null)return true;//return false;//}//
//@Override//public Node next() {//Node temp = i;//i = i.next;//return temp;//}//};//}
}