利用鏈地址法實現 hash表


鏈地址法也成為拉鏈法。

  其基本思路是:將全部具有同樣哈希地址的而不同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;
}
Total Code

RRR


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM