在维基百科中 hash 的解释为:
散列函数(或散列算法,英语:Hash Function)是一种从任何一种数据中创建小的数字“指纹”的方法。该函数将数据打乱混合,重新创建一个叫做散列值的指纹。散列值通常用来代表一个短的随机字母和数字组成的字符串。好的散列函数在输入域中很少出现散列冲突。在散列表和数据处理中,不抑制冲突来区别数据,会使得数据库记录更难找到。
这里所指“指纹”是指:通过一个唯一的“量”(如:一个object的物理地址的指针值),在二叉树中快速的查找到相对应的变量。
具体代码:
THashTable.hpp
1
#ifndef _HASHTABLE_HPP_
2
#define
_HASHTABLE_HPP_
3
4
#include
"
FoundationLIB.hpp
"
5
6
#include
"
System.hpp
"
7
8
/**/
/*
9
* 利用hash函数 实现对链表的访问运算量达到和数组访问相当的效率
10
*/
11
namespace
PX2
12
{
13
/**//// 哈希表模板类
14
template<class TKEY, class TVALUE>
15
class THashTable
16
{
17
public:
18
THashTable ( int iTableSize );
19
~THashTable ();
20
21
int GetQuantity () const;
22
23
bool Insert ( const TKEY& rtKey, const TVALUE& rtValue );
24
25
TVALUE* Find ( const TKEY& rtKey ) const;
26
27
bool Remove ( const TKEY& rtKey );
28
void RemoveAll ();
29
30
TVALUE* GetFirst ( TKEY* ptKey ) const;
31
TVALUE* GetNext ( TKEY* ptKey ) const;
32
33
int (*UserHashFunction) ( const TKEY& );
34
35
private:
36
class HashItem
37
{
38
public:
39
TKEY m_tKey;
40
TVALUE m_tValue;
41
HashItem* m_pkNext;
42
};
43
44
int HashFunction ( const TKEY& rtKey ) const;
45
46
int m_iTableSize;
47
int m_iQuantity;
48
HashItem** m_apkTable;
49
50
mutable int m_iIndex;
51
mutable HashItem* m_pkItem;
52
};
53
54
#include "THashTable.inl"
55
}
56
#endif
//
_HASHTABLE_HPP_

2

3

4

5

6

7

8


9

10

11

12



13


14

15

16



17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37



38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

THashTable.inl
1
template
<
class
TKEY,
class
TVALUE
>
2
THashTable
<
TKEY, TVALUE
>
::THashTable(
int
iTableSize )
3
{
4
assert( iTableSize > 0);
5
6
m_iTableSize = iTableSize;
7
m_iQuantity = 0;
8
m_iIndex = 0;
9
m_pkItem = 0;
10
m_apkTable = NEW HashItem*[m_iTableSize];
11
12
memset(m_apkTable, 0, m_iTableSize * sizeof(HashItem*));
13
UserHashFunction = 0;
14
}
15
//
-------------------------------------------------------------------------------
16
template
<
class
TKEY,
class
TVALUE
>
17
THashTable
<
TKEY, TVALUE
>
::
~
THashTable()
18
{
19
RemoveAll();
20
DELETE [] m_apkTable;
21
}
22
//
-------------------------------------------------------------------------------
23
template
<
class
TKEY,
class
TVALUE
>
24
int
THashTable
<
TKEY, TVALUE
>
::GetQuantity ()
const
25
{
26
return m_iQuantity;
27
}
28
//
-------------------------------------------------------------------------------
29
template
<
class
TKEY,
class
TVALUE
>
30
bool
THashTable
<
TKEY, TVALUE
>
::Insert(
const
TKEY
&
rtKey,
31
const
TVALUE
&
rtValue )
32
{
33
int iIndex = HashFunction( rtKey );
34
HashItem* pkItem = m_apkTable[iIndex];
35
36
while (pkItem)
37
{
38
if (rtKey == pkItem->m_tKey)
39
{
40
return false;
41
}
42
43
pkItem = pkItem->m_pkNext;
44
}
45
46
pkItem = NEW HashItem;
47
pkItem->m_tKey = rtKey;
48
pkItem->m_tValue = rtValue;
49
pkItem->m_pkNext = m_apkTable[iIndex];
50
m_apkTable[iIndex] = pkItem;
51
++m_iQuantity;
52
53
return true;
54
}
55
//
-------------------------------------------------------------------------------
56
template
<
class
TKEY,
class
TVALUE
>
57
TVALUE
*
THashTable
<
TKEY, TVALUE
>
::Find(
const
TKEY
&
rtKey )
const
58
{
59
60
int iIndex = HashFunction( rtKey );
61
HashItem* pkItem = m_apkTable[iIndex];
62
63
while( pkItem )
64
{
65
if (rtKey == pkItem->m_tKey )
66
{
67
return &pkItem->m_tValue;
68
}
69
70
pkItem = pkItem->m_pkNext;
71
}
72
return 0;
73
}
74
//
-------------------------------------------------------------------------------
75
template
<
class
TKEY,
class
TVALUE
>
76
bool
THashTable
<
TKEY, TVALUE
>
::Remove (
const
TKEY
&
rtKey)
77
{
78
int iIndex = HashFunction( rtKey );
79
HashItem* pkItem = m_apkTable[iIndex];
80
81
if (!pkItem)
82
{
83
return false;
84
}
85
86
if (rtKey == pkItem->m_tKey)
87
{
88
HashItem* pkSave = pkItem;
89
m_apkTable[iIndex] = pkItem->m_pkNext;
90
DELETE pkSave;
91
--m_iQuantity;
92
93
return true;
94
}
95
96
HashItem* pkPrev = pkItem;
97
HashItem* pkCurr = pkItem->m_pkNext;
98
while ( pkPrev && rtKey != pkCurr->m_tKey)
99
{
100
pkPrev = pkCurr;
101
pkCurr = pkCurr->m_pkNext;
102
}
103
104
if (pkCurr)
105
{
106
pkPrev->m_pkNext = pkCurr->m_pkNext;
107
DELETE pkCurr;
108
m_iQuantity--;
109
return true;
110
}
111
112
return false;
113
}
114
//
-------------------------------------------------------------------------------
115
template
<
class
TKEY,
class
TVALUE
>
116
void
THashTable
<
TKEY,TVALUE
>
::RemoveAll ()
117
{
118
if (m_iQuantity > 0)
119
{
120
for (int iIndex = 0; iIndex < m_iTableSize; iIndex++)
121
{
122
while (m_apkTable[iIndex])
123
{
124
HashItem* pkSave = m_apkTable[iIndex];
125
m_apkTable[iIndex] = m_apkTable[iIndex]->m_pkNext;
126
DELETE pkSave;
127
if (--m_iQuantity == 0)
128
{
129
return;
130
}
131
}
132
}
133
}
134
}
135
//
-------------------------------------------------------------------------------
136
template
<
class
TKEY,
class
TVALUE
>
137
TVALUE
*
THashTable
<
TKEY,TVALUE
>
::GetFirst ( TKEY
*
ptKey )
const
138
{
139
if (m_iQuantity > 0)
140
{
141
for (m_iIndex = 0; m_iIndex < m_iTableSize; m_iIndex++)
142
{
143
if (m_apkTable[m_iIndex])
144
{
145
m_pkItem = m_apkTable[m_iIndex];
146
*ptKey = m_pkItem->m_tKey;
147
return &m_pkItem->m_tValue;
148
}
149
}
150
}
151
152
return 0;
153
}
154
//
-------------------------------------------------------------------------------
155
template
<
class
TKEY,
class
TVALUE
>
156
TVALUE
*
THashTable
<
TKEY,TVALUE
>
::GetNext ( TKEY
*
ptKey )
const
157
{
158
if (m_iQuantity > 0)
159
{
160
m_pkItem = m_pkItem->m_pkNext;
161
if (m_pkItem)
162
{
163
*ptKey = m_pkItem->m_tKey;
164
return &m_pkItem->m_tValue;
165
}
166
167
for (m_iIndex++; m_iIndex < m_iTableSize; m_iIndex++)
168
{
169
if (m_apkTable[m_iIndex])
170
{
171
m_pkItem = m_apkTable[m_iIndex];
172
*ptKey = m_pkItem->m_tKey;
173
return &m_pkItem->m_tValue;
174
}
175
}
176
}
177
178
return 0;
179
}
180
//
-------------------------------------------------------------------------------
181
template
<
class
TKEY,
class
TVALUE
>
182
int
THashTable
<
TKEY,TVALUE
>
::HashFunction (
const
TKEY
&
rtKey)
const
183
{
184
if (UserHashFunction)
185
{
186
return (*UserHashFunction)(rtKey);
187
}
188
189
// 默认Hash 函数 采用黄金分割
190
static double s_dHashMultiplier = 0.5*(sqrt(5.0)-1.0);
191
unsigned int uiKey;
192
System::Memcpy(&uiKey, sizeof(unsigned int), &rtKey, sizeof(unsigned int));
193
uiKey %= m_iTableSize;
194
double dFraction = fmod(s_dHashMultiplier*uiKey,1.0);
195
return (int)floor(m_iTableSize*dFraction);
196
}
197
//
-------------------------------------------------------------------------------
198
199
//
end

2

3



4

5

6

7

8

9

10

11

12

13

14

15

16

17

18



19

20

21

22

23

24

25



26

27

28

29

30

31

32



33

34

35

36

37



38

39



40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58



59

60

61

62

63

64



65

66



67

68

69

70

71

72

73

74

75

76

77



78

79

80

81

82



83

84

85

86

87



88

89

90

91

92

93

94

95

96

97

98

99



100

101

102

103

104

105



106

107

108

109

110

111

112

113

114

115

116

117



118

119



120

121



122

123



124

125

126

127

128



129

130

131

132

133

134

135

136

137

138



139

140



141

142



143

144



145

146

147

148

149

150

151

152

153

154

155

156

157



158

159



160

161

162



163

164

165

166

167

168



169

170



171

172

173

174

175

176

177

178

179

180

181

182

183



184

185



186

187

188

189

190

191

192

193

194

195

196

197

198

199
