我目前正在为一个项目构建ScapeGoatTree。但是我在获取重建功能以正确掌握正在构建的替罪羊节点时遇到问题。在下面的代码中,您将在'if(height> alpha height)'语句中看到另外2个if语句。第一个if语句比较我的替罪羊节点(我知道当前测试数据应该是静态root.left节点),并且正确地说它们相等。但是,当我尝试更改“占位符”节点(希望它应该是对root.left的对象引用)时,它只会覆盖我的占位符节点。因此第二条if语句不会触发,但是我需要FindScapeGoat的返回值成为要编辑的节点。
我不会撒谎,我一直不太会理解语言中的引用传递和值传递差异,但是我确实需要弄清楚如何正确地将更改应用于root.left而不需要对其进行特定的调用(因为该函数将不会总是选择root.left作为替罪羊节点,因此我需要一种方法来调用树中以静态位置为根的各个节点)。
public static void Insert(int key) {
height = dupflag = 0;
root = insertHelp(root, key);
if(dupflag == 0) MaxNodeCount++; //If inserted value wasn't duplicate increase max node count
double alphaHeight = ((Math.log(MaxNodeCount) / Math.log(1 / alpha)) + 1);
if (height > alphaHeight){
Node ToBeRebalanced = FindScapegoat(root, key); // Find scapegoat node
int sizeRoot = TreeSize(ToBeRebalanced, 0);
if(ToBeRebalanced == root.left) System.out.println("Scapegoat node == root.left");
ToBeRebalanced = RebuildTree(sizeRoot+1, ToBeRebalanced);
if(ToBeRebalanced == root.left) System.out.println("Scapegoat node == root.left");
Print(ToBeRebalanced);
Print(root);
}
}
答案 0 :(得分:0)
要解决值/引用问题:Java中的非原始变量的行为(通常是大的警告,超出了此答案的范围)类似于指向内存位置的指针。当您说ToBeReplaced
时,您正在更改ToBeReplaced
指向的内存地址。
对于您更具体的问题,有两种解决方法。我要处理的方式是更改FindScapegoat
的返回值以指示该节点是左侧还是右侧。似乎只在检查直接子节点,因此无需返回对节点本身的引用。
类似这样的东西:
public enum Side {
LEFT,
RIGHT
}
//...
Side ToBeRebalanced = FindScapegoat(root, key); // Find scapegoat node
if (ToBeRebalanced == Side.Left){
int sizeRoot = TreeSize(root.left, 0);
root.left = RebuildTree(sizeRoot+1, root.left);
} else {
int sizeRoot = TreeSize(root.right, 0);
root.right = RebuildTree(sizeRoot+1, root.right);
}
然后,您可以将TreeSize
调用移至RebuildTree
方法中,以避免重复的代码。