搜索大量排序的数据块

时间:2011-03-07 22:50:47

标签: c++ algorithm search binary-search

我在磁盘中有大量的数据记录,这些记录按照某些键排序。 数据一次被读入一个块(数千条记录)。 我必须搜索并显示与键匹配的所有记录。 我在想一些基于二进制搜索的算法,但我在这里有一些限制。

  1. 记录只能在块开始的一个块内顺序查找。
  2. 使用相同键的记录可以跨越多个块(如图所示 - 8个跨度)。在二进制搜索中,如果我正在加载中间块并且第一条记录匹配,那么我必须这样做 扫描匹配块之前的块。
  3. 有人可以帮助我设计一个可以在C ++中运行的有效策略。使用线性搜索方法是否有效。

    +---+
    | 1 | Block1
    | 3 |
    | 3 |
    | 4 |
    +---+
    | 4 | Block2
    | 6 |
    | 7 |
    | 8 |
    +---+
    | 8 | Block3
    | 8 |
    | 8 |
    | 8 |
    +---+
    | 8 | Block4
    | 14|
    | 15|
    | 16|
    +---+
    

4 个答案:

答案 0 :(得分:4)

您的想法,使用二进制搜索,是正确的。您可以通过保存每个节点中的最小值和最大值来完全避免线性扫描。在您的示例中,构造的二元搜索树将如下所示:

Block1    <- (1,4)
                    (1,8)
Block2    <- (4,8)
                          (1,16)
Block3    <- (8,8)
                    (8,16)
Block4    <- (8,16)

....

同时具有最大值和最小值可以有效地计算更高的节点。在您的示例中,如果您要搜索“8”,您将进入...-&gt; ...-&gt; ...-&gt;(1,16) - &gt;(1,8) - &gt; (4,8),所以你找到了正确的块,而没有向后寻求并以最有效(log(n))正确的方式。

答案 1 :(得分:4)

您可以构建一个辅助数组,该数组由每个块中的第一个条目组成,然后在该数组上运行二进制搜索。数组的索引应直接与块索引对应,使其成为O(1)查找以获得相应的块。

它将最坏的情况从O(n)切换到O(logn),并且仍然相对简单。

答案 2 :(得分:2)

这是一个众所周知的问题,有一个众所周知的数据结构可以解决它,主要用于数据库:)

我们的想法是使用B+ Tree

这个想法是在结构的顶部叠加一种二进制搜索树(除了每个节点有超过2个子节点)以进行搜索。

答案 3 :(得分:1)

如果您对密钥分发有任何想法,可以通过猜测要检查的第一个位置来改进二进制搜索。作为样本,使用“名称”键和值“Bob”,您可以近似“B”所在的位置,或者简单地基于字母表中的位置,或者更复杂地使用关键字的特定领域知识(首先是分配频率)英文名字中的字符例如)

无论哪种方式,二进制搜索都是可行的方式,可选择使用第一个键入块预加载或缓存 - 就像你看到它们一样。