如果不是作业(那是你的标签?)我会推荐一个 unordered_map 或 map。你的概念还没有融合在一起 - 最好简化它并一次解决一件事,而不是咬得比你能咀嚼的更多。如果你想要一个树的哈希图,我建议你从你可以依赖的 C++ STL 容器开始构建它,然后 - 如果你不应该将它们用于此任务 - 一个一个地替换它们,确保你保持高层次的使用/测试在你做的时候工作。这意味着:
typedef vector<map<T> > Container;
Container container;
您可以使用 container.resize(n) 用 n 个空地图填充容器,或者将容器从以前的某个大小扩大到一个新的大小,而额外的地图为空。
真的,从那开始。然后,如果您必须作为练习,独立实现每个向量和映射,并在将它们放回混合哈希映射之前使用简单的独立测试用例测试它们的用法。
听起来我有点苛刻,所以让我们通过你的一些问题来看看我所说的一些误解:
无论如何,我很难弄清楚
搞清楚如何做一些事情,比如
设置哈希表,这是一个
数组为 NULL,并且还 memcpy'ing BST
对象从一张桌子转移到另一张桌子。
我的建议是保持简单,做明显和干净的事情。如果你必须使用数组而不是向量,那么如果它在堆栈上:
X* buckets[N];
for (int i = 0; i < sizeof buckets / sizeof buckets[0]; ++i)
array[i] = NULL;
如果它在堆上:
X** p_buckets = new X*[N];
for (int i = 0; i < N; ++i)
array[i] = NULL;
这比 memset() 慢,但它简单易懂,让你养成考虑循环容器的习惯,做你想做的操作。有更多的 C++ 方法可以做到这一点,但是对于其他任意任务使用相同样式的迭代会更难,所以坚持下去,直到你完全适应它为止。
BST *prevData;
BST *currData;
据我了解,我认为我必须重载 = 和 == 运算符才能允许设置
数组元素为NULL,这是正确的吗?我真的不清楚如何实施所有
这个,但是从谷歌的例子来看,我有:
BST& BST :: operator= (int null);
bool BST :: operator== (int null);
== 运算符重载是检查特定数组索引是否等于 NULL。
我假设我需要一些额外的代码,而不仅仅是原型,这是
我来不及了。
您有两个指向 BST 的指针。您的哈希表是此类对象的数组,但只有您的一条评论建议您将这些视为指向两个此类哈希表的指针(而不是说在通过哈希表迭代期间记录非 NULL 元素的临时变量)。它们应该是 BST**,因为它们指向哈希表中的第一个 BST*。但是,这是实现哈希表的一种非常危险的方式,因为客户端使用的是指向哈希表的指针,而不是指向某个提供哈希表概念的安全实现的类的指针。有了这样一个指针,他们所能做的就是索引到特定的 BST,但是与您打算维护哈希表的函数没有关联,也没有跟踪它当前有多少存储桶空间的变量,它有多少元素包含等。您应该将数组放入提供所有这些的类中;有很多设计决策,但它应该看起来像这样:
template <typename Key, typename Value>
class Hash
{
public:
Hash() : p_(NULL), size_(0), num_buckets_(0) { }
// find/make entry for Key, giving read/write access to the current/a-default value
Value& operator[](const Key&);
const Value& operator[](const Key&) const;
// try to find an entry, throw an exception if not found...
Value& at(const Key&);
const Value& at(const Key&) const;
// report whether a key is already in the hash table...
bool has_key(const Key&) const;
int size() const;
private:
BST* p_;
int num_buckets_;
int size_;
};
(再一次,我只能建议您首先尝试将 p_ 替换为该地图矢量)。
第二点是memcpy,编译器不允许我这样做。
memcpy(prevData[x], currData[x], sizeof(BST) * height);
抱怨
错误 C2664:“memcpy”:无法将参数 1 从“BST”转换为“void *”
没有可以执行此转换的用户定义转换运算符,或
无法调用操作员
将所有内容从一个哈希表中的一个存储桶复制到另一个哈希表中的同一个存储桶中,这是一个非常奇怪的请求。例如,如果存储桶的数量不同或散列函数不同,那么您可能会损坏目标存储桶。无论如何,我建议你实现一个具有值语义的 BST 类(即复制现有树的复制构造函数和 operator=)。然后你可以简单地使用:
prevData.buckets[x] = currData.buckets[x];
(注意:运算符应该在哈希表中查找,并且鉴于键类型应该能够是 int,你不想使用相同的符号来复制整个存储桶 - 你不能重载一个函数如果两者都具有相同的签名。这就是为什么我在这里展示桶是 BST 的暴露容器 - 暴露这会破坏封装;在真实的类中,您只是不希望用户甚至知道桶(或 BST))。