我正在阅读论文making B+-trees cache conscious in main memory。在第3.1.2节中,作者描述了在CSB +树节点内进行搜索的几种方法。
Tha 基本的方法是使用传统的while循环进行二进制搜索。
统一方法是通过代码扩展,将while循环展开到if-then-else
语句中,假设使用了所有密钥。
作者给出了以下示例,该示例展示了对具有最多9个键的节点的搜索的展开。节点中的数字表示在if
测试中使用的密钥的位置
4
/ \
2 6
/ \ / \
1 3 5 8
/ \
7 9
然后是令人困惑的部分:
如果实际只有5个键,我们可以通过 3 比较来遍历这个树。另一方面,将最深的子树放在左侧而不是右侧的展开需要在某些分支上进行 4 比较。
那么为什么它需要在下面的树中进行更多的比较:
6
/ \
4 8
/ \ / \
2 5 7 9
/ \
1 3
此外,
如果我们知道我们只有五个有效密钥,我们可以硬编码一棵树,平均而言,使用 2.67 比较而不是3。
2.67 是如何产生的?
任何提示都将不胜感激。此外,指向代码扩展知识的链接也会有所帮助。
实际上,我不确定在纸上提问是否合适是因为在这里转录时可能遗漏了一些关键信息(问题可能需要重新格式化)。我只是希望有人碰巧阅读了这篇论文。
由于
答案 0 :(得分:1)
这里的关键点是以下同一部分的引文:
我们填补所有 节点中未使用的密钥(keyList [nKeys..2d-1]) 使用最大可能的密钥
同样重要的是,在B + / CSB +树中,我们不搜索节点值,而是搜索这些值之间的间隔。一组可能的值被5个键分成6个区间。
由于大多数正确的子树都填充了最大可能的密钥(L),因此我们需要比平常更少的比较:
4
/ \
2 L
/ \ / \
1 3 5 L
/ \
L L
根节点的右后代具有最大可能的密钥,不需要检查其右侧的任何节点。每个区间都需要进行3次比较:
interval comparisons
up to 1 k>4, k>2, k>1
1..2 k>4, k>2, k>1
2..3 k>4, k>2, k>3
3..4 k>4, k>2, k>3
4..5 k>4, k>L, k>5
5..L k>4, k>L, k>5
如果我们把最深的子树放在左边,我们就有一棵树,非空节点放在一层更深的地方:
L
/ \
4 L
/ \ / \
2 5 L L
/ \
1 3
在此树中搜索节点“1”需要将密钥与4个不同的节点进行比较:L,4,2和1.
如果我们知道我们只有五个有效密钥,那么我们有以下树:
2
/ \
1 4
/ \
3 5
在这里,我们可以安排比较,平均得出2.67比较:
interval comparisons
up to 1 k>2, k>1
1..2 k>2, k>1
2..3 k>2, k>4, k>3
3..4 k>2, k>4, k>3
4..5 k>2, k>4, k>5
5..L k>2, k>4, k>5
“代码扩展”不是一个广泛使用的术语,所以我不能给你最相关的链接。我认为,这与"Loop unwinding"没有什么不同。