异常类 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.