鏈地址法也成為拉鏈法。
其基本思路是:將全部具有同樣哈希地址的而不同keyword的數據元素連接到同一個單鏈表中。假設選定的哈希表長度為m,則可將哈希表定義為一個有m個頭指針組成的指針數組T[0..m-1]。凡是哈希地址為i的數據元素,均以節點的形式插入到T[i]為頭指針的單鏈表中。而且新的元素插入到鏈表的前端,這不僅由於方便。還由於常常發生這種事實:新近插入的元素最優可能不久又被訪問。
鏈地址法特點
(1)拉鏈法處理沖突簡單。且無堆積現象,即非同義詞決不會發生沖突,因此平均查找長度較短;
(2)因為拉鏈法中各鏈表上的結點空間是動態申請的。故它更適合於造表前無法確定表長的情況。
(3)開放定址法為降低沖突。要求裝填因子α較小。故當結點規模較大時會浪費非常多空間。而拉鏈法中可取α≥1,且結點較大時,拉鏈法中添加的指針域可忽略不計,因此節省空間;
(4)在用拉鏈法構造的散列表中,刪除結點的操作易於實現。僅僅要簡單地刪去鏈表上對應的結點就可以。而對開放地址法構造的散列表,刪除結點不能簡單地將被刪結點的空間置為空,否則將截斷在它之后填人散列表的同義詞結點的查找路徑。這是由於各種開放地址法中,空地址單元(即開放地址)都是查找失敗的條件。
因此在用開放地址法處理沖突的散列表上運行刪除操作。僅僅能在被刪結點上做刪除標記,而不能真正刪除結點。
下面簡單的對hash表中數據存儲進行實現,功能主要包括將數組元素存儲在hash表中
用兩個結點分別記錄key值元素與目標數組元素,數據結構定義為
// 存儲目標數組中元素的結點 typedef struct ArcNode{ int data; // 元素值 struct ArcNode * Next; }ArcNode, *pArcNode; // 存儲hash鏈key值數組的結點 typedef struct RouNode{ int key; // key值 ArcNode * link; }RouNode, *pRouNode;
代碼具體執行結果如下
key of the node is 0, the hash number:55 11 key of the node is 1, the hash number:1 23 key of the node is 2, the hash number:68 key of the node is 3, the hash number:14 key of the node is 4, the hash number:37 key of the node is 5, the hash number: key of the node is 6, the hash number: key of the node is 7, the hash number: key of the node is 8, the hash number:19 key of the node is 9, the hash number:86 key of the node is 10, the hash number:
代碼執行結果圖示如下
完整代碼

// hash link+array // 鏈地址法實現 # include <stdio.h> # include <stdlib.h> # define NUM 11 // 表示 hash 鏈的長度 # define Maxsize 9 // 表示需要hash處理數組的長度 // 存儲目標數組中元素的結點 typedef struct ArcNode{ int data; // 元素值 struct ArcNode * Next; }ArcNode, *pArcNode; // 存儲hash鏈key值數組的結點 typedef struct RouNode{ int key; // key值 ArcNode * link; }RouNode, *pRouNode; pRouNode creat_Array(int num); // 創建hash表中key值數組,並初始化指針域為空 pArcNode creat_node(int val); // 創建一個無連接的新結點,並將數組元素保存在結點中 void traverse_node(pRouNode Array); // 遍歷整個hash鏈表 int get_key(int val); // 計算數組元素的key值 pRouNode link_node(pRouNode Array, int val); // 對某個單一的數值進行hash處理 pRouNode link_array(pRouNode Array, int A[]); // 將整個數組依次進行hash int main(void) { int A[Maxsize] = {1,55,14,19,23,37,11,68,86}; pRouNode Array = creat_Array(NUM); link_array(Array, A); traverse_node(Array); return 0; } pRouNode creat_Array(int num) { int i; pRouNode Array = (pRouNode)malloc(sizeof(RouNode)*num); for (i=0; i<NUM; i++) { Array[i].key = i; Array[i].link = NULL; } return Array; } pArcNode creat_node(int val) { pArcNode NODE = (pArcNode)malloc(sizeof(ArcNode)); NODE->data = val; NODE->Next = NULL; return NODE; } void traverse_node(pRouNode Array) { int i; for (i=0; i<NUM; i++) { printf("key of the node is %d, the hash number:",Array[i].key); pArcNode pNew = Array[i].link; while (NULL != pNew) { printf("%d ",pNew->data); pNew = pNew->Next; } printf("\n"); } return ; } int get_key(int val) // 計算數組元素的 key值 { return val%NUM; } pRouNode link_node(pRouNode Array, int val) { if (NULL != Array[get_key(val)].link) { pArcNode pNew = Array[get_key(val)].link; while (NULL != pNew->Next) { pNew = pNew->Next; } pNew->Next = creat_node(val); } else { pArcNode pNew = creat_node(val); Array[get_key(val)].link = pNew; } return Array; } pRouNode link_array(pRouNode Array, int A[]) { int i = 0; for (i; i<Maxsize; i++) { link_node(Array, A[i]); } return Array; }
RRR