异常类 myExceptions 同 数据结构C++(1)线性表——数组实现(arrayList) 。
抽象类 dictionary 的定义同 数据结构C++(8)字典——链表实现(linkDictionary)。
类 pairNode, linkDictionary 的定义同数据结构C++(8)字典——链表实现(linkDictionary)。
类 Hash 的作用是,根据键值“key”得到对应的哈希起始位置(散列函数)。
*** 原书代码中定义的类名为 hash ,会与STL中hash<T> 冲突,因此定义为 Hash,实现代码在 hash.h 中:
1 #pragma once
2
3 #include <iostream>
4 #include <string>
5 #include <functional>
6
7 template <class K> class Hash; 8
9 template<>
10 class Hash<std::string>
11 { 12 public: 13 size_t operator()(const std::string theKey) const
14 { 15 unsigned long hashValue = 0; 16 int length = (int)theKey.length(); 17
18 for (int i = 0; i < length; i++) 19 hashValue = 5 * hashValue + theKey.at(i); 20
21 return size_t(hashValue); 22 } 23 }; 24
25 template<>
26 class Hash<int>
27 { 28 public: 29 size_t operator()(const int theKey) const
30 { 31 return size_t(theKey); 32 } 33 }; 34
35 template<>
36 class Hash<long>
37 { 38 public: 39 size_t operator()(const long theKey) const
40 { 41 return size_t(theKey); 42 } 43 };
类 linkHash 的定义在 linkHash.h 中:
1 #pragma once
2 #include <iostream>
3 #include <ostream>
4 #include <string>
5 #include "hash.h"
6 #include "dictionary.h"
7 #include "linkDictionary.h"
8 #include "myExceptions.h"
9
10
11 template<typename K, typename V>
12 class linkHash : public dictionary<K, V>
13 { 14 public: 15 linkHash(int theDivisor = 11) 16 { 17 divisor = theDivisor; 18 hashSize = 0; 19 hashTable = new linkDictionary<K, V>*[divisor]; 20 for (int i = 0; i < divisor; i++) 21 hashTable[i] = nullptr; 22 } 23 ~linkHash(); 24 bool empty() const; 25 int size() const; 26 std::pair<const K, V>* find(const K &theKey) const; //查找键为key的数对
27 void erase(const K &theKey); 28 void insert(const std::pair<const K, V>& thePair) ; 29
30 void output(std::ostream &out); 31 protected: 32 linkDictionary<K, V> **hashTable; 33 int hashSize; //哈希表中数对的数量
34 int divisor; //除法散列函数的除数
35 Hash<K> Hash; //映射
36 }; 37
38 template<typename K, typename V>
39 linkHash<K, V>::~linkHash() 40 { 41 for (int i = 0; i < divisor; i++) 42 { 43 if (hashTable[i] != nullptr) 44 delete hashTable[i]; 45 } 46 delete[]hashTable; 47 } 48
49 template<typename K, typename V>
50 bool linkHash<K, V>::empty() const
51 { 52 return hashSize == 0; 53 } 54
55 template<typename K, typename V>
56 int linkHash<K, V>::size() const
57 { 58 return hashSize; 59 } 60
61 template<typename K, typename V>
62 std::pair<const K, V>* linkHash<K, V>::find(const K &theKey) const //查找键为key的数对
63 { 64 return hashTable[Hash(theKey) % divisor]->find(theKey); 65 } 66
67 template<typename K, typename V>
68 void linkHash<K, V>::erase(const K &theKey) 69 { 70 hashTable[Hash(theKey) % divisor]->erase(theKey); 71 } 72
73 template<typename K, typename V>
74 void linkHash<K, V>::insert(const std::pair<const K, V>& thePair) 75 { 76 int homeBucket = (int)Hash(thePair.first) % divisor; 77 if (hashTable[homeBucket] == nullptr) 78 { 79 linkDictionary<K, V> *New = new linkDictionary<K, V>; 80 New->insert(thePair); 81 hashTable[homeBucket] = New; 82 hashSize++; 83 } 84 else
85 { 86 int homeSize = hashTable[homeBucket]->size(); 87 hashTable[homeBucket]->insert(thePair); 88 if (hashTable[homeBucket]->size() > homeSize) 89 hashSize++; 90 } 91 } 92
93 template<typename K, typename V>
94 void linkHash<K, V>::output(std::ostream &out) 95 { 96 for (int i = 0; i < divisor; i++) 97 { 98 linkDictionary<K, V> *Tmp = hashTable[i]; 99 out << "hashTable[" << i << "]:"; 100 if (Tmp != nullptr) 101 Tmp->output(out); 102 out << std::endl; 103 } 104 } 105
106 template<typename K, typename V>
107 std::ostream &operator<<(std::ostream &out, linkHash<K, V> &cLinkHash) 108 { 109 cLinkHash.output(out); 110 return out; 111 }
参考文献:
[1].Sartaj Sahni. 数据结构、算法与应用[M]. 机械工业出版社, 2000.