我用Java创建了一个二叉搜索树,但是我在删除节点部分时遇到了麻烦。当它只有1个儿子的时候我设法擦除了节点,并且我有想法在它有2个儿子时进行删除,无论如何我没有儿子时使用的方法(当它是一片叶子时)不起作用Java的。通常在C ++中我会将Node指定为“null”,但它在这里不起作用。
if (numberOfSons(node) == 0) {
node= null;
return true;
}
这是处理归零部分的代码部分。当我调试它时,它正在引用正确的节点并且它为它分配空值,但是当我返回到我正在为我的树调用delete方法的Frame时,节点仍然在那里。在Java中“空”对象的正确方法是什么?我认为这里的一切都是指针,所以这会起作用,但我认为它没有。
答案 0 :(得分:6)
当你null
某事时,你只需在null
所在的范围内进行参考。它不会影响外面的任何事情。
让我举例解释。假设你有一个方法foo:
public void foo(Node node) {
node = null;
if(node == null) {
System.out.println("node is null");
} else {
System.out.println("node is not null");
}
}
现在你这样称呼它:
public void doSomething() {
Node node = new Node();
foo(node);
if(node == null) {
System.out.println("Original node is null");
} else {
System.out.println("Original node is not null");
}
}
在您的控制台中,您将获得:
node is null
original node in not null
原因是它不是指针,它是一个参考。当您null
引用时,您只需说“将此引用同义词设为null”。这并不意味着该对象被删除,它可能仍然存在于其他地方。 无法删除java中的对象。您所能做的就是确保没有其他对象指向它们,垃圾收集器将删除对象(有时)。
答案 1 :(得分:1)
除了重新插入左或右子树之外什么都没有。例如:
class BinaryTree<T extends Comparable<T>> {
class Node {
Node left;
Node right;
T value;
}
Node root;
void delete(T soughtValue) {
root = deleteRec(root, soughtValue);
}
Node deleteRec(Node node, T soughtValue) {
if (node == null) {
return null;
}
int comparison = soughtValue.compareTo(node.value);
if (comparison < 0) {
node.left = deleteRec(node.left, soughtValue);
} else if (comparison > 0) {
node.right = deleteRec(node.right, soughtValue);
} else {
if (node.left == null) {
return node.right;
} else if (node.right == null) {
return node.left;
} else {
// Two subtrees remain, do for instance:
// Return left, with its greatest element getting
// the right subtree.
Node leftsRightmost = node.left;
while (leftsRightmost.right != null) {
leftsRightmost = leftsRightmost.right;
}
leftsRightmost.right = node.right;
return node.left;
}
}
return node;
}
}
由于Java没有像C ++ Node*&
中那样的别名参数 - 一种输入输出参数,我在这里使用deleteRec
的结果。在java中,作为对象变量的任何函数参数都不会使用另一个对象实例更改变量。 这是单继承之类的语言设计决策之一。