基于范围的数据结构的密钥查找

时间:2011-07-27 23:05:04

标签: data-structures

例如,如果我有以下情况

  1. 如果键的范围是1-4,则选择A.
  2. 如果键的范围是5-6,则选择B.
  3. 如果有一个请求获取say,key = 2的值,那么我应该返回A,为5,返回B,依此类推。保持这种关联的良好数据结构是什么?我可以通过存储1-A,2-A,3-A,4-A,5-B和6-B来创建哈希映射,但是想要检查是否有更好的方法来实现这一点。

4 个答案:

答案 0 :(得分:2)

对范围中的每个项目使用哈希映射似乎过于宽泛,如果范围是(1-2 ^ 20)怎么办?如果它是一个双重怎么办?存放这些东西太贵了。

您可以使用普通的跳过列表/树,其中包括每个范围的下限和上限。请注意,当在二叉树中搜索某个值时,如果它不存在,搜索将在搜索之前/之后的下一个值处结束,例如:如果您有范围键1,4,则搜索3 ,当你达到1或4时,搜索将结束。所以我们可以在树中存储范围的上/下界。

现在,我们还需要为这些中的每一个存储真实范围(因此,如果我们有1-4,8-​​9并且我们搜索7,那么当我们达到4/8时我们就会知道它无效)。因此,如果密钥在合法范围内,我们将在搜索时达到其上限/下限!

总而言之,只需在搜索时添加下限和上限,搜索键,然后查看绑定是否匹配。

ops应该是那样的(伪代码):

add (lower,upper,value):
   tree.add(lower/*key*/,(lower,upper,value))
   tree.add(upper/*key*/,(lower,upper,value))
search (key):
   node = tree.search(key)
   if node.lower <= key <= node.upper: 
      return node.value
   return KEY_NOT_IN_TREE_ERROR
del(lower,upper):
  tree.del(lower)
  tree.del (upper)

这些操作中的每一个都是O(logn),慢于哈希,但它会占用更少的空间。

答案 1 :(得分:1)

您可以创建一对<interval,associated value>并构建segment tree。它可以在重叠间隔下正常工作。

如果间隔从不重叠,它仍然可以正常,因为片段树比基于散列的解决方案需要更少的内存。如果范围很宽,任何普通结构都需要大量内存。

编辑:我意识到,通常的矢量可以比哈希更适合您的目的,以防间隔彼此靠近。

答案 2 :(得分:1)

阿米特是对的。对于不重叠的范围,简单的有序数据结构就足够了。更清楚一点:

按照最小边界对范围进行排序。在搜索时,通过树进行闪电检查以查看您是否在您遍历的每个节点的范围内。

答案 3 :(得分:0)

使用类的对象作为hashmap的键存储会更好。

在课堂上,你可以将Fields定义为upperbound,lower bound,并且应该覆盖equals和hashCode方法。

在equals中,您可以编写逻辑来比较密钥对象的上限和下限位于this.upperbound和this.lower bound之间。

要获取值,请使用相同的upperbound = lowerbound = key_val;

创建关键对象
相关问题