TheAlgorithms/C++
1.0.0
All the algorithms implemented in C++
Toggle main menu visibility
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
20
namespace
double_hashing
{
21
// fwd declarations
22
using
Entry
=
struct
Entry
;
23
bool
putProber
(
const
Entry
& entry,
int
key);
24
bool
searchingProber
(
const
Entry
& entry,
int
key);
25
void
add
(
int
key);
26
27
// Undocumented globals
28
int
notPresent;
29
std::vector<Entry> table;
30
int
totalSize;
31
int
tomb = -1;
32
int
size;
33
bool
rehashing;
34
36
struct
Entry
{
37
explicit
Entry
(
int
key
= notPresent) :
key
(
key
) {}
38
int
key
;
39
};
40
47
size_t
hashFxn
(
int
key) {
48
std::hash<int> hash;
49
return
hash(key);
50
}
51
58
size_t
otherHashFxn
(
int
key) {
59
std::hash<int> hash;
60
return
1 + (7 - (hash(key) % 7));
61
}
62
71
int
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
120
bool
putProber
(
const
Entry
& entry,
int
key) {
121
if
(entry.
key
== notPresent || entry.
key
== tomb) {
122
return
true
;
123
}
124
return
false
;
125
}
126
133
bool
searchingProber
(
const
Entry
& entry,
int
key) {
134
if
(entry.
key
== key) {
135
return
true
;
136
}
137
return
false
;
138
}
139
143
void
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
161
void
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
185
void
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
199
void
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
212
void
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
227
void
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
242
243
using
double_hashing::Entry
;
244
using
double_hashing::table;
245
using
double_hashing::totalSize;
246
250
int
main
() {
251
int
cmd = 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;
270
double_hashing::addInfo
(key);
271
break
;
272
case
2:
273
std::cout <<
"Enter key to remove = "
;
274
std::cin >> key;
275
double_hashing::removalInfo
(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:
293
double_hashing::display
();
294
break
;
295
default
:
296
loop =
false
;
297
break
;
298
// delete[] table;
299
}
300
std::cout << std::endl;
301
}
302
return
0;
303
}
main
int main()
Main function.
Definition
generate_parentheses.cpp:110
double_hashing
An implementation of hash table using double hashing algorithm.
double_hashing::hashFxn
size_t hashFxn(int key)
Hash a key. Uses the STL library's std::hash() function.
Definition
double_hash_hash_table.cpp:47
double_hashing::display
void display()
Definition
double_hash_hash_table.cpp:143
double_hashing::remove
void remove(int key)
Definition
double_hash_hash_table.cpp:199
double_hashing::searchingProber
bool searchingProber(const Entry &entry, int key)
Definition
double_hash_hash_table.cpp:133
double_hashing::otherHashFxn
size_t otherHashFxn(int key)
Used for second hash function.
Definition
double_hash_hash_table.cpp:58
double_hashing::removalInfo
void removalInfo(int key)
Definition
double_hash_hash_table.cpp:227
double_hashing::add
void add(int key)
Definition
double_hash_hash_table.cpp:185
double_hashing::doubleHash
int doubleHash(int key, bool searching)
Performs double hashing to resolve collisions.
Definition
double_hash_hash_table.cpp:71
double_hashing::addInfo
void addInfo(int key)
Definition
double_hash_hash_table.cpp:212
double_hashing::putProber
bool putProber(const Entry &entry, int key)
Definition
double_hash_hash_table.cpp:120
double_hashing::rehash
void rehash()
Definition
double_hash_hash_table.cpp:161
double_hashing::Entry
Definition
double_hash_hash_table.cpp:36
double_hashing::Entry::Entry
Entry(int key=notPresent)
constructor
Definition
double_hash_hash_table.cpp:37
double_hashing::Entry::key
int key
key value
Definition
double_hash_hash_table.cpp:38
hashing
double_hash_hash_table.cpp
Generated by
1.18.0