TheAlgorithms/C++ 1.0.0
All the algorithms implemented in C++
Loading...
Searching...
No Matches
quadratic_probing_hash_table.cpp
Go to the documentation of this file.
1
9#include <cmath>
10#include <iostream>
11#include <vector>
12
20namespace quadratic_probing {
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// globals
28int notPresent;
29std::vector<Entry> table;
30int totalSize;
31int tomb = -1;
32int size;
33bool rehashing;
34
37struct Entry {
38 explicit Entry(int key = notPresent) : key(key) {}
39 int key;
40};
41
46size_t hashFxn(int key) {
47 std::hash<int> hash;
48 return hash(key);
49}
50
56int quadraticProbe(int key, bool searching) {
57 int hash = static_cast<int>(hashFxn(key));
58 int i = 0;
59 Entry entry;
60 do {
61 size_t index =
62 (hash + static_cast<size_t>(std::round(std::pow(i, 2)))) %
63 totalSize;
64 entry = table[index];
65 if (searching) {
66 if (entry.key == notPresent) {
67 return notPresent;
68 }
69 if (searchingProber(entry, key)) {
70 std::cout << "Found key!" << std::endl;
71 return index;
72 }
73 std::cout << "Found tombstone or equal hash, checking next"
74 << std::endl;
75 i++;
76 } else {
77 if (putProber(entry, key)) {
78 if (!rehashing) {
79 std::cout << "Spot found!" << std::endl;
80 }
81 return index;
82 }
83 if (!rehashing) {
84 std::cout << "Spot taken, looking at next (next index = "
85 << (hash + static_cast<size_t>(
86 std::round(std::pow(i + 1, 2)))) %
87 totalSize
88 << std::endl;
89 }
90 i++;
91 }
92 if (i == totalSize * 100) {
93 std::cout << "Quadratic probe failed (infinite loop)" << std::endl;
94 return notPresent;
95 }
96 } while (entry.key != notPresent);
97 return notPresent;
98}
99
106bool putProber(const Entry& entry, int key) {
107 if (entry.key == notPresent || entry.key == tomb) {
108 return true;
109 }
110 return false;
111}
112
119bool searchingProber(const Entry& entry, int key) {
120 if (entry.key == key) {
121 return true;
122 }
123 return false;
124}
125
131Entry find(int key) {
132 int index = quadraticProbe(key, true);
133 if (index == notPresent) {
134 return Entry();
135 }
136 return table[index];
137}
138
142void display() {
143 for (int i = 0; i < totalSize; i++) {
144 if (table[i].key == notPresent) {
145 std::cout << " Empty ";
146 } else if (table[i].key == tomb) {
147 std::cout << " Tomb ";
148 } else {
149 std::cout << " ";
150 std::cout << table[i].key;
151 std::cout << " ";
152 }
153 }
154 std::cout << std::endl;
155}
156
160void rehash() {
161 // Necessary so wall of add info isn't printed all at once
162 rehashing = true;
163 int oldSize = totalSize;
164 std::vector<Entry> oldTable(table);
165 // Really this should use the next prime number greater than totalSize * 2
166 totalSize *= 2;
167 table = std::vector<Entry>(totalSize);
168 for (int i = 0; i < oldSize; i++) {
169 if (oldTable[i].key != -1 && oldTable[i].key != notPresent) {
170 size--; // Size stays the same (add increments size)
171 add(oldTable[i].key);
172 }
173 }
174 // delete[] oldTable;
175 rehashing = false;
176 std::cout << "Table was rehashed, new size is: " << totalSize << std::endl;
177}
178
182void add(int key) {
183 int index = quadraticProbe(key, false);
184 table[index].key = key;
185 // Load factor greater than 0.5 causes resizing
186 if (++size / static_cast<double>(totalSize) >= 0.5) {
187 rehash();
188 }
189}
190
194void remove(int key) {
195 int index = quadraticProbe(key, true);
196 if (index == notPresent) {
197 std::cout << "key not found" << std::endl;
198 }
199 table[index].key = tomb;
200 std::cout << "Removal successful, leaving tombstone" << std::endl;
201 size--;
202}
203
207void addInfo(int key) {
208 std::cout << "Initial table: ";
209 display();
210 std::cout << std::endl;
211 std::cout << "hash of " << key << " is " << hashFxn(key) << " % "
212 << totalSize << " == " << hashFxn(key) % totalSize;
213 std::cout << std::endl;
214 add(key);
215 std::cout << "New table: ";
216 display();
217}
218
222void removalInfo(int key) {
223 std::cout << "Initial table: ";
224 display();
225 std::cout << std::endl;
226 std::cout << "hash of " << key << " is " << hashFxn(key) << " % "
227 << totalSize << " == " << hashFxn(key) % totalSize;
228 std::cout << std::endl;
229 remove(key);
230 std::cout << "New table: ";
231 display();
232}
233
234} // namespace quadratic_probing
240using quadratic_probing::table;
241using quadratic_probing::totalSize;
242
246int main() {
247 int cmd = 0, hash = 0, key = 0;
248 std::cout << "Enter the initial size of Hash Table. = ";
249 std::cin >> totalSize;
250 table = std::vector<Entry>(totalSize);
251 bool loop = true;
252 while (loop) {
253 std::cout << std::endl;
254 std::cout << "PLEASE CHOOSE -" << std::endl;
255 std::cout << "1. Add key. (Numeric only)" << std::endl;
256 std::cout << "2. Remove key." << std::endl;
257 std::cout << "3. Find key." << std::endl;
258 std::cout << "4. Generate Hash. (Numeric only)" << std::endl;
259 std::cout << "5. Display Hash table." << std::endl;
260 std::cout << "6. Exit." << std::endl;
261 std::cin >> cmd;
262 switch (cmd) {
263 case 1:
264 std::cout << "Enter key to add = ";
265 std::cin >> key;
267 break;
268 case 2:
269 std::cout << "Enter key to remove = ";
270 std::cin >> key;
272 break;
273 case 3: {
274 std::cout << "Enter key to search = ";
275 std::cin >> key;
277 quadratic_probing::table[quadratic_probing::quadraticProbe(
278 key, true)];
279 if (entry.key == quadratic_probing::notPresent) {
280 std::cout << "Key not present";
281 }
282 break;
283 }
284 case 4:
285 std::cout << "Enter element to generate hash = ";
286 std::cin >> key;
287 std::cout << "Hash of " << key
288 << " is = " << quadratic_probing::hashFxn(key);
289 break;
290 case 5:
292 break;
293 default:
294 loop = false;
295 break;
296 // delete[] table;
297 }
298 std::cout << std::endl;
299 }
300 return 0;
301}
An implementation of hash table using quadratic probing algorithm.
int quadraticProbe(int key, bool searching)
bool putProber(const Entry &entry, int key)
bool searchingProber(const Entry &entry, int key)
int key
key value
Entry(int key=notPresent)
constructor