diff --git a/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/LinearProbingHashMap.java b/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/LinearProbingHashMap.java
index c96da27c0331..10d5dc7decae 100644
--- a/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/LinearProbingHashMap.java
+++ b/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/LinearProbingHashMap.java
@@ -2,24 +2,51 @@
import java.util.ArrayList;
-/***
- * This class is an implementation of a hash table using linear probing.
+/**
+ * This class implements a hash table using linear probing to resolve collisions.
+ * Linear probing is a collision resolution method where each slot in the hash table is checked in a sequential manner
+ * until an empty slot is found.
+ *
+ *
+ * The class allows for storing key-value pairs, where both the key and value are generic types.
+ * The key must be of a type that implements the Comparable interface to ensure that the keys can be compared for sorting.
+ *
+ *
+ *
+ * This implementation supports basic operations such as:
+ *
+ * - put(Key key, Value value): Adds a key-value pair to the hash table. If the key already exists, its value is updated.
+ * - get(Key key): Retrieves the value associated with the given key.
+ * - delete(Key key): Removes the key and its associated value from the hash table.
+ * - contains(Key key): Checks if the hash table contains a given key.
+ * - size(): Returns the number of key-value pairs in the hash table.
+ * - keys(): Returns an iterable collection of keys stored in the hash table.
+ *
+ *
+ *
+ *
+ * The internal size of the hash table is automatically resized when the load factor exceeds 0.5 or falls below 0.125,
+ * ensuring efficient space utilization.
+ *
+ *
* @see Linear Probing Hash Table
*
- * @param keys type.
- * @param values type.
+ * @param the type of keys maintained by this map
+ * @param the type of mapped values
*/
public class LinearProbingHashMap, Value> extends Map {
private int hsize; // size of the hash table
- private Key[] keys;
- private Value[] values;
- private int size; // amount of elements in the hash table
+ private Key[] keys; // array to store keys
+ private Value[] values; // array to store values
+ private int size; // number of elements in the hash table
+ // Default constructor initializes the table with a default size of 16
public LinearProbingHashMap() {
this(16);
}
@SuppressWarnings("unchecked")
+ // Constructor to initialize the hash table with a specified size
public LinearProbingHashMap(int size) {
this.hsize = size;
keys = (Key[]) new Comparable[size];
@@ -81,7 +108,7 @@ public boolean delete(Key key) {
i = increment(i);
while (keys[i] != null) {
- // delete keys[i] an vals[i] and reinsert
+ // Save the key and value for rehashing
Key keyToRehash = keys[i];
Value valToRehash = values[i];
keys[i] = null;
diff --git a/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/LinearProbingHashMapTest.java b/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/LinearProbingHashMapTest.java
index d0a72a1509ee..34b165d4bbcf 100644
--- a/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/LinearProbingHashMapTest.java
+++ b/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/LinearProbingHashMapTest.java
@@ -1,8 +1,91 @@
package com.thealgorithms.datastructures.hashmap.hashing;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.junit.jupiter.api.Test;
+
class LinearProbingHashMapTest extends MapTest {
+
@Override
, Value> Map getMap() {
return new LinearProbingHashMap<>();
}
+
+ @Test
+ void putNullKey() {
+ Map map = getMap();
+ assertFalse(map.put(null, "value"), "Putting a null key should return false");
+ }
+
+ @Test
+ void putDuplicateKeys() {
+ Map map = getMap();
+ map.put(1, "one");
+ map.put(1, "uno");
+ assertEquals("uno", map.get(1), "Value should be updated to 'uno'");
+ }
+
+ @Test
+ void putResizeTest() {
+ Map map = getMap();
+ for (int i = 0; i < 20; i++) {
+ map.put(i, String.valueOf(i));
+ }
+ assertEquals(20, map.size(), "Map size should be 20 after inserting 20 elements");
+ }
+
+ @Test
+ void deleteNonExistentKey() {
+ Map map = getMap();
+ assertFalse(map.delete(999), "Deleting a non-existent key should return false");
+ }
+
+ @Test
+ void deleteAndReinsert() {
+ Map map = getMap();
+ map.put(1, "one");
+ map.delete(1);
+ assertFalse(map.contains(1), "Map should not contain the deleted key");
+ map.put(1, "one again");
+ assertTrue(map.contains(1), "Map should contain the key after reinsertion");
+ }
+
+ @Test
+ void resizeDown() {
+ Map map = getMap();
+ for (int i = 0; i < 16; i++) {
+ map.put(i, String.valueOf(i));
+ }
+ for (int i = 0; i < 12; i++) {
+ map.delete(i);
+ }
+ assertEquals(4, map.size(), "Map size should be 4 after deleting 12 elements");
+ }
+
+ @Test
+ void keysOrderTest() {
+ Map map = getMap();
+ for (int i = 10; i > 0; i--) {
+ map.put(i, String.valueOf(i));
+ }
+ int expectedKey = 1;
+ for (Integer key : map.keys()) {
+ assertEquals(expectedKey++, key, "Keys should be in sorted order");
+ }
+ }
+
+ @Test
+ void stressTest() {
+ Map map = getMap();
+ for (int i = 0; i < 1000; i++) {
+ map.put(i, String.valueOf(i));
+ assertEquals(i + 1, map.size(), "Size should match number of inserted elements");
+ }
+ for (int i = 0; i < 500; i++) {
+ map.delete(i);
+ assertEquals(1000 - (i + 1), map.size(), "Size should decrease correctly");
+ }
+ }
}