I cant seem to figure out why my hash table's insert function keeps hanging. I know its this portion because it started to hang after i tweaked this portion of the code.
void HashTable::Insert(string key)
{
int code = HashCode(key) % tableSize;
cout << "Key '" << key << "' hashes to " << code << endl;
/// TO DO:
/// Add a new node to the bucket with the index code
/// Step 1: Create a new node
/// Step 2: Locate the position for inserting the node
/// Step 3: Attach the new node to the structure. Also, DO remember to
//increase the number of the elements
HashNode *newHashNode = new HashNode;
newHashNode -> data = key;
//Traverse pointer made to point at first linked list
HashNode *traversePtr = new HashNode;
traversePtr = table[code].next;
//whle pointer doesnt reach end of bucket
while(traversePtr != nullptr)
{
traversePtr = traversePtr -> next;
}
//if(table[code].next == nullptr || traversePtr == nullptr)
//{
table[code].next = newHashNode;
numElements++;
//}
}
When attempting to debug I get this error(line 5):
It did not point to nullptr but when i changed it i got the same problem. I also deleted traversePtr in the function (placed at last line) but now i get: Thread 1:EXC_BAD_ACCESS in line 21. But that error rarely occurs. The program still stalls after displaying "Key 'horse' hashes to 4" so i know its inserting everything but once the insert is done then it appears to hang, or thats what it seems to me
The program still stalls after displaying "Key 'horse' hashes to 4" so i know its inserting everything but once the insert is done then it appears to hang, or thats what it seems to me
That message occurs after Insert is called, but before anything is actually inserted. It seems likely, given your code, that the linked list that comprises your bucket has an invariant that is violated (i.e. the list is not properly terminated with a null pointer.)
I said "I think Ive found the error" not " I Found the error". Maybe giving another hint instead of throwing shade would be more helpful.
If anyone would still like to help Ive gotten my program to run but now im stuck in an infinite loop inside my print statement and it appears as if nothing got added to the bucket. I thought it was a missing nullPtr but i cant seem to find where.
void HashTable::Insert(string key)
{
int code = HashCode(key) % tableSize;
cout << "Key '" << key << "' hashes to " << code << endl;
/// TO DO:
/// Add a new node to the bucket with the index code
/// Step 1: Create a new node
/// Step 2: Locate the position for inserting the node
/// Step 3: Attach the new node to the structure. Also, DO remember to
//increase the number of the elements
HashNode *newHashNode = new HashNode;
newHashNode -> data = key;
newHashNode -> next = nullptr;
//Traverse pointer made to point at first linked list
HashNode *traversePtr = new HashNode;
traversePtr = nullptr;
traversePtr = &table[code];
if(table[code].next == nullptr)
{
table[code].next = newHashNode;
}
else
{
//while pointer doesnt reach end of bucket
while(traversePtr -> next != nullptr)
{
traversePtr = traversePtr -> next;
}
}
traversePtr -> next = newHashNode;
numElements++;
delete newHashNode;
}
That code occurs nowhere in the code you've posted thus far, and suggests that table has a different type here than it does elsewhere. You could help yourself by showing a complete, compilable sample of code that reproduces the issue(s) you're having, rather than asking people to guess.
I already stated: infinite loop inside my print statement(i meant function) and I posted this in the very beginning: I know its this portion because it started to hang after i tweaked this portion of the code.
So we're clear: The program runs perfectly fine without the insert function. Once the insert function is implemented and then print function is called the program continues to only print "inside print" forever.
#include <iostream>
#include <vector>
usingnamespace std;
constint INITIAL_SIZE = 11;
//****************
//HashNode Struct*
//****************
struct HashNode
{
string data;
HashNode * next = nullptr;
};
//Variables
constint HASH_SEED = 5381;
constint HASH_MULTIPLIER = 33;
constint HASH_MASK = unsigned(-1) >> 1;
//******************
//HashCode Function*
//******************
int HashCode(string str)
{
unsigned hash = HASH_SEED;
int n = str.length();
for (int i = 0; i < n; i++)
{
hash = HASH_MULTIPLIER * hash + str[i];
}
returnint(hash & HASH_MASK);
}
//****************
//HashTable Class*
//****************
class HashTable
{
private:
HashNode * table; /// dynamically allocated array of pointers to nodes
int tableSize; /// should be a prime number
int numElements;
public:
HashTable();
void Insert(string key);
void Remove(string key);
bool Find(string key);
void Display();
};
//**********************
//HashTable Constructor*
//**********************
HashTable::HashTable()
{
tableSize = INITIAL_SIZE;
table = new HashNode[tableSize];
numElements = 0;
/// TO DO:
/// Set all elements to NULL
for(int i = 0; i < tableSize; i++)
{
table[i].next = nullptr;
}
}
//***************************
//HashTable-Display Function*
//***************************
void HashTable::Display()
{
for(int i = 0; i < tableSize; i++)
{
if(table -> next == nullptr)
{
i++;
}
else
{
while(table -> next != nullptr)
{
cout << "INSIDE PRINT" << endl;
cout << table -> data << endl;
}
i++;
}
}
}
//**************************
//HashTable-Insert Function*
//**************************
void HashTable::Insert(string key)
{
int code = HashCode(key) % tableSize;
cout << "Key '" << key << "' hashes to " << code << endl;
/// TO DO:
/// Add a new node to the bucket with the index code
/// Step 1: Create a new node
/// Step 2: Locate the position for inserting the node
/// Step 3: Attach the new node to the structure. Also, DO remember to
//increase the number of the elements
HashNode *newHashNode = new HashNode;
newHashNode -> data = key;
newHashNode -> next = nullptr;
//Traverse pointer made to point at first linked list
HashNode *traversePtr = new HashNode;
traversePtr = nullptr;
traversePtr = &table[code];
if(table[code].next == nullptr)
{
table[code].next = newHashNode;
}
else
{
//while pointer doesnt reach end of bucket
while(traversePtr -> next != nullptr)
{
traversePtr = traversePtr -> next;
}
}
traversePtr -> next = newHashNode;
numElements++;
//delete traversePtr;
}
//**************************
//HashTable-Remove Function*
//**************************
void HashTable::Remove(string key)
{
int code = HashCode(key) % tableSize;
cout << "Trying to remove key '" << key << "' at index " << code << endl;
/// TO DO:
/// Search the linked list, and remove the match element
}
//bool HashTable::Find(string key)
//{
// int code = HashCode(key) % tableSize;
// cout << "Looking for key '" << key << "' at index " << code << endl;
/// TO DO:
/// Search through the linked list and return true if the key is found. Otherwise,
//return false.
//}
int main()
{
HashTable animals;
animals.Insert("cat");
animals.Insert("fish");
animals.Insert("elephant");
animals.Insert("tiger");
animals.Insert("panda");
animals.Insert("otter");
animals.Insert("horse");
animals.Display();
/// tiger should be found this time
//if (animals.Find("tiger"))
// cout << "tiger is found" << endl;
//else
// cout << "tiger is NOT found" << endl;
animals.Remove("tiger");
animals.Display();
/// tiger should NOT be found since it has been removed
//if (animals.Find("tiger"))
// cout << "tiger is found" << endl;
//else
// cout << "tiger is NOT found" << endl;
return 0;
}
You should probably begin by revisiting the data members of your data structure. A hash table is typically an array of linked lists, not an array of nodes.
Your comment "/// dynamically allocated array of pointers to nodes" is not accurate. table is a dynamically allocated array of nodes, but you should have an array of pointers to nodes.
Now i am a little confused. My professor provided some of the code like the HashTable class so I am unsure if he wants me to do it this way or if theres another way he wants it to be done.
And also I am not sure what you mean with this line of code. : table(new HashNode*[INITIAL_SIZE]), tableSize(INITIAL_SIZE), numElements(0)
Thank You for your feed back! I will start implementing what you have shown me