Skip to content

Commit 19946f1

Browse files
authored
Hash Table by open addressing
1 parent 1276ebe commit 19946f1

File tree

1 file changed

+183
-0
lines changed

1 file changed

+183
-0
lines changed

Diff for: ProbHashTable.h

+183
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
#pragma once
2+
3+
// 开放寻址法 Open addressing
4+
5+
#include <vector>
6+
#include <string>
7+
#include <functional>
8+
#include <algorithm>
9+
10+
using std::vector;
11+
using std::hash;
12+
using std::string;
13+
14+
int nextPrime(int value)
15+
{
16+
int currentValue = value + 1;
17+
while (true)
18+
{
19+
bool flag = true;
20+
for (int i = 2; i * i <= currentValue; ++i)
21+
{
22+
if (currentValue % i == 0)
23+
{
24+
flag = false;
25+
break;
26+
}
27+
}
28+
if (flag)
29+
{
30+
break;
31+
}
32+
++currentValue;
33+
}
34+
return currentValue;
35+
}
36+
37+
38+
template <typename HashObj>
39+
class ProbHashTable
40+
{
41+
public:
42+
explicit ProbHashTable(int size = 101):
43+
array(size)
44+
{
45+
makeEmpty();
46+
}
47+
48+
bool contains(const HashObj& x) const
49+
{
50+
return isActive(findPos(x));
51+
}
52+
53+
bool insert(const HashObj& x)
54+
{
55+
int pos = findPos(x);
56+
if (isActive(pos)) return false;
57+
58+
array[pos].element = x;
59+
array[pos].type = ACTIVE;
60+
61+
if (++currentSize > array.size() / 2)
62+
{
63+
rehash();
64+
}
65+
return true;
66+
}
67+
68+
bool insert(HashObj&& x)
69+
{
70+
int pos = findPos(x);
71+
if (isActive(pos)) return false;
72+
73+
array[pos].element = std::move(x);
74+
array[pos].type = ACTIVE;
75+
76+
if (++currentSize > array.size() / 2)
77+
{
78+
rehash();
79+
}
80+
return true;
81+
}
82+
83+
bool remove(const HashObj& x)
84+
{
85+
int pos = findPos(x);
86+
if (!isActive(pos)) return false;
87+
88+
array[pos].type = DELETED;
89+
--currentSize;
90+
return true;
91+
}
92+
93+
void makeEmpty()
94+
{
95+
currentSize = 0;
96+
for (HashEntry& entry : array)
97+
{
98+
entry.type = EMPTY;
99+
}
100+
}
101+
102+
enum EntryType { ACTIVE, EMPTY, DELETED};
103+
104+
private:
105+
106+
struct HashEntry
107+
{
108+
HashObj element;
109+
EntryType type;
110+
111+
HashEntry(const HashObj& e = HashObj{}, EntryType t = EMPTY) :
112+
element{e}, type{t}
113+
{}
114+
115+
HashEntry(HashObj&& e, EntryType t = EMPTY) :
116+
element{ std::move(e) }, type{ t }
117+
{}
118+
};
119+
120+
vector<HashEntry> array;
121+
int currentSize;
122+
123+
bool isActive(int pos) const { return array[pos].type == ACTIVE; }
124+
125+
int findPos(const HashObj& x) const
126+
{
127+
int offset = 1;
128+
int currentPos = myHash(x);
129+
130+
while (array[currentPos].type != EMPTY &&
131+
array[currentPos].element != x)
132+
{
133+
currentPos += offset;
134+
offset += 2;
135+
if (currentPos >= array.size())
136+
{
137+
currentPos -= array.size();
138+
}
139+
}
140+
return currentPos;
141+
}
142+
143+
void rehash()
144+
{
145+
vector<HashEntry> oldArray = array;
146+
array.resize(nextPrime(2 * array.size()));
147+
for (auto& entry : array)
148+
{
149+
entry.type = EMPTY;
150+
}
151+
152+
currentSize = 0;
153+
for (auto& entry : oldArray)
154+
{
155+
if (entry.type == ACTIVE)
156+
{
157+
insert(std::move(entry.element));
158+
}
159+
}
160+
161+
};
162+
163+
size_t myHash(const HashObj& x) const
164+
{
165+
static hash<HashObj> hf;
166+
return hf(x) % array.size();
167+
}
168+
};
169+
170+
template <>
171+
class hash<string>
172+
{
173+
public:
174+
size_t operator()(const string& key)
175+
{
176+
size_t hashVal = 0;
177+
for (char c : key)
178+
{
179+
hashVal = 37 * hashVal + c;
180+
}
181+
return hashVal;
182+
}
183+
};

0 commit comments

Comments
 (0)