【轉載】一步一步寫演算法(之hash表)

摩斯電碼發表於2013-07-19

轉載自:http://blog.csdn.net/feixiaoxing/article/details/6885657

 

【 宣告:版權所有,歡迎轉載,請勿用於商業用途。  聯絡信箱:feixiaoxing @163.com】


    hash表,有時候也被稱為雜湊表。個人認為,hash表是介於連結串列和二叉樹之間的一種中間結構。連結串列使用十分方便,但是資料查詢十分麻煩;二叉樹中的 資料嚴格有序,但是這是以多一個指標作為代價的結果。hash表既滿足了資料的查詢方便,同時不佔用太多的內容空間,使用也十分方便。

    打個比方來說,所有的資料就好像許許多多的書本。如果這些書本是一本一本堆起來的,就好像連結串列或者線性表一樣,整個資料會顯得非常的無序和凌亂,在你找 到自己需要的書之前,你要經歷許多的查詢過程;而如果你對所有的書本進行編號,並且把這些書本按次序進行排列的話,那麼如果你要尋找的書本編號是n,那麼 經過二分查詢,你很快就會找到自己需要的書本;但是如果你每一個種類的書本都不是很多,那麼你就可以對這些書本進行歸類,哪些是文學類,哪些是藝術類,哪 些是工科的,哪些是理科的,你只要對這些書本進行簡單的歸類,那麼尋找一本書也會變得非常簡單,比如說如果你要找的書是計算機方面的書,那麼你就會到工科 一類當中去尋找,這樣查詢起來也會顯得麻煩。

    不知道這樣舉例你清楚了沒有,上面提到的歸類方法其實就是hash表的本質。下面我們可以寫一個簡單的hash操作程式碼。

    a)定義hash表和基本資料節點

  1. typedef struct _NODE  
  2. {  
  3.     int data;  
  4.     struct _NODE* next;  
  5. }NODE;  
  6.   
  7. typedef struct _HASH_TABLE  
  8. {  
  9.     NODE* value[10];  
  10. }HASH_TABLE;  

    b)建立hash表
  1. HASH_TABLE* create_hash_table()  
  2. {  
  3.     HASH_TABLE* pHashTbl = (HASH_TABLE*)malloc(sizeof(HASH_TABLE));  
  4.     memset(pHashTbl, 0, sizeof(HASH_TABLE));  
  5.     return pHashTbl;  
  6. }  

    c)在hash表當中尋找資料
  1. NODE* find_data_in_hash(HASH_TABLE* pHashTbl, int data)  
  2. {  
  3.     NODE* pNode;  
  4.     if(NULL ==  pHashTbl)  
  5.         return NULL;  
  6.   
  7.     if(NULL == (pNode = pHashTbl->value[data % 10]))  
  8.         return NULL;  
  9.   
  10.     while(pNode){  
  11.         if(data == pNode->data)  
  12.             return pNode;  
  13.         pNode = pNode->next;  
  14.     }  
  15.     return NULL;  
  16. }  

    d)在hash表當中插入資料
  1. STATUS insert_data_into_hash(HASH_TABLE* pHashTbl, int data)  
  2. {  
  3.     NODE* pNode;  
  4.     if(NULL == pHashTbl)  
  5.         return FALSE;  
  6.   
  7.     if(NULL == pHashTbl->value[data % 10]){  
  8.         pNode = (NODE*)malloc(sizeof(NODE));  
  9.         memset(pNode, 0, sizeof(NODE));  
  10.         pNode->data = data;  
  11.         pHashTbl->value[data % 10] = pNode;  
  12.         return TRUE;  
  13.     }  
  14.   
  15.     if(NULL != find_data_in_hash(pHashTbl, data))  
  16.         return FALSE;  
  17.   
  18.     pNode = pHashTbl->value[data % 10];  
  19.     while(NULL != pNode->next)  
  20.         pNode = pNode->next;  
  21.   
  22.     pNode->next = (NODE*)malloc(sizeof(NODE));  
  23.     memset(pNode->next, 0, sizeof(NODE));  
  24.     pNode->next->data = data;  
  25.     return TRUE;  
  26. }  

    e)從hash表中刪除資料
  1. STATUS delete_data_from_hash(HASH_TABLE* pHashTbl, int data)  
  2. {  
  3.     NODE* pHead;  
  4.     NODE* pNode;  
  5.     if(NULL == pHashTbl || NULL == pHashTbl->value[data % 10])  
  6.         return FALSE;  
  7.   
  8.     if(NULL == (pNode = find_data_in_hash(pHashTbl, data)))  
  9.         return FALSE;  
  10.   
  11.     if(pNode == pHashTbl->value[data % 10]){  
  12.         pHashTbl->value[data % 10] = pNode->next;  
  13.         goto final;  
  14.     }  
  15.   
  16.     pHead = pHashTbl->value[data % 10];  
  17.     while(pNode != pHead ->next)  
  18.         pHead = pHead->next;  
  19.     pHead->next = pNode->next;  
  20.   
  21. final:  
  22.     free(pNode);  
  23.     return TRUE;  
  24. }  

總結:

    1、hash表不復雜,我們在開發中也經常使用,建議朋友們好好掌握;

    2、hash表可以和二叉樹形成複合結構,至於為什麼,建議朋友們好好思考一下?


相關文章