Skip to content

Commit 1276ebe

Browse files
authored
The implemention of hashTable by separate chaining
1 parent 7618e8f commit 1276ebe

File tree

1 file changed

+155
-0
lines changed

1 file changed

+155
-0
lines changed

HashTable.h

+155
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
#pragma once
2+
3+
// 分离链接法 Separate Chaining
4+
5+
#include <iostream>
6+
#include <vector>
7+
#include <list>
8+
#include <string>
9+
#include <functional>
10+
#include <algorithm>
11+
12+
using std::vector;
13+
using std::list;
14+
using std::hash;
15+
using std::string;
16+
using std::cout;
17+
18+
int nextPrime(int value)
19+
{
20+
int currentValue = value + 1;
21+
while (true)
22+
{
23+
bool flag = true;
24+
for (int i = 2; i * i <= currentValue; ++i)
25+
{
26+
if (currentValue % i == 0)
27+
{
28+
flag = false;
29+
break;
30+
}
31+
}
32+
if (flag)
33+
{
34+
break;
35+
}
36+
++currentValue;
37+
}
38+
return currentValue;
39+
}
40+
41+
template<typename HashedObj>
42+
class HashTable
43+
{
44+
public:
45+
explicit HashTable(int size = 101):
46+
theLists(size, list<HashedObj>())
47+
{}
48+
49+
bool contains(const HashedObj& x) const
50+
{
51+
auto& lt = theLists[myHash(x)];
52+
return std::find(lt.begin(), lt.end(), x) != lt.end();
53+
}
54+
55+
void makeEmpty()
56+
{
57+
for (list<HashedObj>& lt : theLists)
58+
{
59+
lt.clear();
60+
}
61+
}
62+
63+
bool insert(const HashedObj& x)
64+
{
65+
list<HashedObj>& lt = theLists[myHash(x)];
66+
auto itr = std::find(lt.begin(), lt.end(), x);
67+
68+
if (itr != lt.end()) return false; // 已经存在
69+
70+
lt.push_back(x);
71+
72+
// 重新hash
73+
if (++currentSize > theLists.size())
74+
{
75+
rehash();
76+
}
77+
78+
return true;
79+
}
80+
81+
bool insert(HashedObj&& x)
82+
{
83+
list<HashedObj>& lt = theLists[myHash(x)];
84+
auto itr = std::find(lt.begin(), lt.end(), x);
85+
86+
if (itr != lt.end()) return false; // 已经存在
87+
88+
lt.push_back(std::move(x));
89+
90+
// 重新hash
91+
if (++currentSize > theLists.size())
92+
{
93+
rehash();
94+
}
95+
96+
return true;
97+
}
98+
99+
bool remove(const HashedObj& x)
100+
{
101+
list<HashedObj>& lt = theLists[myHash(x)];
102+
auto itr = std::find(lt.begin(), lt.end(), x);
103+
104+
if (itr == lt.end()) return false; // 不存在
105+
106+
lt.erase(itr);
107+
--currentSize;
108+
return true;
109+
}
110+
111+
private:
112+
vector<list<HashedObj>> theLists;
113+
int currentSize;
114+
115+
void rehash()
116+
{
117+
vector<list<HashedObj>> oldLists = theLists;
118+
theLists.resize(nextPrime(2 * theLists.size()));
119+
for (auto& lt : theLists)
120+
{
121+
lt.clear();
122+
}
123+
124+
currentSize = 0;
125+
for (auto& lt : oldLists)
126+
{
127+
for (auto& x : lt)
128+
{
129+
insert(std::move(x));
130+
}
131+
}
132+
133+
};
134+
135+
size_t myHash(const HashedObj& x) const
136+
{
137+
static hash<HashedObj> hf;
138+
return hf(x) % theLists.size();
139+
}
140+
};
141+
142+
template <>
143+
class hash<string>
144+
{
145+
public:
146+
size_t operator()(const string& key)
147+
{
148+
size_t hashVal = 0;
149+
for (char c : key)
150+
{
151+
hashVal = 37 * hashVal + c;
152+
}
153+
return hashVal;
154+
}
155+
};

0 commit comments

Comments
 (0)