簡述:
考慮到有大量數(shù)據(jù)的情況,所以使用Hash表
使用泛型實現(xiàn)
TypeA 是Key的類型,TypeB 是value的類型
1. 主要函數(shù)
1). TypeB Put(HashNode<TypeA,TypeB> 函數(shù)用來加入一個新的MapNode
2). TypeB Delete(const TypeA& key) 用來刪除一個鍵值為key的節(jié)點
3). TypeB GetValue(const  TypeA& key) 通過key值來搜尋他的value
2. 主要算法
1) 使用一個函數(shù)類型指向用戶定義的哈希值計算函數(shù),這里我用了GetKeyValue_1這個平方取中法
2)使用鏈式法解決沖突,首先是一個節(jié)點指針數(shù)組,table[index] ,其中index是哈希函數(shù)計算出來的
如果由于鍵值傳入哈希函數(shù)后計算出同一個index值,那么就以table[index]為頭節(jié)點,橫向建立鏈表避免沖突
3.類實現(xiàn)以及測試代碼
HashMap.cpp
-   
-   
-   
-   
- #include <iostream>  
- #include <string>  
- #include <cstring>  
- #include <stdlib.h>  
- #include <time.h>  
-   
- using namespace std;  
-   
- typedef unsigned long(*GetKeyValue)(const string& );  
-   
-   
- template<class TypeA,class TypeB>  
- struct HashNode{  
-     TypeA key;  
-     TypeB value;  
-     HashNode *next;  
-     HashNode(TypeA key,TypeB value){  
-         HashNode::key = key;  
-         HashNode::value = value;  
-         next = NULL;  
-     }  
-     HashNode& operator=(const HashNode& node){  
-         key = node.key;  
-         value = node.key;  
-         next = node.next;  
-         return *this;  
-     }  
- };  
-   
-   
-   
- template<class TypeA,class TypeB,class FuncType>  
- class HashMap{  
-     HashNode<TypeA,TypeB> **table;  
-     unsigned long capacity;  
-     FuncType GetKeyValue;  
-     const TypeB TYPEB_NULL;  
- public:  
-     HashMap(FuncType func,const TypeB& _null);  
-     ~HashMap();  
-     TypeB Put(const HashNode<TypeA,TypeB>& hashNode);    
-     TypeB GetValue(const TypeA& key);    
-     TypeB Delete(const TypeA& key);    
- };  
-   
-   
- template<class TypeA,class TypeB,class FuncType>   
- HashMap<TypeA,TypeB,FuncType>::HashMap(FuncType func,const TypeB& _null) : TYPEB_NULL(_null){  
-     capacity = 10000000;  
-     GetKeyValue = func;  
-     table = new HashNode<TypeA,TypeB>*[capacity];  
-     for(unsigned i = 0;i < capacity;i++)  
-         table[i] = NULL;  
- }  
-   
-   
- template<class TypeA,class TypeB,class FuncType>  
- HashMap<TypeA,TypeB,FuncType>::~HashMap(){  
-     for(unsigned i = 0;i < capacity;i++){  
-         HashNode<TypeA,TypeB> *currentNode = table[i];  
-         while(currentNode){  
-             HashNode<TypeA,TypeB> *temp = currentNode;  
-             currentNode = currentNode->next;  
-             delete temp;  
-         }  
-     }  
- }  
-   
-   
-   
- template<class TypeA,class TypeB,class FuncType>  
- TypeB HashMap<TypeA,TypeB,FuncType>::Put(const HashNode<TypeA,TypeB>& hashNode){  
-     HashNode<TypeA,TypeB> *newNode = NULL;  
-     unsigned long index = GetKeyValue(hashNode.key);  
-     if(table[index] == NULL){  
-         table[index] = new HashNode<TypeA,TypeB>(hashNode.key,hashNode.value);  
-         newNode = table[index];  
-     }  
-     else{  
-         newNode = table[index];  
-         while(newNode->next){  
-             newNode = newNode->next;  
-         }  
-         newNode->next = new HashNode<TypeA,TypeB>(hashNode.key,hashNode.value);  
-         newNode = newNode->next;  
-     }  
-     return newNode->value;  
- }  
-   
-   
-   
- template<class TypeA,class TypeB,class FuncType>  
- TypeB HashMap<TypeA,TypeB,FuncType>::GetValue(const TypeA& key){  
-     unsigned long index = GetKeyValue(key);  
-     if(table[index] == NULL)  
-         return TYPEB_NULL;  
-     else{  
-         HashNode<TypeA,TypeB> *currentNode = table[index];  
-         while(currentNode){  
-             if(currentNode->key == key)  
-                 return currentNode->value;  
-             currentNode = currentNode->next;  
-         }  
-     }  
-     return TYPEB_NULL;  
- }  
-   
-   
-   
- template<class TypeA,class TypeB,class FuncType>  
- TypeB HashMap<TypeA,TypeB,FuncType>::Delete(const TypeA& key){  
-     TypeB deletedNodeValue = TYPEB_NULL;  
-     unsigned long index = GetKeyValue(key);  
-     if(table[index] == NULL)  
-         return deletedNodeValue;  
-     else{  
-         HashNode<TypeA,TypeB> *currentNode = table[index];  
-         if(currentNode->key == key){  
-             table[index] = currentNode->next;  
-             deletedNodeValue = currentNode->value;  
-             delete currentNode;  
-             return deletedNodeValue;  
-         }  
-         while(currentNode){  
-             if(currentNode->next->key == key){  
-                 HashNode<TypeA,TypeB> *temp = currentNode->next;  
-                 currentNode->next = currentNode->next->next;  
-                 deletedNodeValue = temp->value;  
-                 delete temp;  
-                 return deletedNodeValue;;  
-             }  
-             currentNode = currentNode->next;  
-         }  
-     }  
-     return deletedNodeValue;  
- }  
-   
-   
-   
-   
-   
-   
- unsigned long GetKeyValue_1(const string& key){  
-     unsigned long keyValue = 0;  
-     int strSize = key.size();  
-     string tempStr(key);  
-     for(int i = strSize;i < 3;i++)  
-         tempStr = "0" + tempStr;  
-       
-     if(strSize >= 3){  
-         tempStr[0] = key[strSize / 2 - 1];  
-         tempStr[1] = key[strSize / 2];  
-         tempStr[2] = key[strSize / 2 + 1];  
-     }  
-     tempStr = tempStr.substr(0,3);  
-     unsigned long num = 10000 * (unsigned long)(48);  
-     num += 100 * (unsigned long)(tempStr[1]);  
-     num += (unsigned long)(tempStr[2]);  
-     num *= num;  
-     char *numStr = new char[15];  
-     numStr = itoa(num,numStr,10) ;  
-     int strLen = strlen(numStr);  
-     tempStr = "000000";  
-     for(int i = -2;i < 4;i++)  
-         tempStr[2 + i] = numStr[strLen / 2 + i];  
-     keyValue = atoi(tempStr.c_str());  
-   
-     delete []numStr;  
-     return keyValue;  
- }  
-   
- int main(){  
-     clock_t start = clock();  
-       
-     HashMap<string,string,GetKeyValue> hashMap(GetKeyValue_1,"NULL");  
-     for(int i = 0;i < 100000;i++){  
-         char *ckey = new char[20];  
-         char *cvalue = new char[20];  
-         ckey = itoa(i,ckey,10);  
-         cvalue = itoa(i,cvalue,10);  
-         string key(ckey);  
-         string value(cvalue);  
-         if(i == 67){  
-             key = "67";  
-             value = "hello hash No.67";  
-         }  
-         HashNode<string,string> node1(key,value);  
-           
-         hashMap.Put(node1);  
-   
-   
-   
-     }  
-     clock_t end = clock();  
-     cout << "Test Result: \n";  
-       
-     cout << "插入100000條數(shù)據(jù)耗時: "  
-          << double(end - start) / CLOCKS_PER_SEC << " 秒" << endl;  
-     cout << "hashMap.GetValue(\"67\"): " << hashMap.GetValue("67") << endl;  
-     cout << "hashMap.Delete(\"67\"): " << hashMap.Delete("67") << endl;  
-     cout << "hashMap.GetValue(\"67\"): " << hashMap.GetValue("67") << endl;  
-     return 0;  
- }  
 
測試輸出:
1) 函數(shù)測試
這里選用的是插入一萬條的結(jié)果,測試函數(shù)是否正確。
每次新增、刪除、搜索一個節(jié)點,就輸出該節(jié)點的value值。
發(fā)現(xiàn)index為67的先加入后來成功刪除,就輸出了NULL

2) 性能測試:
插入10萬條數(shù)據(jù)時間:

插入100萬條:

插入1000萬條:
