如果我有一堆以下数据,我应该使用哪种数据结构:
MyData
{
float ValueA;
float ValueB;
object OtherInfo;
}
我需要快速找到符合此类条件的所有MyData
个实例:
0.5 <= ValueA <= 0.7 AND 0.2 <= ValueB <= 0.9
找到这些项目很简单,但我需要尽快完成。是否有适合这种情况的数据结构?我不介意用尽额外的记忆。
我目前的想法是有一个排序列表,按ValueA排序。然后我会进行二分搜索以找到具有ValueA&gt; = 0.5的第一个项目,并迭代直到我得到一个具有ValueA&gt;的项目。 0.7。对于每次迭代,我检查ValueB是否介于0.2和0.9之间。我将所有匹配项放在输出数据集中。
有更好/更快的方法吗?
顺便说一句,我正在使用C#。
答案 0 :(得分:3)
interval tree符合您的需求。示例实现(我尚未测试)at Codeplex。更多here。
更新:区间树与相关结构(段树)的比较如下:What are the differences between segment trees, interval trees, binary indexed trees and range trees?
答案 1 :(得分:2)
您的问题是二维的,但您只是在一个维度上优化搜索空间。 quadtree是适当的数据结构;你应该没有困难在C#中找到合适的实现。如果您想要其他替代方案,那么只需搜索2D空间分区算法。这基本上就是你在这里做的事情; ValueA和ValueB可以被视为2D坐标,即使它们不是它们实际代表的那些。
答案 2 :(得分:2)
您可以使用单个列表执行此操作,该列表首先在ValueA上排序,然后在ValueB上排序。所以,如果你有这些项目:
A B
{0.5, 0.7}
{0.3, 0.1}
{0.5, 0.2}
{0.5, 0.4}
{0.2, 0.3}
您可以在列表中订购:
{0.2, 0.3}
{0.3, 0.1}
{0.5, 0.2}
{0.5, 0.4}
{0.5, 0.7}
在LINQ中按两个条件排序非常简单:
var sortedList = theList.OrderBy(s => s.ValueA).ThenBy(s => s.ValueB).ToList();
您还可以通过将自定义比较委托传递给Sort方法来就地排序列表。
现在,根据搜索:0.5 <= ValueA <= 0.7 && 0.2 <= ValueB <= 0.9
,您可以执行以下操作:
startA
endA
[startA..endA]
,查找第一个值>&gt; = 0.2的ValueB。请拨打此startB
。[startA..endA]
以查找最后一个&lt; = 0.9的ValueB。请拨打此endB
。您要查找的项目位于[startB..endB]
区间。
请注意,如果您要迭代[startB..endB]
范围内的所有项目,则不必执行最后一次二进制搜索,因为您可以在迭代期间将其过滤掉。
答案 3 :(得分:1)
在此解决方案中,我将数据合并到列表中,其中每个列表包含widthX by widthY框内的所有数据点。如果您的数据在valA=[0,1], valB=[0,2]
范围内,并且您将网格划分为.1个.1个bins(如代码所示),则searchList(4,12)
是一个包含所有值的列表,{{1} }和.4 <= valA <= .5
此解决方案仅对相当紧凑的相当大的输入数组有效。如果有任何极端异常值,您将创建许多不必要的箱。
如果查询是在“自然”(I.E. .1,.01)边界上,则效果最好,但这不是必需的。您必须手动循环1.2 <= valB <= 1.3
以过滤掉不需要的元素。
搜索查询非常简单 - 在每个维度上找到你的最小/最大分档,并循环遍历其间的所有分档。
searchList(i,j)