Java:在方法中将对象设置为null无效(重用代码)

时间:2015-05-31 16:29:04

标签: java algorithm reference binary-search-tree

我正在尝试编写一种从二进制搜索树中删除节点的方法。这是我删除节点的方法。

public void delete(int deletionNodeValue) {
    Node<Integer> nodeToBeDeleted = getNode(deletionNodeValue);
    if(nodeToBeDeleted == null) return; // No node with such value exists throw an error
    if(isLeafNode(nodeToBeDeleted)) {
        nodeToBeDeleted = null;
    } else if (nodeToBeDeleted.getNumChildren() == 1) {
        bypassNode(nodeToBeDeleted);
    }else {
        replace(nodeToBeDeleted, getSuccessor(nodeToBeDeleted.getValue()));
    }
}

我在叶子节点上检查了这个方法,但是在调试之后我发现nodeToBeSelected=null的执行发生了,节点实际上没有被删除。因为我仍然可以搜索已删除的值,程序仍然设法获取它。

tree.add(5);
tree.delete(5);
System.out.println(tree.getNode(5).getValue()); // Output : 5, should've been deleted

这是我的getNode()方法

public Node<Integer> getNode(int searchValue) {
    Node<Integer> currentNode = root;
    while(currentNode != null) {
        int currentNodeValue = currentNode.getValue();
        if(searchValue == currentNodeValue)
            return currentNode;
        else if(searchValue < currentNodeValue)
            currentNode = currentNode.getLeftChild();
        else
            currentNode = currentNode.getRightChild();
    }

    // if no node with given value is found
    return null;
}

getNode()方法是否按值返回找到的节点?如何让它返回引用并直接操作找到的节点?

3 个答案:

答案 0 :(得分:5)

您必须从树中删除节点,而不是在程序中本地删除。

Node<Integer> nodeToBeDeleted = getNode(deletionNodeValue);

为您提供树中节点的副本。

nodeToBeDeleted = null;

将此副本设置为null。不会删除与树的连接,因为它是节点对象的一部分。要删除连接,您必须编写另一种方法来删除节点,这应该包含类似

的内容
parent.leftNode = null; // if nodeToBeDeleted == leftNode
parent.rightNode = null; // if nodeToBeDeleted == rightNode

答案 1 :(得分:4)

当你在nodeToBeDeleted = null;方法中说delete时,你并没有真正导致Node方法返回的getNode开始指向null

Java总是pass-by-value。这意味着您无法将传递给方法的引用指向方法内的新内存位置。同样,您不能将方法调用返回的引用指向另一个方法中的新内存位置。 (即使位置是,嗯..一个空)。

根据上述说明,几乎不可能使用getNode方法获取您要删除的Node,然后使此节点指向其他方法中null。一个快速的解决方案是在getNode方法中复制delete方法中的代码。您应该在setLeftChild中添加setRightChildNode方法(而不是像其他人一样公开leftChild和rightChild)。然后,您可以将其设置为null,如下所示:

nodeToBeDeleted.setLeftChild(null)

答案 2 :(得分:4)

nodeToBeDeleted设置为null时,只设置保存对实际对象的引用的局部变量的值。不会以任何方式删除实际对象。

使用此处显示的代码,要删除节点,您应找到其父节点并将对此节点(leftChild或rightChild)的引用设置为null。这将确保该对象不被其父对象引用,可能不再被任何引用看到,因此有资格进行垃圾回收。