-
Notifications
You must be signed in to change notification settings - Fork 0
/
HashTable.cpp
175 lines (149 loc) · 4.62 KB
/
HashTable.cpp
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
#include "HashTable.h"
// Constructor()
// Used to create a hash table with length size.
HashTable::HashTable(int size)
{
// Create table.
table = new Record*[size];
// Initialize size, elements, and table.
numSize = size;
numElements = 0;
initialize(table);
}
// Destructor()
// Destroy the entire hash table.
HashTable::~HashTable()
{
delete [] table;
}
// Update()
// Either adds a new record with (nm, sc) as values OR
// modifies the record with sc if it is a better score.
void HashTable::update(string nm, int sc)
{
// More than 3/4 of the table is full.
// If so, grow the table by doubling its size.
if(getLoadFactor() > 0.75)
growTable();
// Update helper the record (nm, sc).
updateHelper(table, nm, sc);
}
// Exists()
// Returns whether name nm exists in the table.
bool HashTable::exists(string nm)
{
// Calculate the hash of the function.
int hash = hashFunction(nm);
// While there are elements to still look at in the table.
while(table[hash] != NULL)
{
// If the hash matches, then return true.
if(table[hash]->name == nm)
return true;
// Move to next element.
hash = (hash + 1) % numSize;
}
// If no match is found, return false.
return false;
}
// GetScore()
// Returns the score of the name nm in the table.
int HashTable::getScore(string nm)
{
// Calculate the hash of the function.
int hash = hashFunction(nm);
// While there are elements to still look at in the table.
while(table[hash] != NULL)
{
// If the hash matches, then return score.
if(table[hash]->name == nm)
return table[hash]->score;
// Move to next element.
hash = (hash + 1) % numSize;
}
// If no match is found, return -1.
return -1;
}
// HashFunction()
// An internal function used to calculate the hash for a value.
int HashTable::hashFunction(string word)
{
// Start sum at 0.
int sum = 0;
// Use char values from word, cast them to integer
// And sum them up to form the value to be hashed.
for(int i = 0; i < word.length(); i++) {
sum += static_cast<int>(word[i]);
}
// Hash the sum by the table size.
return sum % numSize;
}
// GetLoadFactor()
// Used to determine how full the table is.
// Values are 0 <= LF <= 1.
double HashTable::getLoadFactor()
{
return numElements / numSize;
}
// GrowTable()
// Used to double the size of the table, if space is running out.
void HashTable::growTable()
{
// Double the size of the table.
numSize *= 2;
// Create a new table of double size.
// Initialize it as well to empty.
Record **newTable = new Record*[numSize];
initialize(newTable);
// Go through all elements in the old table
for(int i = 0; i < numSize / 2; i++)
{
// If there's a value in the table
// Then we have to reinsert it into the new table.
if(table[i] != NULL)
{
// Insert into new table.
updateHelper(newTable, table[i]->name, table[i]->score);
// Delete old table value.
delete table[i];
}
}
// Delete the old table and set new table.
delete [] table;
table = newTable;
}
// UpdateHelper()
// Used as a Helper function to update a table tab with value (nm, sc).
void HashTable::updateHelper(Record **tab, string nm, int sc)
{
// Hash the value into the appropriate location.
int hash = hashFunction(nm);
// If some value exists and it is this item nm we're looking forr
// then we may need to update it.
if(tab[hash] != NULL && tab[hash]->name == nm)
{
// Update it only if the value of the score is better
// than what is previously there.
if(tab[hash]->score < sc)
tab[hash]->score = sc;
}
else
{
// Otherwise use Linear Probing to find the right hash
// location.
while(tab[hash] != NULL)
hash = (hash + 1) % numSize;
// Store new record into table's hash value.
// Increase the number of elements inside of it by 1.
tab[hash] = new Record(nm, sc);
numElements++;
}
}
// Initialize()
// Used to empty a table of Records.
void HashTable::initialize(Record **tab)
{
// Go through all elements in table and set it to NULL.
for(int i = 0; i < numSize; i++)
tab[i] = NULL;
}