Skip to content

Commit b98dc2c

Browse files
authored
Fix linear probing hash map (TheAlgorithms#3902)
1 parent 45923d6 commit b98dc2c

File tree

6 files changed

+301
-272
lines changed

6 files changed

+301
-272
lines changed

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

Lines changed: 0 additions & 203 deletions
This file was deleted.
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
package com.thealgorithms.datastructures.hashmap.hashing;
2+
3+
import java.util.ArrayList;
4+
5+
/***
6+
* This class is an implementation of a hash table using linear probing.
7+
* @see <a href="https://en.wikipedia.org/wiki/Linear_probing">Linear Probing Hash Table</a>
8+
*
9+
* @param <Key> keys type.
10+
* @param <Value> values type.
11+
*/
12+
public class LinearProbingHashMap<Key extends Comparable<Key>, Value> extends Map<Key, Value> {
13+
private int hsize; // size of the hash table
14+
private Key[] keys;
15+
private Value[] values;
16+
private int size; // amount of elements in the hash table
17+
18+
public LinearProbingHashMap() {
19+
this(16);
20+
}
21+
22+
@SuppressWarnings("unchecked")
23+
public LinearProbingHashMap(int size) {
24+
this.hsize = size;
25+
keys = (Key[]) new Comparable[size];
26+
values = (Value[]) new Object[size];
27+
}
28+
29+
@Override
30+
public boolean put(Key key, Value value) {
31+
if (key == null) {
32+
return false;
33+
}
34+
35+
if (size > hsize / 2) {
36+
resize(2 * hsize);
37+
}
38+
39+
int keyIndex = hash(key, hsize);
40+
for (; keys[keyIndex] != null; keyIndex = increment(keyIndex)) {
41+
if (key.equals(keys[keyIndex])) {
42+
values[keyIndex] = value;
43+
return true;
44+
}
45+
}
46+
47+
keys[keyIndex] = key;
48+
values[keyIndex] = value;
49+
size++;
50+
return true;
51+
}
52+
53+
@Override
54+
public Value get(Key key) {
55+
if (key == null) {
56+
return null;
57+
}
58+
59+
for (int i = hash(key, hsize); keys[i] != null; i = increment(i)) {
60+
if (key.equals(keys[i])) {
61+
return values[i];
62+
}
63+
}
64+
65+
return null;
66+
}
67+
68+
@Override
69+
public boolean delete(Key key) {
70+
if (key == null || !contains(key)) {
71+
return false;
72+
}
73+
74+
int i = hash(key, hsize);
75+
while (!key.equals(keys[i])) {
76+
i = increment(i);
77+
}
78+
79+
keys[i] = null;
80+
values[i] = null;
81+
82+
i = increment(i);
83+
while (keys[i] != null) {
84+
// delete keys[i] an vals[i] and reinsert
85+
Key keyToRehash = keys[i];
86+
Value valToRehash = values[i];
87+
keys[i] = null;
88+
values[i] = null;
89+
size--;
90+
put(keyToRehash, valToRehash);
91+
i = increment(i);
92+
}
93+
94+
size--;
95+
if (size > 0 && size <= hsize / 8) {
96+
resize(hsize / 2);
97+
}
98+
99+
return true;
100+
}
101+
102+
@Override
103+
public boolean contains(Key key) {
104+
return get(key) != null;
105+
}
106+
107+
@Override
108+
int size() {
109+
return size;
110+
}
111+
112+
@Override
113+
Iterable<Key> keys() {
114+
ArrayList<Key> listOfKeys = new ArrayList<>(size);
115+
for (int i = 0; i < hsize; i++) {
116+
if (keys[i] != null) {
117+
listOfKeys.add(keys[i]);
118+
}
119+
}
120+
121+
listOfKeys.sort(Comparable::compareTo);
122+
return listOfKeys;
123+
}
124+
125+
private int increment(int i) {
126+
return (i + 1) % hsize;
127+
}
128+
129+
private void resize(int newSize) {
130+
LinearProbingHashMap<Key, Value> tmp = new LinearProbingHashMap<>(newSize);
131+
for (int i = 0; i < hsize; i++) {
132+
if (keys[i] != null) {
133+
tmp.put(keys[i], values[i]);
134+
}
135+
}
136+
137+
this.keys = tmp.keys;
138+
this.values = tmp.values;
139+
this.hsize = newSize;
140+
}
141+
}

0 commit comments

Comments
 (0)