【问题标题】:How to maximize the number of elements per btree node如何最大化每个 btree 节点的元素数量
【发布时间】:2015-06-11 01:46:54
【问题描述】:

我正在从一些数据构建一个 btree。一旦我构造了 btree(即插入所有元素),我就不再插入或删除元素。但是,从某种意义上说,如果我可以非常频繁地为每个节点拥有 n 个最大元素,那么生成的 btree 并不是最优的,那么我的节点包含的元素少于 n 个(n越大,问题就越严重> 是)。这是我的 btree 中的一个部分,包含数百个元素并且 n 等于 5。该部分包含根节点和几个最底部的节点

如您所见,不少节点的元素数少于 5 个。我的问题是: 有没有办法在构建后“压缩”btree,以便所有(可能除了一些最底部的节点)都包含准确的 n 元素。将作为键存储在节点中的内容将是 32 位值,但我不能保证它们会以任何特定顺序插入。

【问题讨论】:

  • 我没有时间阅读这篇论文,但是您能否改变构建 btree 的方式以使其在构建期间变得紧凑? sciencedirect.com/science/article/pii/0020019083900844
  • 这表明你可以在线性时间内从头开始构建一个紧凑的 btree(在顶部的摘要中):cpsc.yale.edu/sites/default/files/files/tr167.pdf
  • 那些论文谈论“按顺序”插入键,我不能保证。我想我可以在第一个之后重建我的 btree(因为我会知道顺序)但这会占用很多内存......如果没有其他方法,我会这样做......
  • 您的数据来自哪里?
  • 问题是我有不止一个 b​​tree 同时获取密钥。密钥在 btree 之间共享,但我只能保证第一个 btree 的顺序。其余的都不是,因为说碰巧插入到我的第一个 btree 中的第一个键(将是 0)可能是我的第二个 btree 中的第 25 个键(它仍然是零,但我已经有 25 个其他值了那里...)

标签: algorithm b-tree


【解决方案1】:

如果获取打包 btree 的经典方法不可行,因为键/记录未按键顺序传递,那么基本上有两种选择:

  • 离线:从头开始构建一个新的打包 btree
  • 在线:使用与节点拆分相反的过程就地压缩 btree

构建新的 btree 更简单、更快捷,并且可以“几乎”就地完成。唯一的额外空间要求包括 btree 的每一级的一个页面(或页面缓冲区),以容纳正在构建的新 btree 的右脊椎。旧树的页面清空后可以立即为新树回收。

这种方案通常被称为“金字塔”方案或“自下而上包装”。不用说,它要求 btree 在打包期间完全脱机,或者根据查询的键将查询分派到正确的树(旧的或新的)的函数。

在线压缩使用基本相同的逻辑,只是细节有点不同,因为键(记录)是从右邻居而不是从输入中提取的。树必须逐层压缩,从底部向上,从最左边的叶子开始:

  • 从父节点下拉分隔键
  • 从右邻居获取密钥,直到此节点已满
  • 向上推右邻居的新最左键作为分隔符
  • 将正确的邻居设为当前节点,冲洗并重复

两种方案 - 打包构建和在线压缩 - 可能会使树右脊上的节点填充不足甚至是空的。如果这不是可取的,那么可以通过在关卡的最后两个节点之间重新分配密钥来修复它。这可以通过调用在正常 btree 操作中使用的相同借用/平衡过程来完成。就像打包和压实一样,这种脊柱再平衡必须从下往上进行。 IE。从最右边的叶子向上到根。

【讨论】:

  • 感谢您的回答!你能给我指出一些关于在线方法的文献吗?我真的找不到任何东西,并使用非饱和节点的任何子节点上的拆分过程自上而下编写了类似的代码(并重复出现,直到树不再改变)。关于离线方法,经典方法是我的问题的cmets中的两篇论文中描述的方法?
  • 谷歌搜索“B-tree 批量加载”应该会给你很多关于离线方法背后的想法的信息,比如this video by Jens Dittrich。 Missie 链接的Rosenberg/Snyder paper 包含详细的描述和伪代码,但它使事情变得非常复杂(以至于它根本没有多大帮助)。关键点是更改 btree 节点可能会在树中产生向上冒泡的影响,这就是您必须工作的原因
  • 自下而上一层一层地,这样完成的页面就不会冒泡更改,并且与您打包它们时完全一样。构建打包树和一般批量加载之间的唯一区别是您将所需的页面利用率设置为 100%。该算法的核心是:尝试将传入的密钥附加到最右边的叶子页面(在验证它大于树的当前最大密钥之后);如果最右边的页面已满,则添加一个空页面作为新的最右边页面,并尝试以完全相同的方式将键附加到下一个更高级别。
  • 我从未见过任何地方描述的在线方法,可能是因为它是对批量加载背后的想法的简单扩展,并且因为它几乎没有学术兴趣。我对它进行了编码,因为我发现它是一种更简单的方法,可以在压缩过程中继续提供查找功能,与我的帖子中暗示的“旧树 + 新树 + 调度程序”方案相比。后者在一些论文中有所描述,但主要是为需要周期性重建树结构的算法获得良好的摊销复杂性界限的噱头。
  • 我接受您的回答,因为据我所知,根据您的回答和您给我的指示,我无法比所描述的解决方案做得更好。谢谢。
猜你喜欢
  • 2013-04-23
  • 2017-10-28
  • 2015-06-29
  • 2013-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-17
相关资源
最近更新 更多