在一个时间范围内有效的对象的搜索列表

时间:2015-06-10 02:33:36

标签: javascript algorithm range binary-search-tree b-tree-index

我有以下数据结构,它描述了一个对象及其有效的时间段。假设下面的数字是unix时间戳。

{
  "id": 1234,
  "valid_from": 2000
  "valid_to": 4000
},
{
 "id": 1235,
 "valid_from": 1000,
 "valid_to": 2200,
}
...

我希望能够快速将这些项目存储在JavaScript中,然后查询在特定时间有效的项目。

例如,如果我要查询2100年有效的对象,我会得到[1234,1235]。如果我要查询有效在3999的对象,我会得到[1234],而在4999没有。

我将在结构中拥有大约50-100k项目的大小,我希望快速查找速度但插入和删除可能会更慢。

项目将具有重复的valid_from和valid_to值,因此它需要支持重复项。项目将重叠。

我需要不断地将数据插入到结构中(可能通过批量进行初始加载,然后在数据更改时进行一次更新)。我还会定期修改记录,以便删除和插入。

我不确定以最有效的方式解决这个问题的最佳方法是什么?

算法不是我的强项,但如果我只知道正确的方法,我可以自己研究算法。

我的想法:

我最初想的是修改后的二进制搜索树,以支持重复键和最接近的查找,但这只允许我查询>对象。 valid_from或<失效日期。

这将涉及我将数组或树二等分以查找所有项目> valid_from然后手动检查每一个是否为valid_to。

我想我可以有两个搜索树,一个用于valid_to和valid_from,然后我可以检查结果中的哪个ID重叠并返回那些id?

这对我来说似乎还有些什么?是否有人可以推荐更好的方法,或者这是怎么做的。

1 个答案:

答案 0 :(得分:0)

想象一下,您有两个列表:启动/开始和到期/结束。两者都按时间排序。

给定特定时间,您可以通过二分查找找到每个列表中第一个符合条件的项目。您也可以通过二进制搜索将插入插入到每个列表中。

例如,如果有1000个项目并且开始位置是342,则项目1-342是可能的,并且如果结束位置是901,则终止列表中的项目901-1000是可能的。您现在需要与两个子列表相交。

从开始时的1-342和最后的901-1000中取项目ID,并将它们放在一个单独的数组中(提前分配)。对数组进行排序。遍历阵列。每当相同的ID连续出现两次时,它就是一个命中,一个有效的匹配。