3
3
import java .util .Objects ;
4
4
5
5
/**
6
- * This class is an implementation of a hash table using Cuckoo Hashing It uses
7
- * a dynamic array to lengthen the size of the hash table when load factor > .7
6
+ * This class implements a hash table using Cuckoo Hashing.
7
+ * Cuckoo hashing is a type of open-addressing hash table that resolves collisions
8
+ * by relocating existing keys. It utilizes two hash functions to minimize collisions
9
+ * and automatically resizes the table when the load factor exceeds 0.7.
8
10
*
9
- * <a href="https://en.wikipedia.org/wiki/Cuckoo_hashing">...</a>
11
+ * For more information on cuckoo hashing, refer to
12
+ * <a href="https://en.wikipedia.org/wiki/Cuckoo_hashing">this Wikipedia page</a>.
10
13
*/
11
14
public class HashMapCuckooHashing {
12
15
13
- private int tableSize ; // size of the hash table
14
- private Integer [] buckets ; // array representing the table
15
- private final Integer emptySlot ;
16
- private int size ; // number of elements in the hash table
17
-
18
- private int thresh ; // threshold for infinite loop checking
16
+ private int tableSize ; // Size of the hash table
17
+ private Integer [] buckets ; // Array representing the hash table
18
+ private final Integer emptySlot ; // Placeholder for deleted slots
19
+ private int size ; // Number of elements in the hash table
20
+ private int thresh ; // Threshold for detecting infinite loops during insertion
19
21
20
22
/**
21
- * Constructor initializes buckets array, hsize, and creates dummy object
22
- * for emptySlot
23
+ * Constructs a HashMapCuckooHashing object with the specified initial table size.
23
24
*
24
- * @param tableSize the desired size of the hash map
25
+ * @param tableSize the initial size of the hash map
25
26
*/
26
27
public HashMapCuckooHashing (int tableSize ) {
27
28
this .buckets = new Integer [tableSize ];
@@ -32,13 +33,11 @@ public HashMapCuckooHashing(int tableSize) {
32
33
}
33
34
34
35
/**
35
- * The 2 Hash Functions takes a given key and finds an index based on its data, 2 distinctive
36
- * ways to minimize collisions
36
+ * Computes the first hash index for a given key using the modulo operation.
37
37
*
38
- * @param key the desired key to be converted
39
- * @return int an index corresponding to the key
38
+ * @param key the key for which the hash index is computed
39
+ * @return an integer index corresponding to the key
40
40
*/
41
-
42
41
public int hashFunction1 (int key ) {
43
42
int hash = key % tableSize ;
44
43
if (hash < 0 ) {
@@ -47,6 +46,12 @@ public int hashFunction1(int key) {
47
46
return hash ;
48
47
}
49
48
49
+ /**
50
+ * Computes the second hash index for a given key using integer division.
51
+ *
52
+ * @param key the key for which the hash index is computed
53
+ * @return an integer index corresponding to the key
54
+ */
50
55
public int hashFunction2 (int key ) {
51
56
int hash = key / tableSize ;
52
57
hash %= tableSize ;
@@ -57,14 +62,14 @@ public int hashFunction2(int key) {
57
62
}
58
63
59
64
/**
60
- * inserts the key into the hash map by wrapping it as an Integer object, then uses while loop
61
- * to insert new key if desired place is empty, return. if already occupied, continue while loop
62
- * over the new key that has just been pushed out. if while loop continues more than Thresh ,
63
- * rehash table to new size, then push again .
65
+ * Inserts a key into the hash table using cuckoo hashing.
66
+ * If the target bucket is occupied, it relocates the existing key and attempts to insert
67
+ * it into its alternate location. If the insertion process exceeds the threshold ,
68
+ * the table is resized .
64
69
*
65
- * @param key the desired key to be inserted in the hash map
70
+ * @param key the key to be inserted into the hash table
71
+ * @throws IllegalArgumentException if the key already exists in the table
66
72
*/
67
-
68
73
public void insertKey2HashTable (int key ) {
69
74
Integer wrappedInt = key ;
70
75
Integer temp ;
@@ -77,7 +82,7 @@ public void insertKey2HashTable(int key) {
77
82
}
78
83
79
84
if (checkTableContainsKey (key )) {
80
- throw new IllegalArgumentException ("Key already inside, no duplicates allowed" );
85
+ throw new IllegalArgumentException ("Key already exists; duplicates are not allowed. " );
81
86
}
82
87
83
88
while (loopCounter <= thresh ) {
@@ -117,9 +122,7 @@ public void insertKey2HashTable(int key) {
117
122
}
118
123
119
124
/**
120
- * creates new HashMapCuckooHashing object, then inserts each of the elements in the previous
121
- * table to it with its new hash functions. then refers current array to new table.
122
- *
125
+ * Rehashes the current table to a new size (double the current size) and reinserts existing keys.
123
126
*/
124
127
public void reHashTableIncreasesTableSize () {
125
128
HashMapCuckooHashing newT = new HashMapCuckooHashing (tableSize * 2 );
@@ -134,15 +137,16 @@ public void reHashTableIncreasesTableSize() {
134
137
}
135
138
136
139
/**
137
- * deletes a key from the hash map and adds an available placeholder
140
+ * Deletes a key from the hash table, marking its position as available.
138
141
*
139
- * @param key the desired key to be deleted
142
+ * @param key the key to be deleted from the hash table
143
+ * @throws IllegalArgumentException if the table is empty or if the key is not found
140
144
*/
141
145
public void deleteKeyFromHashTable (int key ) {
142
146
Integer wrappedInt = key ;
143
147
int hash = hashFunction1 (key );
144
148
if (isEmpty ()) {
145
- throw new IllegalArgumentException ("Table is empty" );
149
+ throw new IllegalArgumentException ("Table is empty, cannot delete. " );
146
150
}
147
151
148
152
if (Objects .equals (buckets [hash ], wrappedInt )) {
@@ -157,11 +161,11 @@ public void deleteKeyFromHashTable(int key) {
157
161
size --;
158
162
return ;
159
163
}
160
- throw new IllegalArgumentException ("Key " + key + " already inside, no duplicates allowed " );
164
+ throw new IllegalArgumentException ("Key " + key + " not found in the table. " );
161
165
}
162
166
163
167
/**
164
- * Displays the hash table line by line
168
+ * Displays the hash table contents, bucket by bucket.
165
169
*/
166
170
public void displayHashtable () {
167
171
for (int i = 0 ; i < tableSize ; i ++) {
@@ -175,17 +179,18 @@ public void displayHashtable() {
175
179
}
176
180
177
181
/**
178
- * Finds the index of location based on an inputted key
182
+ * Finds the index of a given key in the hash table.
179
183
*
180
- * @param key the desired key to be found
181
- * @return int the index where the key is located
184
+ * @param key the key to be found
185
+ * @return the index where the key is located
186
+ * @throws IllegalArgumentException if the table is empty or the key is not found
182
187
*/
183
188
public int findKeyInTable (int key ) {
184
189
Integer wrappedInt = key ;
185
190
int hash = hashFunction1 (key );
186
191
187
192
if (isEmpty ()) {
188
- throw new IllegalArgumentException ("Table is empty" );
193
+ throw new IllegalArgumentException ("Table is empty; cannot find keys. " );
189
194
}
190
195
191
196
if (Objects .equals (buckets [hash ], wrappedInt )) {
@@ -194,66 +199,70 @@ public int findKeyInTable(int key) {
194
199
195
200
hash = hashFunction2 (key );
196
201
if (!Objects .equals (buckets [hash ], wrappedInt )) {
197
- throw new IllegalArgumentException ("Key " + key + " not found in table" );
202
+ throw new IllegalArgumentException ("Key " + key + " not found in the table. " );
198
203
} else {
199
204
return hash ;
200
205
}
201
206
}
202
207
203
208
/**
204
- * checks if key is inside without any output other than returned boolean .
209
+ * Checks if the given key is present in the hash table .
205
210
*
206
- * @param key the desired key to be found
207
- * @return int the index where the key is located
211
+ * @param key the key to be checked
212
+ * @return true if the key exists, false otherwise
208
213
*/
209
214
public boolean checkTableContainsKey (int key ) {
210
- return ((buckets [hashFunction1 (key )] != null && buckets [hashFunction1 (key )].equals (key )) || (buckets [hashFunction2 (key )] != null && buckets [hashFunction2 (key )] == key ));
215
+ return ((buckets [hashFunction1 (key )] != null && buckets [hashFunction1 (key )].equals (key )) || (buckets [hashFunction2 (key )] != null && buckets [hashFunction2 (key )]. equals ( key ) ));
211
216
}
212
217
213
218
/**
214
- * Checks the load factor of the hash table if greater than .7,
215
- * automatically lengthens table to prevent further collisions
219
+ * Checks the load factor of the hash table. If the load factor exceeds 0.7,
220
+ * the table is resized to prevent further collisions.
221
+ *
222
+ * @return the current load factor of the hash table
216
223
*/
217
224
public double checkLoadFactor () {
218
225
double factor = (double ) size / tableSize ;
219
226
if (factor > .7 ) {
220
- System .out .printf ("Load factor is %.2f , rehashing table%n" , factor );
227
+ System .out .printf ("Load factor is %.2f, rehashing table. %n" , factor );
221
228
reHashTableIncreasesTableSize ();
222
229
}
223
230
return factor ;
224
231
}
225
232
226
233
/**
227
- * isFull returns true if the hash map is full and false if not full
234
+ * Checks if the hash map is full.
228
235
*
229
- * @return boolean is Empty
236
+ * @return true if the hash map is full, false otherwise
230
237
*/
231
238
public boolean isFull () {
232
- boolean response = true ;
233
239
for (int i = 0 ; i < tableSize ; i ++) {
234
240
if (buckets [i ] == null || Objects .equals (buckets [i ], emptySlot )) {
235
241
return false ;
236
242
}
237
243
}
238
- return response ;
244
+ return true ;
239
245
}
240
246
241
247
/**
242
- * isEmpty returns true if the hash map is empty and false if not empty
248
+ * Checks if the hash map is empty.
243
249
*
244
- * @return boolean is Empty
250
+ * @return true if the hash map is empty, false otherwise
245
251
*/
246
252
public boolean isEmpty () {
247
- boolean response = true ;
248
253
for (int i = 0 ; i < tableSize ; i ++) {
249
254
if (buckets [i ] != null ) {
250
- response = false ;
251
- break ;
255
+ return false ;
252
256
}
253
257
}
254
- return response ;
258
+ return true ;
255
259
}
256
260
261
+ /**
262
+ * Returns the current number of keys in the hash table.
263
+ *
264
+ * @return the number of keys present in the hash table
265
+ */
257
266
public int getNumberOfKeysInTable () {
258
267
return size ;
259
268
}
0 commit comments