我在我的第一个学期学习并作为我的课程的一部分。科学作业我必须使用向量实现一个简单的哈希映射,但是我在理解这个概念时遇到了一些问题。
首先,我必须实现一个哈希函数。为避免冲突,我认为最好使用双散列,如下所示:
do {
h = (k % m + j*(1+(k % (m-2)));
j++;
} while ( j % m != 0 );
其中h是要返回的哈希值,k是键,m是hash_map的大小(和素数;它们都是int类型)。
这很简单,但我需要能够在地图中插入或删除一对键和相应的值。
两个函数的签名应该是bool,所以我必须返回true或flase,并且我猜测当向量中的位置h没有元素时我应该返回true。 (但我不知道为什么删除也应该是bool)。
我的问题是当insert函数返回false时要做什么(即,当位置h上已经保存了键值对时 - 我将其实现为名为find的函数)。通过简单地增加j,我显然可以将它移动到下一个空闲位置,但是由我的哈希函数计算的哈希不再告诉我们在某个地方保存某个键,导致删除函数的错误行为。
网上有没有好的例子,不使用预定义的STD方法? (我的谷歌在过去几天表现得非常糟糕,只能用当地语言重新燃起我无用的点击率)
答案 0 :(得分:2)
我被告知将我的评论移到答案所以就是这样。我假设你的get方法接受你正在寻找参数的值。
所以我们要做的是一个称为线性探测的过程。
当我们插入值时,我们将其哈希为正常,假设我们的哈希值为4
[x,x,x,,,x,x]
我们可以看到我们可以简单地将其插入:
[x,x,x,x,,x,x]
但是如果在我们插入它时采用4,我们将只移动到下一个空的插槽
[x,x,x,**x**,x,,x,x]
在线性探测中,如果我们到达终点,我们会循环回到开头,直到找到一个槽。当你使用一个可以在开始接近满容量时分配额外空间的向量时,你不应该用完空间
这会在您搜索时导致问题,因为4处的值可能不再是4(在本例中为5)。为了解决这个问题,我们做了一些黑客攻击。请注意,只要负载平衡低于1,我们仍然会在插入和检索时获得O(1)运行时复杂度。
在我们的get方法中,而不是在4中返回数组中的值,而是在4处开始寻找我们的值,如果它在那里我们可以返回它。如果不是,我们会查看5处的值,依此类推,直到找到值。
在 psudo代码中,新内容看起来像这样
bool insert(value){
h = hash(value);
while(node[h] != null){
h++;
if( h = node.length){
h = 0;
}
}
node[h] = value;
return true;
}
获取
get(value){
h = hash(value);
roundTrip = 0; //used to see if we keep going round the hashmap
while(true){
if(node[h] == value)
return node[h];
h++;
if( h = node.length){
h = 0;
roundTrip++;
}
if(roundTrip > 1){ //we can't find it after going round list once
return -1;
}
}
}