基於拉鍊法的散列表(來自:演算法)
阿新 • • 發佈:2018-12-10
下列程式碼主要實現了基於拉鍊法的散列表的新增元素put(),查詢元素get(),刪除元素delete(),遍歷元素keys()等方法,我們需要首先根據元素值呼叫hash()方法找到該元素所對應的陣列,而每一個數組都是一個連結串列,遍歷連結串列,若元素不存在,則可以實現元素的新增,若存在,則可以實現元素的更新,刪除等操作.
對於每一條連結串列的操作
package cn.edu.zzuli.api; import edu.princeton.cs.algs4.Queue; public class SequentialSearchST<Key, Value> { private Node first;//連結串列首結點 private class Node{ //連結串列結點的定義 private final Key key; private Value val; private Node next; public Node(Key key, Value val, Node next) { this.key = key; this.val = val; this.next = next; } public Key getKey() { return key; } public Value getVal() { return val; } public void setVal(Value val) { this.val = val; } public Node getNext() { return next; } public void setNext(Node next) { this.next = next; } } //查詢給定的鍵,返回相關聯的值 public Value get(Key key) { for(Node i = first; i != null; i = i.next) { if(key.equals(i.key)) return i.val; } return null; } //查詢給定的鍵,找到則更新其值,否則在表中新建結點 public void put(Key key, Value val) { for(Node i = first; i != null; i = i.next) { if(key.equals(i.key)) { i.val = val; return; } } first = new Node(key, val, first); } //刪除結點 public void delete(Key key) { first = delete(first, key); } private Node delete(Node x, Key key) { if(x == null) { return null; } if(key.equals(x.key)) { return x.next; } x.next = delete(x.next, key); return x; } public Iterable<Key> keys(){ Queue<Key> q = new Queue<Key>(); for(Node i = first; i != null; i = i.next) { q.enqueue(i.key); } return q; } public Key getKey() { return first.key; } }
基於拉鍊法的散列表
package cn.edu.zzuli.api; import edu.princeton.cs.algs4.StdOut; import edu.princeton.cs.algs4.Queue; import edu.princeton.cs.algs4.StdIn; public class SeparateChainingHashST<Key, Value> { //SequetialSearchST private int N;//鍵值對總數 private int M;//散列表的大小 private SequentialSearchST<Key, Value>[] st;//存放連結串列物件的陣列 public SeparateChainingHashST() {//預設的建構函式會使用997條連結串列 this(997); } public SeparateChainingHashST(int M) { //建立M條連結串列 this.M = M; //創造一個(SequentialSearchST<Key, Value>[])型別的,長度為M的陣列 st = (SequentialSearchST<Key, Value>[]) new SequentialSearchST[M]; for(int i = 0; i < M; i++) { //為每一個數組元素申請一個空間 st[i] = new SequentialSearchST(); } } private int hash(Key key) { return (key.hashCode() & 0x7fffffff) % M; } public Value get(Key key) { return (Value)st[hash(key)].get(key); } public void put(Key key, Value val) { st[hash(key)].put(key, val); } public void delete(Key key) { st[hash(key)].delete(key); } public Iterable<Key> keys(){ Queue<Key> queue = new Queue<Key>(); for(int i = 0; i < M; i++) { System.out.println("第" + i +"個元素的連結串列"); for(Key key : st[i].keys()) { queue.enqueue(key); System.out.print(key + " " + get(key) + " ,"); } System.out.println(); } return queue; } public static void main(String[] args) { SeparateChainingHashST<String, Integer> st = new SeparateChainingHashST<String, Integer>(5); for (int i = 0; i < 13; i++) { String key = StdIn.readString(); st.put(key, i); } for (String s : st.keys()) StdOut.println(s + " " + st.get(s)); st.delete("M"); StdOut.println("*************************************"); for (String s : st.keys()) { StdOut.println(s + " " + st.get(s)); } } }
測試用例
S E A R C H E X A M P L E