下列代码主要实现了调整数组的大小来保证散列表的使用率永远都不会超过1/2resize(),插入键put(),查找键get(),查找键在线性表中的位置getplace(),删除键delete(),遍历线性表keys()等方法
package cn.edu.zzuli.api;
import edu.princeton.cs.algs4.Queue;
import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;
public class LPHST<Key, Value> {
private int N;//符号表中键值对的总数
private int M;//线性探测表的大小
private Key[] keys;//键
private Value[] vals;//值
public LPHST(int capacity){
N = 0;
M = capacity;
keys = (Key[]) new Object[M];
vals = (Value[]) new Object[M];
}
private int hash(Key key) {
return (key.hashCode() & 0xfffffff) % M;
}
//通过调整数组的大小来保证散列表的使用率永远都不会超过1/2
private void resize(int capacity) {
LPHST<Key, Value> temp = new LPHST<Key, Value>(capacity);
for(int i = 0; i < M; i++) {
if(keys[i] != null)
temp.put(keys[i], vals[i]);
}
M = temp.M;
keys = temp.keys;
vals = temp.vals;
}
public void put(Key key, Value val) {
if(N >= M/2)
resize(2 * M);
int i;
for(i = hash(key); keys[i] != null; i = (i + 1) % M) {
if(key.equals(keys[i])) {
vals[i] = val;
return;
}
}
keys[i] = key;
vals[i] = val;
N++;
}
//删除键时,我们需要将簇中被删除键右边的所有键重新插入散列表
public void delete(Key key) {
if(get(key) == null) {
return;
}
int i = hash(key);
while(!key.equals(keys[i])) {
i = (i + 1) % M;
}
keys[i] = null;
vals[i] = null;
i = (i + 1) % M;
while(keys[i] != null) {
Key keyToRedo = keys[i];
Value valToRedo = vals[i];
keys[i] = null;
vals[i] = null;
N--;
put(keyToRedo, valToRedo);
i = (i + 1) % M;
}
N--;
if(N > 0 && N <= M/8) {
resize(M / 2);
}
}
//将键在线性表中的位置返回,如果键在线性表中找不到,则返回(M + 1)
public int getpalce(Key key) {
for(int i = hash(key); keys[i] != null; i = (i + 1) % M) {
if(key.equals(keys[i])) {
return i;
}
}
return M + 1;
}
//查找与键对应的值
public Value get(Key key) {
for(int i = hash(key); keys[i] != null; i = (i + 1) % M) {
if(key.equals(keys[i])) {
return vals[i];
}
}
return null;
}
public Iterable<Key> keys(){
Queue<Key> queue = new Queue<Key>();
for(int i = 0; i < M; i++) {
if(keys[i] != null)
queue.enqueue(keys[i]);
}
return queue;
}
public static void main(String[] args) {
LPHST<String, Integer> st = new LPHST<String, Integer>(16);
for (int i = 0; i < 13; i++) {
String key = StdIn.readString();
st.put(key, i);
}
for (String s : st.keys()) {
StdOut.print(s + " " + st.get(s));
StdOut.println(", " + st.getpalce(s));
}
st.delete("M");
StdOut.println("*************************************");
for (String s : st.keys()) {
StdOut.print(s + " " + st.get(s));
StdOut.println(", " + st.getpalce(s));
}
StdOut.println("*************************************");
}
}
测试用例
S E A R C H E X A M P L E
不同的机器的hashCode()不一定相同