C++ 搜索大量已排序的数据块
我在磁盘上有大量的数据记录,这些记录是根据一些键按顺序排列的。 数据一次读取一个块(数千条记录)到内存中。 我必须搜索并显示所有与密钥匹配的记录。 我在考虑一些基于二进制搜索的算法,但这里有一些限制C++ 搜索大量已排序的数据块,c++,algorithm,search,binary-search,C++,Algorithm,Search,Binary Search,我在磁盘上有大量的数据记录,这些记录是根据一些键按顺序排列的。 数据一次读取一个块(数千条记录)到内存中。 我必须搜索并显示所有与密钥匹配的记录。 我在考虑一些基于二进制搜索的算法,但这里有一些限制 只能从块的开头开始在块内按顺序查找记录 具有相同键的记录可以跨越多个块(如图8所示)。在二进制搜索中,如果我正在加载中间块,并且如果第一条记录匹配,那么我必须 扫描匹配块之前的块 有人能帮我设计一个可以在C++中工作的有效策略。使用线性搜索方法是否有效 +---+ | 1 | Block1 | 3
+---+
| 1 | Block1
| 3 |
| 3 |
| 4 |
+---+
| 4 | Block2
| 6 |
| 7 |
| 8 |
+---+
| 8 | Block3
| 8 |
| 8 |
| 8 |
+---+
| 8 | Block4
| 14|
| 15|
| 16|
+---+
您使用二进制搜索的想法是正确的。通过保存每个节点中的最小值和最大值,可以避免线性扫描。在您的示例中,构建的二进制搜索树如下所示:
Block1 <- (1,4)
(1,8)
Block2 <- (4,8)
(1,16)
Block3 <- (8,8)
(8,16)
Block4 <- (8,16)
....
Block1(1,8)->(4,8),因此您可以找到正确的块,而无需以最有效(log(n))的正确方式向后搜索。您可以构建包含每个块中的第一个条目的辅助数组,然后在该数组上运行二进制搜索。数组的索引应与块索引直接对应,使其成为O(1)查找以获得相应的块
它将最坏的情况从O(n)减少到O(logn),并且仍然相对简单。如果您对密钥分配有任何想法,可以通过猜测要检查的第一个位置来改进二进制搜索。作为示例,使用“Name”键和值“Bob”,您可以简单地根据字母表中的位置,或更复杂地根据键的特定领域知识(例如,英语名字中第一个字符的分布频率)来近似“B”的位置
无论哪种方法,二进制搜索都是可行的,可以选择在块预加载或缓存中使用第一个键。这是一个众所周知的问题,有一个众所周知的数据结构来解决它,主要用于数据库:)
这个想法是使用一个新的方法
其想法是在结构的顶部叠加一种二叉搜索树(每个节点有两个子节点除外)。您是否有(或允许您预先计算)任何类型的索引结构,可以保存在内存中?例如,每个块的起始值。我的第一印象是二进制搜索可能是最好的。如果第一条记录匹配,不管搜索方法如何,您都将检查上一个块(或者,等效地,您将匹配最后一条记录,并且必须检查下一个块)。。。不过,我很想看看其他人有什么想法。我可以预先计算索引。不过,您必须从磁盘加载每个块才能获得第一个条目。您可以直接对块执行二进制搜索,并仅加载logn
块。如果它将被反复搜索,并且额外的数组可以存储在某个地方,那么我喜欢你的想法,然而,我正在考虑这个问题。考虑到他的块看起来是固定大小的,他可能需要在任何时候向数组添加数据时移动数据,此时他可以获得第一个条目。