我在维基百科上看到了这个:
在B树中,内部(非叶子)节点可以具有可变数量的节点 某些预定义范围内的子节点。插入数据或时 从节点中删除,其子节点数发生变化。为了 保持预定义的范围,内部节点可以连接或拆分。 因为允许一系列子节点,所以不需要B树 像其他自平衡搜索树一样频繁地重新平衡,但是 可能会浪费一些空间,因为节点并不完整。
我们必须为B树指定此范围。即使我查阅了CLRS(算法简介),似乎也可以将数组用于键和子项。我的问题是 - 有没有办法通过将键和子项定义为列表而不是预定的数组来减少空间中的浪费?这太麻烦了吗?
另外,对于我的生活,我无法在btreeDeleteNode上获得一个像样的psedocode。这里也有任何帮助。
答案 0 :(得分:2)
当您说“列表”时,您的意思是链接列表吗?
某个元素的数组占用每个插槽一个元素的内存,无论该插槽是否已填充。链表只占用它实际包含的元素的内存,但对于每个元素,它占用一个元素的内存,加上一个指针的大小(如果它是双向链表,则为两个,除非你可以使用xor技巧重叠它们。)
如果要存储指针并使用单链表,则每个列表链接的大小是每个数组插槽的两倍。这意味着除非列表小于半满,否则链表将使用 more 内存,而不是更少。
如果你使用的语言的运行时有每个对象的开销(比如Java,除非你自己处理内存分配),那么你还必须在每个列表链接上支付这笔开销,但仅限于一旦在阵列上,比率就更差了。
我建议你的平衡算法应该保持树节点至少半满。如果在节点已满时拆分节点,则将创建两个半满节点。然后,当它们小于半满时,您需要合并相邻节点。然后,您可以使用数组,因为它比链表更有效。
不知道删除的细节,抱歉!
答案 1 :(得分:1)
B-Tree节点具有重要特性,节点中的所有键都已排序。找到特定键时,二进制搜索用于查找正确的位置。使用二分搜索可以在B-Tree O(logn)
中保持搜索算法的复杂性。
如果使用某种链表替换预分配的数组,则会丢失排序。除非您使用一些复杂的数据结构(如跳过列表),否则将搜索算法保留为O(logn)
。但这完全没必要,跳过列表本身就更好。