【发布时间】:2014-07-01 07:21:06
【问题描述】:
我正在尝试在 C++ 中实现可扩展散列
有一个结构体充当索引,它包含一个“桶”类型的数组
Bucket * bucket_pointers;
还有另一个结构,Bucket,它有一个数组,用来保存我的值
E values[N] = {};
我有一个或多或少的工作程序,但有一个问题:每次我将哈希表的大小加倍时,我都会将所有存储桶复制到一个新数组中(大小的两倍)
Index_0
Bucket <n= 3, local_depth=2, 0x100200000>
[12,4,,8,]
Index_1
Bucket <n= 0, local_depth=1, 0x100200028>
[,,,,]
Index_2
Bucket <n= 3, local_depth=2, 0x100200050>
[2,10,6,,]
Index_3
Bucket <n= 0, local_depth=1, 0x100200078>
[,,,,]
但是,地址为 0x100200078 的 Bucket 实际上应该指向地址为 0x100200028 的 Bucket,即两个索引(1 和 3)应该指向同一个 Bucket。
我在这里决定是拆分存储桶还是将索引大小增加一倍...
while (!bucket_pointers[h%index_size].append(e)){
if(bucket_pointers[h%index_size].local_depth<global_depth){
split(hashValue);
}
else if(bucket_pointers[h%index_size].local_depth==global_depth){
resize();
}
}
我目前正在像这样将数组的大小增加一倍:
for (size_t i = 0; i < index_size; ++i){
for (size_t j = 0; j < bucket_pointers[i].n; ++j){
newBucket_pointers[i] = bucket_pointers[i];
newBucket_pointers[i+index_size] = bucket_pointers[i];
}
}
【问题讨论】:
-
我认为我们需要查看更多代码。您是否考虑过将 std::vector 用于可扩展哈希表?它会为您完成所有工作。
-
嗨,理查德,感谢您的评论,我已经编辑了答案以添加更多代码。好吧,这当然会更容易!但是,我正在尝试学习 C++,所以在这种情况下,这不是一个选择。
-
也许我没有正确阅读代码,或者你只是在做这件事有点不同,但至少出现你遇到了一个相关的问题(并且可能还不知道)是您在新表中重新安装节点的方式。节点的最终哈希索引(通常)基于 表大小 的模数。如果要将表的大小加倍,则需要重新散列每个节点以计算(希望有 50% 的可能性)给定节点在扩展表中具有新家的可能性。批量复制数组是行不通的(再次,如果我在你的代码上留了空间,我深表歉意)。
-
我同意这一点。我还关心一个桶中的固定数量的地方。您是否打算在每次存储桶填满时添加索引?
-
嗯,发生了两件事:我要么调整我的哈希表的大小(加倍),要么我正在拆分一个桶(这也是我重新散列每个节点的地方。确切地说,那是我是如何理解“可扩展散列”的。有一个固定的桶大小,每次一个桶填满时,我要么:拆分桶,要么加倍我的哈希表,然后拆分桶(取决于全局和本地深度)
标签: c++ arrays pointers hashtable