publicSeparateChainingHashST(int M){ this.M = M; st = (SequentialSearchST<Key, Value>[]) new SequentialSearchST[M]; for (int i = 0; i < M; i++) st[i] = new SequentialSearchST(); }
public Value get(Key key){ if (key == null) thrownew IllegalArgumentException(); if (isEmpty()) thrownew NoSuchElementException(); return (Value) st[hash(key)].get(key); }
插入 put:
1 2 3 4 5 6 7 8 9 10 11
publicvoidput(Key key, Value value){ if (key == null) thrownew IllegalArgumentException(); if (value == null) { delete(key); } else { //动态调整散列表的大小 if (N >= 10 * M) resize(2 * M); if (!st[hash(key)].contains(key)) N++; st[hash(key)].put(key, value); } }
privatevoidresize(int chains){ SeparateChainingHashST<Key, Value> temp = new SeparateChainingHashST(chains); for (int i = 0; i < M; i++) { Iterator<Key> iterator = st[i].keys().iterator(); while (iterator.hasNext()) { Key key = iterator.next(); Value value = st[i].get(key); temp.put(key, value); } } M = temp.M; N = temp.N; st = temp.st; }
删除 delete:
1 2 3 4 5 6 7 8 9
publicvoiddelete(Key key){ if (key == null) thrownew IllegalArgumentException(); if (isEmpty()) thrownew NoSuchElementException(); if (get(key) == null) thrownew NoSuchElementException(); if (st[hash(key)].contains(key)) N--; st[hash(key)].delete(key); if (M > 4 && N <= 2 * M) resize(M / 2); }
publicclassLinearProbingHashST<Key, Value> { privateint N; //total number of item privateint M; //Size of map , M > N private Key[] keys; private Value[] values;
public Value get(Key key){ if (key == null) thrownew IllegalArgumentException(); if (isEmpty()) thrownew NoSuchElementException(); for (int i = hash(key); keys[i] != null; i = (i + 1) % M) { if (keys[i].equals(key)) { return values[i]; } } returnnull; }
由于是使用数组实现,所以查找比较简单,开销很小,最差情况也能在 O(logN) 内能完成。
插入 put:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
publicvoidput(Key key, Value value){ if (key == null) thrownew IllegalArgumentException(); if (N >= M / 2) resize(2 * M); if (value == null) delete(key); int i; for (i = hash(key); keys[i] != null; i = (i + 1) % M) { if (keys[i].equals(key)) { values[i] = value; return; } } keys[i] = key; values[i] = value; N++; }
publicvoiddelete(Key key){ if (key == null) return; if (isEmpty() || !contains(key)) thrownew NoSuchElementException(); int i = hash(key); while (!key.equals(keys[i])) { i = (i + 1) % M; } keys[i] = null; values[i] = null; i = (i + 1) % M; while (keys[i] != null) { Key keyToRedo = keys[i]; Value valueToRedo = values[i]; keys[i] = null; values[i] = null; N--; put(keyToRedo, valueToRedo); i = (i + 1) % M; } N--; if (N > 0 && N <= M / 8) resize(M / 2); }
privatevoidresize(int cap){//must be needed LinearProbingHashST<Key, Value> t; t = new LinearProbingHashST<>(cap); for (int i = 0; i < M; i++) if (keys[i] != null) t.put(keys[i], values[i]); keys = t.keys; values = t.values; M = t.M; }