在 C++ 中为特定哈希表创建插入函数

Creating an insert function for a specific hash table in c++

本文关键字:哈希表 创建 插入 函数 C++      更新时间:2023-10-16

我正在尝试制作一个使用列表数组来存储数据的模板哈希表。 对于表格,我正在尝试为哈希表编写一个插入函数,如果哈希索引指向尚未包含列表的部分,该函数将创建一个新列表。

以下是该类的基础知识:

template <class T>
class Hash
{
public:
Hash(int buckets);
Hash(const Hash <T> & rhs);
~Hash() { delete [] table; }
/*some functions removed for brevity*/ 
void insert(const T & t);   //this is the function I am struggling with
virtual int hash(const T & t) const = 0;
private:
list <T> * table;
int numElements;
int numBuckets;
};

这是我对插入功能的尝试:

//insert                                                                                         
template <class T>
void Hash <T> :: insert(const T & t)
{
if (table[hash(t)] == NULL) // I am not comparing this right 
{
//compiler does not like this assignment                                                 
table[hash(t)] = new list <T>; 
//insert passed in value into new list                                                  
table[hash(t)].insert(hash(t));
}
else
{
//insert passed in value into list                                                  
table[hash(t)].insert(hash(t));
}
numElements++;
}

我的理解是我的私有变量列表 * 表可以充当数组。

我的问题是:如何正确查看表变量内部以查看那里是否创建了列表,以及如何在传入的哈希索引处创建新列表

编辑这里是我的构造函数定义和整数的哈希类:

我正在使用非默认构造函数来获取用户在哈希表中想要的"桶"数量:

//non-default constructor                                                                  
template <class T>
Hash <T> :: Hash(int buckets)
{
table = new list <T> [buckets];
numElements = 0;
numBuckets = buckets;
}

下面是整数哈希类:

/****************************************                                                  
* I HASH                                                                                  
* A simple hash of integers                                                               
****************************************/
class IHash : public Hash <int>
{
public:
IHash(int numBuckets)    : Hash <int> (numBuckets) {}
IHash(const IHash & rhs) : Hash <int> (rhs)        {}
// hash function for integers is simply to take the modulous                            
int hash(const int & value) const
{
int index = abs(value) % capacity();
assert(0 <= index && index < capacity());
return index;
}
};

这整件事对我来说有点不舒服。但是你说这条线失败了:

table[hash(t)] = new list <T>; 

您已将表定义为:

list <T> * table;

也就是说,表 [0] 的类型是列表而不是列表 *。我认为您可能需要这样做:

list<T> ** table;

坦率地说,我不会那样做。我会这样做:

std::vector<list<T> *> table;

但是你对此有很大的问题。你的哈希((方法可以返回什么范围?通常哈希值可能非常大,所以现在你正在创建一个具有非常大值的数组。

您的代码还有其他问题。您已经将表本身设置为指针,但您没有向我们显示您为其分配任何空间的位置,也没有在您的插入方法中显示根据需要扩展空间的位置。

我会这样说:哈希表实现不使用数组是有原因的。他们倾向于使用树,或者如果不是平衡的树,至少是树(因为保持树的平衡是一种痛苦(。

在函数中添加了注释。

template <class T>
void Hash <T> :: insert(const T & t)
{
//Following line should not compile. table[index] gives you list<T> object not the pointer.
if (table[hash(t)] == NULL) // I am not comparing this right 
{
//You don't need to do this. table isn't a pointer to pointer.
table[hash(t)] = new list <T>; 
//insert takes two argument, you perhaps meant push_back?
//Also, you should be adding 't' to the list not the hash(t). hash(t) is only there to identified the bucket from the table.                                                  
table[hash(t)].insert(hash(t));
}
else
{
table[hash(t)].insert(hash(t));
}
numElements++;

}

至少,你应该尝试这样的事情:

template <class T>
void Hash <T> :: insert(const T & t)
{
int hashValue = hash(t);
table[hashValue].push_back(t);
numElements++;
}

您需要确保正确分配该表以保存可能的哈希值的范围