C++ 哈希表实现(使用数组)

C++ 哈希表实现(使用数组),c++,arrays,hash,hashmap,hashtable,C++,Arrays,Hash,Hashmap,Hashtable,这是我第一次尝试实现哈希表。我正在读一些指南,但似乎不对。对于我所有的函数,我必须创建一个新的int,然后使用它 对于所有的函数调用,我都创建了一个“inthi”。然后用它来散列我正在制作的任何密钥。这是设置哈希表的正确方法吗? 我找不到很多指南来解释如何正确设置哈希表和映射键 作为一个整体,我仍在编写代码,但我不想继续。我很确定我遗漏了什么。在每次函数调用中创建新的int和字符串对我来说似乎很不合适 下面是我正在编写的代码 #include <iostream> using nam

这是我第一次尝试实现哈希表。我正在读一些指南,但似乎不对。对于我所有的函数,我必须创建一个新的int,然后使用它

对于所有的函数调用,我都创建了一个“inthi”。然后用它来散列我正在制作的任何密钥。这是设置哈希表的正确方法吗? 我找不到很多指南来解释如何正确设置哈希表和映射键

作为一个整体,我仍在编写代码,但我不想继续。我很确定我遗漏了什么。在每次函数调用中创建新的int和字符串对我来说似乎很不合适

下面是我正在编写的代码

#include <iostream>
using namespace std;

class HashTable
{
    struct Element
    {
        string key;
        int mark;
    };
    Element** table;
    int size;

private:
    int hash(string);
    public:
    HashTable(int);
    ~HashTable();
    void insert(string);
    void remove(string);
    bool isFull();
    bool isEmpty();
    void clear();
    void print();
    bool find(string);
};

int HashTable::hash(string s)
{
    return 0;
}

HashTable::HashTable(int s)
{
    int hi;
    table = new Element *[s];
    for (int i = 0; i < size; i++)
    {
        table[hi] = NULL;
    }
}

HashTable::~HashTable()
{
    int hi;
    for (int i = 0; i < size; i++)
    {
        if (table[hi])
        delete table[hi];
    }
    delete[]table;
}

void HashTable::insert(string s)
{
    string key;
    int hi;
    if (!isFull)
    {
        hi = hash(key);
        while (table[hi]->mark == 1)
        {
            hi = (hi + 1) % size;
        }
        table[hi]->key = key;
        table[hi]->mark = 1;
    }
}

void HashTable::remove(string s)
{
    string key;
    int i;
    int hi;
    if (!isEmpty)
    {
        hi = hash(key);
        i = 0;
    }
    while (i < size && table[hi]->mark != 0)
    {
        if (table[hi]->key == key)
        {
            table[hi]->mark = 2;
            break;
        }
        i = i + 1;
        hi = (hi + 1) % size;
    }
}

bool HashTable::isFull()
{
int hi;
if (table[hi] >= size)
{
    return true;
}
}

bool HashTable::isEmpty()
{
    int hi;
    if (table[hi] >= size)
    {
        return true;
    }
}

void HashTable::clear()
{
    int hi;
    for (int i = 0; i < size; i++)
    {
        delete table[hi];
        table[hi] = nullptr;
    }
}

void HashTable::print()
{
    int hi;
    string key;
    for (int i = 0; i < size; ++i)
    {
        if (table[hi]->mark == 2)
        {
            printf("test \n", table[hi]->key);
        }
    }
}

bool HashTable::find(string s)
{
    string key;
    int i;
    int found;
    int hi;
    if (!isEmpty)
    {
        hi = hash(key);
        found = false;
    }
    i = 0;
    while (table[hi]->mark != 0 && (!found) && i < size)
    {
        if (table[hi]->mark == 1 && table[hi]->key == key)
        {
            found = true;
        }
        hi = (hi + 1) % size;
        i = i + 1;
    }
    return found;
}
#包括
使用名称空间std;
类哈希表
{
结构元素
{
字符串键;
整数标记;
};
元素**表;
整数大小;
私人:
int散列(字符串);
公众:
哈希表(int);
~HashTable();
空白插入(字符串);
脱空(串);
bool已满();
bool是空的();
无效清除();
作废打印();
布尔查找(字符串);
};
int哈希表::哈希(字符串s)
{
返回0;
}
哈希表::哈希表(int s)
{
int hi;
表=新元素*[s];
对于(int i=0;imark==1)
{
hi=(hi+1)%size;
}
表[hi]->key=key;
表[hi]->标记=1;
}
}
void哈希表::删除(字符串s)
{
字符串键;
int i;
int hi;
如果(!isEmpty)
{
hi=散列(键);
i=0;
}
而(imark!=0)
{
if(表[hi]->key==key)
{
表[hi]->标记=2;
打破
}
i=i+1;
hi=(hi+1)%size;
}
}
bool哈希表::isFull()
{
int hi;
如果(表[hi]>=大小)
{
返回true;
}
}
bool哈希表::isEmpty()
{
int hi;
如果(表[hi]>=大小)
{
返回true;
}
}
void哈希表::clear()
{
int hi;
对于(int i=0;i标记==2)
{
printf(“测试\n”,表[hi]->键);
}
}
}
布尔哈希表::查找(字符串s)
{
字符串键;
int i;
int-found;
int hi;
如果(!isEmpty)
{
hi=散列(键);
发现=错误;
}
i=0;
while(表[hi]->mark!=0&&(!found)&&imark==1和表[hi]->key==key)
{
发现=真;
}
hi=(hi+1)%size;
i=i+1;
}
发现退货;
}

首先,让我们修复您的构造函数:

HashTable::HashTable(int s)
{
    table = new Element*[s];
    size = s;                      // you forgot this line
    for (int i = 0; i < size; i++)
    {
        table[i] = NULL;           // "i", not "hi"
    }
}
C++本身有一个内置的哈希算法,它可能有更好的扩散和分布方式:

size_t HashTable::hash(const string& s)
{
    std::hash<string> hasher;
    size_t hi = hasher(s) % size;
    return hi;
}
因此,插入可以简单地如下所示:

void insert(const string& key)
{
     size_t hi = hash(key);
     Element* e = Lookup(key);
     if (e == nullptr)
     {
         e = new Element();
         e->key = key;
         e->value = value;
         e->next = table[hi];
         table[hi] = e;
     }
     else
     {
         // item already exists
     }
}
和查找:

Element* Lookup(const string& key)
{
    Element* e = nullptr;
    size_t hi = hash(key);
    e = table[hi];
    while (e && e->key != key)
    {
        e = e->next;
    }
    return e;
}
和remove是类似的查找操作

 void HashTable::remove(const string& key)
 {
    size_t hi = hash(key);
    Element* e = table[hi];
    Element* prev = nullptr;
    while (e && e->key != key)
    {
        prev = e;
        e = e->next;
    }
    if (e && prev)
    {
        prev->next = e->next;
        delete e;
    }
    else if (e)
    {
        table[hi] = e->next;
        delete e;
    }      
 }

我将把剩下的方法留给您的类作为练习。

注意,您的循环使用
I
作为索引,但在循环中使用未初始化的
hi
变量。我确信。。。
Element* Lookup(const string& key)
{
    Element* e = nullptr;
    size_t hi = hash(key);
    e = table[hi];
    while (e && e->key != key)
    {
        e = e->next;
    }
    return e;
}
 void HashTable::remove(const string& key)
 {
    size_t hi = hash(key);
    Element* e = table[hi];
    Element* prev = nullptr;
    while (e && e->key != key)
    {
        prev = e;
        e = e->next;
    }
    if (e && prev)
    {
        prev->next = e->next;
        delete e;
    }
    else if (e)
    {
        table[hi] = e->next;
        delete e;
    }      
 }