Skip to content

Commit cd40dfb

Browse files
authored
Enhance docs, add tests in HashMapCuckooHashing (#5975)
1 parent 84cd883 commit cd40dfb

File tree

4 files changed

+204
-149
lines changed

4 files changed

+204
-149
lines changed

DIRECTORY.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -857,12 +857,12 @@
857857
* hashing
858858
* [GenericHashMapUsingArrayListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArrayListTest.java)
859859
* [GenericHashMapUsingArrayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArrayTest.java)
860+
* [HashMapCuckooHashingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/HashMapCuckooHashingTest.java)
860861
* [HashMapTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/HashMapTest.java)
861862
* [IntersectionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/IntersectionTest.java)
862863
* [LinearProbingHashMapTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/LinearProbingHashMapTest.java)
863864
* [MajorityElementTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/MajorityElementTest.java)
864865
* [MapTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/MapTest.java)
865-
* [HashMapCuckooHashingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/hashmap/HashMapCuckooHashingTest.java)
866866
* heaps
867867
* [FibonacciHeapTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/FibonacciHeapTest.java)
868868
* [GenericHeapTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/GenericHeapTest.java)

src/main/java/com/thealgorithms/datastructures/hashmap/hashing/HashMapCuckooHashing.java

Lines changed: 63 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,26 @@
33
import java.util.Objects;
44

55
/**
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.
810
*
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>.
1013
*/
1114
public class HashMapCuckooHashing {
1215

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
1921

2022
/**
21-
* Constructor initializes buckets array, hsize, and creates dummy object
22-
* for emptySlot
23+
* Constructs a HashMapCuckooHashing object with the specified initial table size.
2324
*
24-
* @param tableSize the desired size of the hash map
25+
* @param tableSize the initial size of the hash map
2526
*/
2627
public HashMapCuckooHashing(int tableSize) {
2728
this.buckets = new Integer[tableSize];
@@ -32,13 +33,11 @@ public HashMapCuckooHashing(int tableSize) {
3233
}
3334

3435
/**
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.
3737
*
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
4040
*/
41-
4241
public int hashFunction1(int key) {
4342
int hash = key % tableSize;
4443
if (hash < 0) {
@@ -47,6 +46,12 @@ public int hashFunction1(int key) {
4746
return hash;
4847
}
4948

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+
*/
5055
public int hashFunction2(int key) {
5156
int hash = key / tableSize;
5257
hash %= tableSize;
@@ -57,14 +62,14 @@ public int hashFunction2(int key) {
5762
}
5863

5964
/**
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.
6469
*
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
6672
*/
67-
6873
public void insertKey2HashTable(int key) {
6974
Integer wrappedInt = key;
7075
Integer temp;
@@ -77,7 +82,7 @@ public void insertKey2HashTable(int key) {
7782
}
7883

7984
if (checkTableContainsKey(key)) {
80-
throw new IllegalArgumentException("Key already inside, no duplicates allowed");
85+
throw new IllegalArgumentException("Key already exists; duplicates are not allowed.");
8186
}
8287

8388
while (loopCounter <= thresh) {
@@ -117,9 +122,7 @@ public void insertKey2HashTable(int key) {
117122
}
118123

119124
/**
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.
123126
*/
124127
public void reHashTableIncreasesTableSize() {
125128
HashMapCuckooHashing newT = new HashMapCuckooHashing(tableSize * 2);
@@ -134,15 +137,16 @@ public void reHashTableIncreasesTableSize() {
134137
}
135138

136139
/**
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.
138141
*
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
140144
*/
141145
public void deleteKeyFromHashTable(int key) {
142146
Integer wrappedInt = key;
143147
int hash = hashFunction1(key);
144148
if (isEmpty()) {
145-
throw new IllegalArgumentException("Table is empty");
149+
throw new IllegalArgumentException("Table is empty, cannot delete.");
146150
}
147151

148152
if (Objects.equals(buckets[hash], wrappedInt)) {
@@ -157,11 +161,11 @@ public void deleteKeyFromHashTable(int key) {
157161
size--;
158162
return;
159163
}
160-
throw new IllegalArgumentException("Key " + key + " already inside, no duplicates allowed");
164+
throw new IllegalArgumentException("Key " + key + " not found in the table.");
161165
}
162166

163167
/**
164-
* Displays the hash table line by line
168+
* Displays the hash table contents, bucket by bucket.
165169
*/
166170
public void displayHashtable() {
167171
for (int i = 0; i < tableSize; i++) {
@@ -175,17 +179,18 @@ public void displayHashtable() {
175179
}
176180

177181
/**
178-
* Finds the index of location based on an inputted key
182+
* Finds the index of a given key in the hash table.
179183
*
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
182187
*/
183188
public int findKeyInTable(int key) {
184189
Integer wrappedInt = key;
185190
int hash = hashFunction1(key);
186191

187192
if (isEmpty()) {
188-
throw new IllegalArgumentException("Table is empty");
193+
throw new IllegalArgumentException("Table is empty; cannot find keys.");
189194
}
190195

191196
if (Objects.equals(buckets[hash], wrappedInt)) {
@@ -194,66 +199,70 @@ public int findKeyInTable(int key) {
194199

195200
hash = hashFunction2(key);
196201
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.");
198203
} else {
199204
return hash;
200205
}
201206
}
202207

203208
/**
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.
205210
*
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
208213
*/
209214
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)));
211216
}
212217

213218
/**
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
216223
*/
217224
public double checkLoadFactor() {
218225
double factor = (double) size / tableSize;
219226
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);
221228
reHashTableIncreasesTableSize();
222229
}
223230
return factor;
224231
}
225232

226233
/**
227-
* isFull returns true if the hash map is full and false if not full
234+
* Checks if the hash map is full.
228235
*
229-
* @return boolean is Empty
236+
* @return true if the hash map is full, false otherwise
230237
*/
231238
public boolean isFull() {
232-
boolean response = true;
233239
for (int i = 0; i < tableSize; i++) {
234240
if (buckets[i] == null || Objects.equals(buckets[i], emptySlot)) {
235241
return false;
236242
}
237243
}
238-
return response;
244+
return true;
239245
}
240246

241247
/**
242-
* isEmpty returns true if the hash map is empty and false if not empty
248+
* Checks if the hash map is empty.
243249
*
244-
* @return boolean is Empty
250+
* @return true if the hash map is empty, false otherwise
245251
*/
246252
public boolean isEmpty() {
247-
boolean response = true;
248253
for (int i = 0; i < tableSize; i++) {
249254
if (buckets[i] != null) {
250-
response = false;
251-
break;
255+
return false;
252256
}
253257
}
254-
return response;
258+
return true;
255259
}
256260

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+
*/
257266
public int getNumberOfKeysInTable() {
258267
return size;
259268
}

src/test/java/com/thealgorithms/datastructures/hashmap/HashMapCuckooHashingTest.java

Lines changed: 0 additions & 94 deletions
This file was deleted.

0 commit comments

Comments
 (0)