TheAlgorithms/C++ 1.0.0
All the algorithms implemented in C++
Loading...
Searching...
No Matches
double_hash_hash_table.cpp
Go to the documentation of this file.
1
9#include <iostream>
10#include <memory>
11#include <vector>
12
20namespace double_hashing {
21// fwd declarations
22using Entry = struct Entry;
23bool putProber(const Entry& entry, int key);
24bool searchingProber(const Entry& entry, int key);
25void add(int key);
26
27// Undocumented globals
28int notPresent;
29std::vector<Entry> table;
30int totalSize;
31int tomb = -1;
32int size;
33bool rehashing;
34
36struct Entry {
37 explicit Entry(int key = notPresent) : key(key) {}
38 int key;
39};
40
47size_t hashFxn(int key) {
48 std::hash<int> hash;
49 return hash(key);
50}
51
58size_t otherHashFxn(int key) {
59 std::hash<int> hash;
60 return 1 + (7 - (hash(key) % 7));
61}
62
71int doubleHash(int key, bool searching) {
72 int hash = static_cast<int>(hashFxn(key));
73 int i = 0;
74 Entry entry;
75 do {
76 int index =
77 static_cast<int>(hash + (i * otherHashFxn(key))) % totalSize;
78 entry = table[index];
79 if (searching) {
80 if (entry.key == notPresent) {
81 return notPresent;
82 }
83 if (searchingProber(entry, key)) {
84 std::cout << "Found key!" << std::endl;
85 return index;
86 }
87 std::cout << "Found tombstone or equal hash, checking next"
88 << std::endl;
89 i++;
90 } else {
91 if (putProber(entry, key)) {
92 if (!rehashing) {
93 std::cout << "Spot found!" << std::endl;
94 }
95 return index;
96 }
97 if (!rehashing) {
98 std::cout << "Spot taken, looking at next (next index:"
99 << " "
100 << static_cast<int>(hash + (i * otherHashFxn(key))) %
101 totalSize
102 << ")" << std::endl;
103 }
104 i++;
105 }
106 if (i == totalSize * 100) {
107 std::cout << "DoubleHash probe failed" << std::endl;
108 return notPresent;
109 }
110 } while (entry.key != notPresent);
111 return notPresent;
112}
113
120bool putProber(const Entry& entry, int key) {
121 if (entry.key == notPresent || entry.key == tomb) {
122 return true;
123 }
124 return false;
125}
126
133bool searchingProber(const Entry& entry, int key) {
134 if (entry.key == key) {
135 return true;
136 }
137 return false;
138}
139
143void display() {
144 for (int i = 0; i < totalSize; i++) {
145 if (table[i].key == notPresent) {
146 std::cout << " Empty ";
147 } else if (table[i].key == tomb) {
148 std::cout << " Tomb ";
149 } else {
150 std::cout << " ";
151 std::cout << table[i].key;
152 std::cout << " ";
153 }
154 }
155 std::cout << std::endl;
156}
157
161void rehash() {
162 // Necessary so wall of add info isn't printed all at once
163 rehashing = true;
164 int oldSize = totalSize;
165 std::vector<Entry> oldTable(table);
166 // Really this should use the next prime number greater than totalSize * 2
167 table = std::vector<Entry>(totalSize * 2);
168 totalSize *= 2;
169 for (int i = 0; i < oldSize; i++) {
170 if (oldTable[i].key != -1 && oldTable[i].key != notPresent) {
171 size--; // Size stays the same (add increments size)
172 add(oldTable[i].key);
173 }
174 }
175 // delete[] oldTable;
176 // oldTable.reset();
177
178 rehashing = false;
179 std::cout << "Table was rehashed, new size is: " << totalSize << std::endl;
180}
181
185void add(int key) {
186 // auto* entry = new Entry();
187 // entry->key = key;
188 int index = doubleHash(key, false);
189 table[index].key = key;
190 // Load factor greater than 0.5 causes resizing
191 if (++size / static_cast<double>(totalSize) >= 0.5) {
192 rehash();
193 }
194}
195
199void remove(int key) {
200 int index = doubleHash(key, true);
201 if (index == notPresent) {
202 std::cout << "key not found" << std::endl;
203 }
204 table[index].key = tomb;
205 std::cout << "Removal successful, leaving tombstone" << std::endl;
206 size--;
207}
208
212void addInfo(int key) {
213 std::cout << "Initial table: ";
214 display();
215 std::cout << std::endl;
216 std::cout << "hash of " << key << " is " << hashFxn(key) << " % "
217 << totalSize << " == " << hashFxn(key) % totalSize;
218 std::cout << std::endl;
219 add(key);
220 std::cout << "New table: ";
221 display();
222}
223
227void removalInfo(int key) {
228 std::cout << "Initial table: ";
229 display();
230 std::cout << std::endl;
231 std::cout << "hash of " << key << " is " << hashFxn(key) << " % "
232 << totalSize << " == " << hashFxn(key) % totalSize;
233 std::cout << std::endl;
234 remove(key);
235 std::cout << "New table: ";
236 display();
237}
238} // namespace double_hashing
244using double_hashing::table;
245using double_hashing::totalSize;
246
250int main() {
251 int cmd = 0, hash = 0, key = 0;
252 std::cout << "Enter the initial size of Hash Table. = ";
253 std::cin >> totalSize;
254 table = std::vector<Entry>(totalSize);
255 bool loop = true;
256 while (loop) {
257 std::cout << std::endl;
258 std::cout << "PLEASE CHOOSE -" << std::endl;
259 std::cout << "1. Add key. (Numeric only)" << std::endl;
260 std::cout << "2. Remove key." << std::endl;
261 std::cout << "3. Find key." << std::endl;
262 std::cout << "4. Generate Hash. (Numeric only)" << std::endl;
263 std::cout << "5. Display Hash table." << std::endl;
264 std::cout << "6. Exit." << std::endl;
265 std::cin >> cmd;
266 switch (cmd) {
267 case 1:
268 std::cout << "Enter key to add = ";
269 std::cin >> key;
271 break;
272 case 2:
273 std::cout << "Enter key to remove = ";
274 std::cin >> key;
276 break;
277 case 3: {
278 std::cout << "Enter key to search = ";
279 std::cin >> key;
280 Entry entry = table[double_hashing::doubleHash(key, true)];
281 if (entry.key == double_hashing::notPresent) {
282 std::cout << "Key not present";
283 }
284 break;
285 }
286 case 4:
287 std::cout << "Enter element to generate hash = ";
288 std::cin >> key;
289 std::cout << "Hash of " << key
290 << " is = " << double_hashing::hashFxn(key);
291 break;
292 case 5:
294 break;
295 default:
296 loop = false;
297 break;
298 // delete[] table;
299 }
300 std::cout << std::endl;
301 }
302 return 0;
303}
An implementation of hash table using double hashing algorithm.
size_t hashFxn(int key)
Hash a key. Uses the STL library's std::hash() function.
bool searchingProber(const Entry &entry, int key)
size_t otherHashFxn(int key)
Used for second hash function.
int doubleHash(int key, bool searching)
Performs double hashing to resolve collisions.
bool putProber(const Entry &entry, int key)
Entry(int key=notPresent)
constructor
int key
key value