【问题标题】:BTree- predetermined size?BTree-预定大小?
【发布时间】:2011-12-08 07:02:51
【问题描述】:

我在维基百科上读到这个:

在 B 树中,内部(非叶)节点可以有可变数量的 某些预定义范围内的子节点。当数据被插入或 从节点中删除,其子节点的数量会发生变化。为了 保持预定义的范围,内部节点可以加入或拆分。 因为允许有一定范围的子节点,所以不需要 B 树 与其他自平衡搜索树一样频繁地重新平衡,但是 可能会浪费一些空间,因为节点未完全填满。

我们必须为 B 树指定这个范围。即使当我查看 CLRS(算法简介)时,它似乎也使用数组作为键和子元素。我的问题是 - 有没有办法通过将键和子项定义为列表而不是预定数组来减少这种空间浪费?是不是太麻烦了?

另外,在我的一生中,我无法在 btreeDeleteNode 上获得像样的伪代码。在这里的任何帮助也很感激。

【问题讨论】:

  • 请尝试一次只问一个问题。

标签: algorithm b-tree


【解决方案1】:

当您说“列表”时,您是指链表吗?

某种元素的数组在每个插槽中占用一个元素的内存,无论该插槽是否已填充。链表只占用它实际包含的元素的内存,但对于每个元素,它占用一个元素的内存,加上一个指针的大小(如果是双向链表,则为两个,除非您可以使用 xor 技巧将它们重叠)。

如果您要存储指针并使用单链表,则每个列表链接的大小是每个数组槽的两倍。这意味着除非列表未满一半,否则链表将使用更多内存,而不是更少。

如果您使用的语言的运行时具有每个对象的开销(如 Java 和 C ,除非您自己处理内存分配),那么您还必须为每个列表链接支付开销,但仅限一次在数组上,比例更差。

我建议您的平衡算法应保持树节点至少半满。如果在一个节点已满时拆分它,您将创建两个半满节点。然后,您需要在相邻节点不到半满时合并它们。然后,您可以使用数组,知道它比链表更有效。

不知道删除的细节,抱歉!

【讨论】:

  • 通过保持 B 树至少半满来平衡 B 树不仅仅是一个建议 - 这是法律!
【解决方案2】:

B-Tree 节点有一个重要的特性,节点中的所有键都是有序的。查找特定键时,使用二进制搜索来查找正确的位置。使用二分查找保持了 B-Tree 中查找算法的复杂度O(logn)

如果你用某种链表替换预先分配的数组,你就会失去排序。除非你使用一些复杂的数据结构,比如跳过列表,来保持搜索算法与O(logn)。但这完全没必要,跳过列表本身更好。

【讨论】:

  • 感谢@Sumit Singh 的编辑。我很新鲜,还在学习相关技能。
猜你喜欢
  • 1970-01-01
  • 2013-10-09
  • 2011-07-02
  • 1970-01-01
  • 1970-01-01
  • 2017-01-23
  • 1970-01-01
  • 2011-05-29
  • 2011-05-13
相关资源
最近更新 更多