【算法與數據結構】哈希表-鏈地址法


哈希表的鏈地址法來解決沖突問題

將所有關鍵字為同義詞的記錄存儲在同一個線性鏈表中,假設某哈希函數產生的哈希地址在區間[0, m - 1]上,則設立一個至振興向量

Chain  ChainHash[m];

 

數據結構

//鏈表結點
typedef struct _tagNode { int data;              //元素值(關鍵字)
    struct _tagNode* next; //下一個結點
}Node, *PNode; //哈希表結點
typedef struct _tagHashTable { //這里用一個聯合體來解釋一下,其index也即哈希值
 union{ int index;            //哈希表index(這里也是哈希值)
        int nHashValue;       //也即哈希值
 }INDEX; Node* firstChild;     //該哈希結點在第一個子節點,即哈希值為該結點INDEX字段的
    struct _tagHashTable* next; //指向下一個哈希結點
}HashTable, *PHashTable;

 

 

 構造哈希表,輸入為頭結點指針的引用

//pHashTable 哈希表頭結點 //length 哈希表長度 //pArr 關鍵字元素數組 //nums 關鍵字元素數組長度
void CreateHashTable(PHashTable& pHashTable, int length, int* pArr, int nums) { pHashTable = new HashTable(); if(NULL == pHashTable) { cerr << "Create Hashtable error! \n"; return;} pHashTable->firstChild = NULL; pHashTable->INDEX = 0; pHashTable->next = NULL; PHashTable pTemp = pHashTable; for (int i = 1; i < length; ++ i) { PHashTable pt = new HashTable(); if(NULL == pt) {cerr << "Create Hahstable error ! \n"; return;} pt->firstChild = NULL; pt->INDEX = i; pt->next = NULL; pTemp->next = pt; pTemp = pt; } //for //Hash(key) = key MOD length;
    for(int i = 0; i < nums; ++ i) { //計算哈希值
        int nHashValue = pArr[i] % length; PHashTable pTemp2 = NULL; if(NULL != (pTemp2 = LocateHashNode(pHashTable, nHashValue)) ) { Insert(pTemp2, pArr[i]); } else { cerr << "元素值為 "<< pArr[i]<< " 的元素,哈希值為 "<< nHashValue<< ", 查找其所在哈希結點失敗"<<endl; } } }

 

 

 

 向某個哈希表結點(不一定是頭結點)中插入元素

//將關鍵字插入所在的pHashtable結點的鏈表 //返回其在該鏈表上的位置(下標從1開始)
int Insert(PHashTable& pHashtable, int data) { if(NULL == pHashtable){cerr << "當前哈希表結點為空 \r\n"; return -1;} int nIndex = 1; PNode pNewNode = new Node(); if(NULL == pNewNode){cerr << "建立新鏈表結點失敗"<<endl; return -1;} pNewNode->data = data; pNewNode->next = NULL; PNode pNode = pHashtable->firstChild; if (NULL == pNode) { pHashtable->firstChild = pNewNode; } else { while(pNode->next != NULL) { ++ nIndex; pNode = pNode->next; } ++nIndex; pNode->next = pNewNode; } cout << "元素 "<< data << " 插入在了哈希表結點 "<< pHashtable->INDEX<< " 的第 "<< nIndex<< " 個位置"<<endl; return nIndex; }

 

 

 

 根據哈希值,返回其所在結點的指針,輸入為表示該哈希表的頭結點指針的引用

//根據哈希值,返回該值應該所在的哈希表結點指針 //pHashtable 哈希表頭結點 //nHashValue 元素的哈希值
PHashTable LocateHashNode(PHashTable& pHashtable, int nHashValue) { if(NULL == pHashtable) {cerr << "哈希表頭結點為空"<<endl; return NULL;} PHashTable pTemp = pHashtable; do { if (pTemp->INDEX == nHashValue) return pTemp; pTemp = pTemp->next; } while (pTemp != NULL); return NULL; }

 

 

 

 從頭結點為pHashtable的哈希表中,查找關鍵字為data,哈希值為nHashValue的元素

在哈希表中的位置,返回值為在該哈希結點的鏈表中的位置(下標從1開始)

    
//查找頭結點為pHashtable的哈希表 //其數據為data,哈希值為nHashValue的元素 //在哈希表某個結點的鏈表中的位置(下標從1開始)
int Find(PHashTable& pHashtable, int data, int nHashValue) { if(NULL == pHashtable){cerr << "哈希表頭結點為空"<<endl; return -1;} PHashTable pHashNode = LocateHashNode(pHashtable, nHashValue); if(NULL == pHashNode) {cerr << "找不到元素 " << data << " ,其哈希值為 "<<nHashValue<< " 在哈希表中的位置"; return -1;} int nINDEX = 1; PNode pNode = pHashNode->firstChild; if (NULL == pNode) { {cerr << "找不到元素 " << data << " ,其哈希值為 "<<nHashValue<< " 在哈希表中的位置"; return -1;} } else { bool b = false; while(pNode != NULL) { if(pNode->data == data) { b = true; break; } ++ nINDEX; pNode = pNode->next; } if (false == b) { cerr << "找不到元素 " << data << " ,其哈希值為 "<<nHashValue<< " 在哈希表中的位置"; return -1; } else { cout << "元素 "<< data << " 插入在了哈希表結點 "<< pHashNode->INDEX<< " 的第 "<< nINDEX<< " 個位置"<<endl; } } return nINDEX; }

 

  

 

int _tmain(int argc, _TCHAR* argv[]) { PHashTable pHashtable = NULL; int length = 0; int nums = 0; cout <<endl<< "請輸入元素個數:"; cin >> nums; int* pArr = new int[nums](); if(NULL == pArr) {cerr<<"申請元素空間錯誤"; return -1;} ZeroMemory(pArr, sizeof(int) * nums); for (int i = 0; i < nums; ++ i) { int data = 0; cout << "請輸入第 "<< i << " 個元素的值:"; cin >> data; pArr[i] = data; } cout << endl<<"輸入完畢"<<endl; cout << "請輸入哈希表長度:"; cin >> length; cout << endl <<endl <<"開始構造哈希表"<<endl; CreateHashTable(pHashtable, length, pArr, nums); cout <<endl<<"哈希表構造完畢"<<endl<<endl; cout<<endl<<endl; int value = 0; for (int i = 0; i < nums * 10; ++ i) { cout << "請輸入要查查找的元素:"; cin >> value; Find(pHashtable, value, value % length); cout<<endl; } return 0; }

 

 

 

 

 

 

 

 

  


免責聲明!

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



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