TheAlgorithms/C++ 1.0.0
All the algorithms implemented in C++
Loading...
Searching...
No Matches
linear_probing_hash_table.cpp
Go to the documentation of this file.
1
9#include <iostream>
10#include <vector>
11
19namespace linear_probing {
20// fwd declarations
21using Entry = struct Entry;
22bool putProber(const Entry& entry, int key);
23bool searchingProber(const Entry& entry, int key);
24void add(int key);
25
26// Undocumented globals
27int notPresent;
28std::vector<Entry> table;
29int totalSize;
30int tomb = -1;
31int size;
32bool rehashing;
33
35struct Entry {
36 explicit Entry(int key = notPresent) : key(key) {}
37 int key;
38};
39
46size_t hashFxn(int key) {
47 std::hash<int> hash;
48 return hash(key);
49}
50
55int linearProbe(int key, bool searching) {
56 int hash = static_cast<int>(hashFxn(key));
57 int i = 0;
58 Entry entry;
59 do {
60 int index = static_cast<int>((hash + i) % totalSize);
61 entry = table[index];
62 if (searching) {
63 if (entry.key == notPresent) {
64 return notPresent;
65 }
66 if (searchingProber(entry, key)) {
67 std::cout << "Found key!" << std::endl;
68 return index;
69 }
70 std::cout << "Found tombstone or equal hash, checking next"
71 << std::endl;
72 i++;
73 } else {
74 if (putProber(entry, key)) {
75 if (!rehashing) {
76 std::cout << "Spot found!" << std::endl;
77 }
78 return index;
79 }
80 if (!rehashing) {
81 std::cout << "Spot taken, looking at next" << std::endl;
82 }
83 i++;
84 }
85 if (i == totalSize) {
86 std::cout << "Linear probe failed" << std::endl;
87 return notPresent;
88 }
89 } while (entry.key != notPresent);
90 return notPresent;
91}
92
98bool putProber(const Entry& entry, int key) {
99 if (entry.key == notPresent || entry.key == tomb) {
100 return true;
101 }
102 return false;
103}
104
110bool searchingProber(const Entry& entry, int key) {
111 if (entry.key == key) {
112 return true;
113 }
114 return false;
115}
116
120void display() {
121 for (int i = 0; i < totalSize; i++) {
122 if (table[i].key == notPresent) {
123 std::cout << " Empty ";
124 } else if (table[i].key == tomb) {
125 std::cout << " Tomb ";
126 } else {
127 std::cout << " ";
128 std::cout << table[i].key;
129 std::cout << " ";
130 }
131 }
132 std::cout << std::endl;
133}
134
138void rehash() {
139 // Necessary so wall of add info isn't printed all at once
140 rehashing = true;
141 int oldSize = totalSize;
142 std::vector<Entry> oldTable(table);
143 // Really this should use the next prime number greater than totalSize *
144 // 2
145 totalSize *= 2;
146 table = std::vector<Entry>(totalSize);
147 for (int i = 0; i < oldSize; i++) {
148 if (oldTable[i].key != -1 && oldTable[i].key != notPresent) {
149 size--; // Size stays the same (add increments size)
150 add(oldTable[i].key);
151 }
152 }
153 // delete[] oldTable;
154 rehashing = false;
155 std::cout << "Table was rehashed, new size is: " << totalSize << std::endl;
156}
157
161void add(int key) {
162 int index = linearProbe(key, false);
163 table[index].key = key;
164 // Load factor greater than 0.5 causes resizing
165 if (++size / static_cast<double>(totalSize) >= 0.5) {
166 rehash();
167 }
168}
169
173void remove(int key) {
174 int index = linearProbe(key, true);
175 if (index == notPresent) {
176 std::cout << "key not found" << std::endl;
177 }
178 std::cout << "Removal Successful, leaving tomb" << std::endl;
179 table[index].key = tomb;
180 size--;
181}
182
186void addInfo(int key) {
187 std::cout << "Initial table: ";
188 display();
189 std::cout << std::endl;
190 std::cout << "hash of " << key << " is " << hashFxn(key) << " % "
191 << totalSize << " == " << hashFxn(key) % totalSize;
192 std::cout << std::endl;
193 add(key);
194 std::cout << "New table: ";
195 display();
196}
197
201void removalInfo(int key) {
202 std::cout << "Initial table: ";
203 display();
204 std::cout << std::endl;
205 std::cout << "hash of " << key << " is " << hashFxn(key) << " % "
206 << totalSize << " == " << hashFxn(key) % totalSize;
207 std::cout << std::endl;
208 remove(key);
209 std::cout << "New table: ";
210 display();
211}
212} // namespace linear_probing
218using linear_probing::table;
219using linear_probing::totalSize;
220
224int main() {
225 int cmd = 0, hash = 0, key = 0;
226 std::cout << "Enter the initial size of Hash Table. = ";
227 std::cin >> totalSize;
228 table = std::vector<Entry>(totalSize);
229 bool loop = true;
230 while (loop) {
231 std::cout << std::endl;
232 std::cout << "PLEASE CHOOSE -" << std::endl;
233 std::cout << "1. Add key. (Numeric only)" << std::endl;
234 std::cout << "2. Remove key." << std::endl;
235 std::cout << "3. Find key." << std::endl;
236 std::cout << "4. Generate Hash. (Numeric only)" << std::endl;
237 std::cout << "5. Display Hash table." << std::endl;
238 std::cout << "6. Exit." << std::endl;
239 std::cin >> cmd;
240 switch (cmd) {
241 case 1:
242 std::cout << "Enter key to add = ";
243 std::cin >> key;
245 break;
246 case 2:
247 std::cout << "Enter key to remove = ";
248 std::cin >> key;
250 break;
251 case 3: {
252 std::cout << "Enter key to search = ";
253 std::cin >> key;
254 Entry entry = table[linear_probing::linearProbe(key, true)];
255 if (entry.key == linear_probing::notPresent) {
256 std::cout << "Key not present";
257 }
258 break;
259 }
260 case 4:
261 std::cout << "Enter element to generate hash = ";
262 std::cin >> key;
263 std::cout << "Hash of " << key
264 << " is = " << linear_probing::hashFxn(key);
265 break;
266 case 5:
268 break;
269 default:
270 loop = false;
271 break;
272 // delete[] table;
273 }
274 std::cout << std::endl;
275 }
276 return 0;
277}
An implementation of hash table using linear probing algorithm.
size_t hashFxn(int key)
Hash a key. Uses the STL library's std::hash() function.
int linearProbe(int key, bool searching)
bool putProber(const Entry &entry, int key)
bool searchingProber(const Entry &entry, int key)
Entry(int key=notPresent)
constructor
int key
key value