I typically implement my hash tables as an array of linked lists.
Code:
struct HashtableNode
{
string key;
string value;
HashtableNode* next;
};
const int HashtableSize = 31;
class Hashtable
{
HashtableNode* table[HashtableSize];
Hashtable()
{
for(int i=0; i<HashtableSize; i++)
table[i] = NULL;
}
// very awful hash function
int
hash(const string& key)
{
return key.size() % HashtableSize;
}
void
insert(const string& name, const string& address)
{
HashtableNode* newNode;
int h = hash(name);
if(table[h])
{
HashtableNode* node = table[h];
// walk the list to see if the key already exists
while(node)
{
// if it does, set the value and return
if(node->key == name)
{
node->value = address;
return;
}
node = node->next;
}
}
// otherwise, we need a new node
newNode = new HashtableNode;
newNode->key = name;
newNode->value = address;
// add it to the front of the linked list
newNode->next = table[h];
table[h] = newNode;
}
}
I find this method of implementing a hashtable to be cleaner and sometimes more efficient. It keeps all elements within linked lists inside their own hash buckets.
The array method forces you to move elements into further buckets when you have collisions.
If you still want to implement it that way, you'd basically need a while loop. You start at your hash bucket and if that spot is taken, you move forward 1 spot and try again. Keep doing this until you find an open spot (or you run out of space in the table).
Something like this for your code:
Code:
bool HashTable::Insert(const string &name, const string &address)
{
unsigned int key = Mask(Hash(name));
while(key < SIZE) // whatever size your array is
{
if (ptr[key].GetName()=="nil" || ptr[key].GetName() == name)
{
ptr[key].SetName(name);
ptr[key].SetAddress(address);
return true;
}
key++;
}
return false; // ran out of room
}
Hope that helps.