-
Notifications
You must be signed in to change notification settings - Fork 0
/
LinearHashTable.java
174 lines (146 loc) · 5.3 KB
/
LinearHashTable.java
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
/*
* Microassignment: Probing Hash Table addElement and removeElement
*
* LinearHashTable: Yet another Hash Table Implementation
*
* Contributors:
* Bolong Zeng <bzeng@wsu.edu>, 2018
* Aaron S. Crandall <acrandal@wsu.edu>, 2019
*
* Copyright:
* For academic use only under the Creative Commons
* Attribution-NonCommercial-NoDerivatives 4.0 International License
* http://creativecommons.org/licenses/by-nc-nd/4.0
*/
class LinearHashTable<K, V> extends HashTableBase<K, V>
{
// Linear and Quadratic probing should rehash at a load factor of 0.5 or higher
private static final double REHASH_LOAD_FACTOR = 0.5;
// Constructors
public LinearHashTable()
{
super();
}
public LinearHashTable(HasherBase<K> hasher)
{
super(hasher);
}
public LinearHashTable(HasherBase<K> hasher, int number_of_elements)
{
super(hasher, number_of_elements);
}
// Copy constructor
public LinearHashTable(LinearHashTable<K, V> other)
{
super(other);
}
// ***** MA Section Start ************************************************ //
// Concrete implementation for parent's addElement method
public void addElement(K key, V value)
{
// Check for size restrictions
resizeCheck();
// Calculate hash based on key
int hash = super.getHash(key);
HashItem<K, V> slot = _items.elementAt(hash);
int i = 0; //index
while (!slot.isEmpty() && slot.getKey() != key) {
if (i == size()) {
return; //hashtable is full
}
hash = (hash + 1) % _items.size();
slot = _items.elementAt(hash); //get next slot
i++;
}
slot.setValue(value);
slot.setKey(key);
slot.setIsEmpty(false); //sets value and key to empty slot
_number_of_elements++; //increase num elements
}
// Removes supplied key from hash table
public void removeElement(K key)
{
// Calculate hash from key
int hash = super.getHash(key);
HashItem<K, V> slot = _items.elementAt(hash);
int i = 0; //index
while (slot.getKey() != key) {
if (i == size() || slot.isTrueEmpty()) {
return; // can not find element
}
hash = (hash + 1) % _items.size();
slot = _items.elementAt(hash); //get next slot
i++;
}
slot.setIsEmpty(true);
_number_of_elements--; //decrease num elements
}
// ***** MA Section End ************************************************ //
// Public API to get current number of elements in Hash Table
public int size() {
return this._number_of_elements;
}
// Public API to test whether the Hash Table is empty (N == 0)
public boolean isEmpty() {
return this._number_of_elements == 0;
}
// Returns true if the key is contained in the hash table
public boolean containsElement(K key)
{
int hash = super.getHash(key);
HashItem<K, V> slot = _items.elementAt(hash);
// Left incomplete to avoid hints in the MA :)
return false;
}
// Returns the item pointed to by key
public V getElement(K key)
{
int hash = super.getHash(key);
HashItem<K, V> slot = _items.elementAt(hash);
// Left incomplete to avoid hints in the MA :)
return null;
}
// Determines whether or not we need to resize
// to turn off resize, just always return false
protected boolean needsResize()
{
// Linear probing seems to get worse after a load factor of about 50%
if (_number_of_elements > (REHASH_LOAD_FACTOR * _primes[_local_prime_index]))
{
return true;
}
return false;
}
// Called to do a resize as needed
protected void resizeCheck()
{
// Right now, resize when load factor > 0.5; it might be worth it to experiment with
// this value for different kinds of hashtables
if (needsResize())
{
_local_prime_index++;
HasherBase<K> hasher = _hasher;
LinearHashTable<K, V> new_hash = new LinearHashTable<K, V>(hasher, _primes[_local_prime_index]);
for (HashItem<K, V> item: _items)
{
if (item.isEmpty() == false)
{
// Add element to new hash table
new_hash.addElement(item.getKey(), item.getValue());
}
}
// Steal temp hash object's internal vector for ourselves
_items = new_hash._items;
}
}
// Debugging tool to print out the entire contents of the hash table
public void printOut() {
System.out.println(" Dumping hash with " + _number_of_elements + " items in " + _items.size() + " buckets");
System.out.println("[X] Key | Value | Deleted");
for( int i = 0; i < _items.size(); i++ ) {
HashItem<K, V> curr_slot = _items.get(i);
System.out.print("[" + i + "] ");
System.out.println(curr_slot.getKey() + " | " + curr_slot.getValue() + " | " + curr_slot.isEmpty());
}
}
}