-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHashTable.h
More file actions
186 lines (140 loc) · 4.95 KB
/
HashTable.h
File metadata and controls
186 lines (140 loc) · 4.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
#ifndef MY_HASH_TABLE
#define MY_HASH_TABLE
#include "HashNode.h"
#include <vector>
#include <list>
using namespace std;
enum HashTableError { OUT_OF_MEMORY, KEY_NOT_FOUND, DUPLICATE_KEY }; // extend if necessary
typedef unsigned long ulint;
class HashTable {
// typedef list<HashNode>::iterator ListIterator;
typedef vector <list<HashNode>> Table;
Table *table; // size of table is stored in the Table data structure
size_t num; // number of entries in the HashTable;
public:
HashTable(); // constructor, initializes table of size 11;
HashTable(size_t); // constructor, requires size of table as arg
~HashTable(); // deconstructor
size_t size(); // returns size of the hash table (number of buckets)
size_t hash_function(ulint); // the table's hash function
ulint getValue(ulint); // find and return data associated with key
void insert(ulint,ulint); // insert data associated with key into table
void erase(ulint); // remove key and associated data from table
void rehash(size_t); // sets a new size for the hash table, reha/shes the hash table
// extend if necessary
bool isresize(); // resize if the table size is less than the number of entries
bool findKey(ulint); // retruns true if the key is found
};
/* Implement the
- Constructors, Destructor
- hash_function, insert, getValue methods
- erase, and rehash methods
*/
HashTable::HashTable() {
num = 0;
table = new Table(11); // table of size 11
if (table == nullptr) {
throw OUT_OF_MEMORY; // error code 0 - when the memory hasn't been initialised
}
}
HashTable::HashTable(size_t tableSize) {
num = 0;
table = new Table(tableSize); // table of size tableSize
if (table == nullptr) {
throw OUT_OF_MEMORY; // error code 0 - when the memory hasn't been initialised
}
}
HashTable::~HashTable() {
delete table; // frees the memory
}
size_t HashTable::size() {
return table->size();
}
size_t HashTable::hash_function(ulint data) {
ulint key;
key = data % size(); // key is the data mod the table size
return key;
}
ulint HashTable::getValue(ulint hashKey) {
list<HashNode> *hashNodeList;
ulint key = hash_function(hashKey); // hash
hashNodeList = &(table->at(key)); // linked list initialised at the vector index determined by the key
for (auto& n : *hashNodeList) { // searches the hashNodeList
if (hashKey == n.getKey())
return n.getValue();
}
throw KEY_NOT_FOUND;
}
/*
used in mc_dlog.cpp
*/
bool HashTable::findKey(ulint y) {
list<HashNode> *hashNodeList;
ulint key = hash_function(y);
hashNodeList = &(table->at(key));
for (auto& n : *hashNodeList) {
if (y == n.getKey())
return true;
}
return false;
}
void HashTable::insert(ulint hashKey, ulint data) {
list<HashNode>* hashNodeList;
HashNode* node = new HashNode; // new node created at insert
ulint key = hash_function(hashKey); // key for each individual node
hashNodeList = &(table->at(key)); // linked list initialised at the vector index determined by the key
node->assign(hashKey, data); // assign the key and the data to the node
for (list<HashNode>::iterator it = hashNodeList->begin(); it != hashNodeList->end(); ++it) {
if (it->getKey() == hashKey)
return;
}
hashNodeList->push_back(*node); // add the node to the back
num++; // number of entries increased
// resize if the table size is less than the number of entries
if (isresize() == true)
rehash(2*size() + 1); // make sure its prime
if (getValue(hashKey) == node->getValue()) {
cout << hashKey << " key and value " << node->getValue() <<
" inserted successfully" << endl;
}
}
void HashTable::erase(ulint hashKey) {
list<HashNode>* hashNodeList;
ulint key = hash_function(hashKey); // hash
hashNodeList = &(table->at(key)); // linked list initialised at the vector index determined by the key
//int count = 0;
for (list<HashNode>::iterator it = hashNodeList->begin(); it != hashNodeList->end(); ++it) {
if ((*it).getKey() == hashKey) {
cout << "Value to be deleted: " << (*it).getValue()
<< ", Key to be deleted: " << (*it).getKey() << endl;
hashNodeList->erase(it); // erase the contents at iterator pos
num--; // table size decreased by 1
return; // once found return otherwise it will keep on searching
}
}
throw KEY_NOT_FOUND; // throws error code 1
}
void HashTable::rehash(size_t tableSize) {
Table oldTable = *table;
table->clear();
table = new Table(tableSize);
printf("\nREHASHING\n");
// reference to list in oldTable
for (list<HashNode> &list : oldTable) {
//reference to node in list
for (HashNode &node : list) {
// oldTable must not be empty before the insert and list
if (!oldTable.empty() && !list.empty()) {
// insert key and value each node at the list
insert(node.getKey(), node.getValue());
}
}
}
}
bool HashTable::isresize() {
if (size() <= num)
return true;
else
return false;
}
#endif