我读到B树和B *树之间的唯一区别是填充因子。 B树的最小填充因子是1/2,B *树的最小填充因子是2/3。
因此,对于B树,您拥有的最大键数和子项数是2 *度(节点中的最小元素数)。如果我的最小填充因子为3,那么节点可以拥有的最多键是6.该逻辑给了我:
keyHolder = new int[2 * degree - 1];
children = new BTreeNode[2 * degree];
这很好用,我的B-Tree按预期工作。因此,当我将B-Tree修改为B *树时,我认为子项和键的最大数量必须为(3 *度)/ 2。这给了我这个:
keyHolder = new int[((3 * degree)/2) - 1];
children = new BStarTreeNode[(3 * degree)/2];
问题:
但是,现在,当我尝试从temp复制键时,split子方法抛出数组超出范围异常:
temp.keyHolder[j] = node.keyHolder[j + degree];
问题:
我不是真的问为什么代码不起作用,而是我的逻辑出了什么问题。如果两棵树之间的唯一区别只是填充因子,那么将一个树转换为另一个树的唯一方法就是更改给定节点的键和子元素的最大数量吗?其他一切,包括如何在根满了之后将节点分开,应该保持不变。您只需要更改分割发生的最大限制吗?
感谢您提前提供任何帮助。
相关代码:
我将splitChild方法放在下面,以防它有用:
public void splitChild(int i, BStarTreeNode node) {
BStarTreeNode temp = new BStarTreeNode(node.degree - 1, node.leaf);
temp.numKeys = degree - 1;
// Copy the degree-1 keys into temo from node
for (int j = 0; j < degree - 1; j++) {
temp.keyHolder[j] = node.keyHolder[j + degree];
}
// If this node is not a leaf, copy the degree children
if (node.leaf == false) {
for (int j = 0; j < degree; j++) {
temp.children[j] = node.children[j + degree];
}
}
// Reduce the number of keys in node
node.numKeys = degree - 1;
// Since this node is going to have a new child,
// create space of new child
for (int j = numKeys; j >= i + 1; j--) {
children[j + 1] = children[j];
}
// Link the new child to this node
children[i + 1] = temp;
//Find location of
// new key and move all greater keys one space ahead
for (int j = numKeys - 1; j >= i; j--) {
keyHolder[j + 1] = keyHolder[j];
}
// Copy the middle key of node
keyHolder[i] = node.keyHolder[degree - 1];
// Increment count of keys in this node
numKeys = numKeys + 1;
}
我写的代码来自here。我只是用Java重写了它。
答案 0 :(得分:1)
每个节点的最大密钥数不会改变。它仍然是 2N 。您必须拆分和加入的条件会发生什么变化。
拆分完整节点时,必须从先前节点和后续节点获取密钥,以便两个新节点满足n >= 2*N/3
,相反,在加入时,必须将密钥分发回先前节点和后续节点,如你将只有一个节点有太多的密钥。