I am trying to implement hashing with separate chaining. This is for a homework assignment. Yes, I've read the policy here.
My understanding of separate chaining is that I am to implement a linked list for elements that result in the same hash. I have an array that holds all the possible slots for the hash positions and then, when more than one element shares the same hash, use a linked list at that slot position in the array. I assume that none of the insertion values hold 0 since that is the default value of each node (for debugging purposes since you could use NULL
).
For the purpose of the assignment, I'm just using an array and a really simple hash function that takes mod of the array size.
There is some kind of issue with my implementation because there is an infinite loop when I execute it. I am very interested to understand why this isn't working. I'm not just looking for an answer but rather an explanation so I can understand why it's not working.
It looks like the issue occurs only in the array elements that are chained. I've rewritten this code many many times trying to understand what's going on. In another version, it was creating the chained nodes correctly but the values were not accessible when I tried to display them (it was outputting garbage values). I suspect there's some kind of reference issue in insertSepChain()
or display()
that's causing it to break.
#include <iostream>
class ListNode {
public:
int value;
ListNode* next;
ListNode(int newValue) {
value = newValue;
next = nullptr;
}
ListNode() {
this->value = 0;
this->next = nullptr;
}
};
class HashTest {
private:
int size;
ListNode arr[17];//used a number for debugging purposes
public:
HashTest(int size) {
this->size = size;
for (int i = 0; i < size; i++) {
arr[i] = ListNode(0);
}
}
void insertSepChain(int value) {
//find the index to place the value
int index = hash(value);
if (arr[index].value == 0) {
//not already filled
arr[index].value = value;
}
//already filled
else {
ListNode temp(value);
arr[index].next = &temp;
}
}
int hash(int value) {
return value % size;
}
void display() {
using namespace std;
for (int i = 0; i < size; i++) {
if (arr[i].value == 0) {
//not filled
cout << "0\n";
}
else if (arr[i].value != 0 && arr[i].next == nullptr) {
//filled and no chain
cout << arr[i].value << "\n";
}
else if (arr[i].value != 0 && arr[i].next != nullptr) {
//filled and chain
cout << "chain: ";
ListNode temp = arr[i];
while (temp.next != nullptr) {
cout << temp.value << ", ";
temp = *temp.next;
}
}
}
}
};
int main() {
HashTest testing(17);
//9, 34, 49, 16, 32, 51
using namespace std;
testing.insertSepChain(9);
testing.insertSepChain(34);
testing.insertSepChain(49);
testing.insertSepChain(16);
testing.insertSepChain(32);
testing.insertSepChain(51);
testing.display();
return 0;
}