雜湊表查詢(Java)
雜湊(雜湊表)
1.基本思想:將關鍵字 (資料項)被對映到從0到Tablesize-1這個範圍中的某個數,並且被放到適當的單元中。其中這個對映就叫做雜湊函式。
0如圖:
2.衝突:將兩個不同的關鍵字對映到同一表的位置。如圖:
3.構造雜湊函式的兩個標準:(1)簡單並且能快速計算;(2)能在地址中獲取鍵的均部分。
4.構造雜湊函式的幾種常見方法:
(1)平均取中法:具體做法是先通過關鍵字的平方值擴大相近數的差別,然後根據表長度取中間的幾位數作為雜湊值。
例如:將一組關鍵字(0100,0110,1010,1001,0111)平方後得(0010000,0012100,1020100,1002001,0012321)若取表長為1000,則可取中間的三位數作為雜湊地址集:(100121,201,020,123)。
(2)除餘法:用關鍵字除以一個不大於雜湊表長度
(3)摺疊法:根據雜湊表長將關鍵字儘可能分成若干段,然後將這幾段的值相加,並將最高位的進位捨去,所得結果即為其雜湊地址。
例如:有一組關鍵字(4766934, 5656975, 4685673, 3547807,7569664),將這些數拆成2位,4位和1位數,然後再把它們相加,如下圖:
4.解決雜湊衝突
4.1開放定址法:當衝突發生時,按照某種方法探測表中的其他儲存單元,直到找到空位置為止。
(1)線性探測法:
(2)二次探查法:
(3)雙重雜湊法 : 一旦發生衝突, 應用第二個雜湊函式以獲取備用位置。
4.2連結串列法:將所有關鍵字為同義詞的結點連結在同一個單鏈表中。
5.雜湊查詢的
“`Java
/**
* 雜湊查詢的演算法的實現
*
* {1,3,66,56,34,67,343,77,31,64,0,5,6,32,55,23,56}採用雜湊表存放 用除餘法構建雜湊函式 用連結串列法解決雜湊衝突
*
* @author zww
*
*/
public class HashTableSearch {
/* 雜湊結點 */
private static class Node {
int key; // 連結串列中的鍵
Node next; // 下一個同義詞
}
/* 在雜湊表中查詢關鍵字key */
public boolean HashSearch(int[] data, int key) {
int p = 1;
// 尋找小於或等於最接近表長的素數
for (int i = data.length; i > 1; i--) {
if (isPrimes(i)) {
p = i;
break;
}
}
// 構建雜湊表
Node[] hashtable = createHashTable(data, p);
// 查詢key是否在雜湊表中
int k = key % p;
Node cur = hashtable[k];
while (cur != null && cur.key != key) {
cur = cur.next;
}
if (cur == null) {
return false;
} else {
return true;
}
}
/*用求餘,連結串列法構建雜湊表*/
public Node[] createHashTable(int[] data, int p) {
Node[] hashtable = new Node[p];
int k; //雜湊函式計算的單元地址
for (int i = 0; i < data.length; i++) {
Node node = new Node();
node.key = data[i];
k = data[i] % p;
if (hashtable[k] == null) {
hashtable[k] = node;
}else {
Node current = hashtable[k];
while(current.next != null) {
current = current.next;
}
current.next = node;
}
}
return hashtable;
}
public boolean isPrimes(int n) {
for(int i = 2; i <= Math.sqrt(n); i++ ) {
if (n % i == 0) {
return false;
}
}
return true;
}
}
“`