可以快速返回子阵列的已排序时间序列数据的最佳数据结构?

时间:2009-04-17 15:56:58

标签: c# linq range sortedlist

我需要一个基本上是数据点列表的数据结构,其中每个数据点都有一个时间戳和一个double []的数据值。我希望能够检索到给定时间戳的最近点或指定时间戳范围内的所有点。

我正在使用c#。我的想法是使用常规列表是可能的,其中“datapoint”是一个包含timestamp和double []字段的类。然后插入,我将使用内置的binarysearch()来查找插入新数据的位置,我可以再次使用它来查找范围搜索的开始/结束索引。

我首先尝试了排序列表,但似乎你不能通过索引来迭代索引i = 0,1,2,...,n,所以我不知道怎么做范围搜索而不用一些错综复杂的功能。

然后我了解到列表<>的insert()是o(n)...我不能做得更好而不牺牲其他地方吗?

或者,是否有一些不错的linq查询可以在一行中完成我想要的所有内容?

4 个答案:

答案 0 :(得分:1)

如果您愿意使用非BCL库,C5.SortedArray<T>对我来说一直都很好。

它有一个很好的方法RangeFromTo,可以很好地解决这类问题。

答案 1 :(得分:1)

如果您有仅静态数据,那么实现IList的任何结构都应该没问题。对它进行排序一次,然后使用BinarySearch进行查询。如果插入的时间戳总是在增加,这也应该有用,那么你可以在O(1)中执行List.Add(),它仍然会被排序。

    List<int> x = new List<int>();
    x.Add(5);
    x.Add(7);
    x.Add(3);

    x.Sort();

    //want to find all elements between 4 and 6
    int rangeStart = x.BinarySearch(4);

    //since there is no element equal to 4, we'll get the binary complement of an index, where 4 could have possibly been found
    //see MSDN for List<T>.BinarySearch
    if (rangeStart < 0)
        rangeStart = ~rangeStart;

    while (x[rangeStart] < 6)
    {
        //do you business
        rangeStart++;
    }

如果您需要在结构中在随机点插入数据,请保持其排序并能够快速查询范围,您需要一个名为B+ tree的结构。它没有在框架中实现,你需要自己在某个地方实现它。

  

在最坏的情况下插入记录需要O(log n)操作

     

在最坏的情况下找到记录需要O(log n)操作

     

删除(以前定位的)记录需要在最坏的情况下执行O(log n)操作

     

在最坏的情况下,执行范围内出现k个元素的范围查询需要O((log n)+ k)操作。

P.S。 “有一些不错的linq查询可以在一行中完成我想要的任何事情”

我希望我知道这样一个很好的linq查询可以在一行中完成我想要的任何事情: - )

答案 2 :(得分:0)

您可以选择插入,检索或删除时的成本。针对这些情况中的每一种都优化了各种数据结构。在你决定一个之前,我会估计你的结构的总大小,生成的数据点数(以及在哪个频率下)以及更常用的内容:插入或检索。

如果您以高频率插入大量新数据点,我建议您查看LinkedList&lt;&gt ;.如果你经常检索,我会使用List&lt;&gt;即使它的插入时间较慢。

当然你可以在LINQ查询中做到这一点,但请记住这只是糖涂层:查询将每次执行并且每次执行搜索整个数据点集以查找匹配。这可能比首先使用正确的工作集合更昂贵。

答案 3 :(得分:0)

如何使用实际数据库存储数据并针对该数据运行查询? 然后,您可以使用LINQ-to-SQL

相关问题