Search code examples
c++hashtable

C++ linked hashtable copying


I have to implement a HashTable with linked lists. It is almost done (still missing templates, will do in time), but I'm stuck at something. Basically, I want to resize my hashtable when the load factor reaches a given value, say 50%. But I don't know how I should do it. I have a basic idea:

  1. Create a temporary HT with the new size
  2. Hash every data in every list from the old HT to the temporary one
  3. Delete the old HT
  4. Return the temporary HT

I can't figure out an implementation for it though...

Here is what I have so far:

//List:
struct Node
{
  string data;
  Node *next;
};

class List
{
  private:
    Node *head, *tail;
    int length;
    friend class HashTable;
  public:
    List();
    List(const List &L);
    //~List() {delete this;};
    List& operator =(List L);
    int find(string);
    void insert(string value);
    void remove_head();
    void remove_poz(int);
    void remove_tail();
    void clear();
    void display();
};

List::List()
{
   head = NULL;
   tail = NULL;
   length = 0;
}

List::List(const List& L)
{
    Node** temp = &head;
    const Node* source = L.head;
    while(source)
    {
        *temp = new Node(*source);
        temp = &(*temp)->next;
        source = source->next;
    }
}

List& List::operator =(List L)
{
  swap(head, L.head);
  return *this;
}

void List::insert(string value)
{
  Node* temp = new Node;
  temp->data = value;
  temp->next = NULL;

  if (!head)
      head = temp;
  if (tail)
      tail->next = temp;
  tail = temp;
  length++;
}

void List::display()
{
  Node *temp = new Node;
  temp = head;
  while (temp != NULL)
  {
    cout<<temp->data<<" ";
    temp = temp->next;
  }
  delete temp;
}


//HashTable:
class HashTable
{
  private:
    List *table;
    float load, stored;
    int slots;
    friend class List;
  public:
    HashTable();
    HashTable(int);
    ~HashTable();
    int hashFunc(string key);
    int findTable(string);
    int findList(string);
    HashTable& operator =(const HashTable&);
    void resize();    //I need this one
    void insert(string);
    void remove(string);
    void clear(int);
    void clear();
    void display();
};

HashTable::HashTable()
{
  stored = 0;
  load = 0.00;
  slots = 15;
  table = new List[slots];
}

HashTable::HashTable(int size)
{
    stored = 0;
    load = 0.00;
    slots = size;
    table = new List[slots];
}

int HashTable::hashFunc(string key)
{
  unsigned int i, ind = 0;
  for (i = 0; i<key.length(); ++i)
      ind = ind + key[i];
  ind %= slots;
  return ind;
}

HashTable& HashTable::operator =(const HashTable& T) //I suppose it is incorrect
{
    int i;
    HashTable temp(T.slots);
    for (i = 0; i < slots; ++i)
    {
        temp.table[i] = T.table[i];
    }

    return temp;
}

void HashTable::insert(string value)
{
  int ind = hashFunc(value);

  table[ind].insert(value);

  if (!table[ind].head->next) stored++;

  load = stored / slots;
  if (load > 0.50) resize();
}

(Note: only the functions that might be needed are shown here)

Any help, correction or suggestion would be much appreciated :)

UPDATE:

Managed to pull this one off:

void HashTable::resize()
{
  int i;
  int newSize = slots * 2;
  int newLoad = stored / newSize;
  HashTable HT(newSize);
  Node* temp;

  for (i = 0; i < slots; ++i)
  {
      temp = table[i].head;
      while (temp != NULL)
      {
          HT.insert(temp->data);
          temp = temp->next;
      }
  }
}

Now I have a new HashTable named HT, with double the size of the original one, and all elements have been inserted correctly. But I don`t know how to proceed.


Solution

  • The easiest way to proceed is to add a swapContents() method to your HashTable class:

    void HashTable::swapContents(HashTable & rhs)
    {
       std::swap(table, rhs.table);
       std::swap(load, rhs.load);
       std::swap(stored, rhs.stored);
       std::swap(slots, rhs.slots);
       // any other member-variables of the HashTable class would get swapped here too
    }
    

    ... then call swapContents(HT) at the end of your resize() method, so that HT becomes the older/smaller HashTable (and gets discarded) while this becomes the newer/larger table.