2014-09-19 30 views
2

我正在使用遞歸方法使用鍵在二叉樹中查找節點。所以當我找到節點時,我將它設置爲我的引用變量(foundNode)並返回。但問題是當我讀取對象時,它的值仍然爲空。任何人都可以幫忙。無法在遞歸調用中設置參考變量

findGivenNode(root, key, foundNode, parentStack); 

private boolean findGivenNode(Node node, int key, Node foundNode, Stack<Node> parentStack) { 
    if (node == null) { 
     return false; 
    } 

    parentStack.add(node); 
    if (node.getData() == key) { 
     foundNode = node; 
     return true; 
    } 
    boolean leftReturn = findGivenNode(node.getLeftChild(), key, foundNode, parentStack); 
    boolean RightReturn = findGivenNode(node.getRightChild(), key, foundNode, parentStack);   
    if (leftReturn || RightReturn) { 
     return true; 
    } else { 
     parentStack.pop(); 
     return false; 
    } 
} 

回答

2

Java不通過引用傳遞參數,它們通過值傳遞。 Read more here

讓我們通過一個例子來說明。將您要找的密鑰設爲值爲21的整數。 在函數開頭的情況如下:

initial_state

所以,現在,當你說:

foundNode = node; // this doesn't reflect outside of the method 

你是局部地改變findGivenNode()方法中的foundNode的價值,它不適用於此方法之外。基本上,名爲foundNode的本地變量引用您想要更改的節點,然後通過上述語句使此本地變量foundNode引用新節點。 此更改只反映在函數內部。只要你的函數完成,局部變量不再存在,因此本地版本foundNode也不存在。視覺效果:

wrong_move

簡單的解決方法是使用一個Wrapper function

要跟蹤的參考,你可以將存儲您想要的參考一個簡單的包裝類:

private class NodeWrapper { 
    Node foundNode; 
    NodeWrapper() { 
     foundNode = null; 
    } 
} 

然後您可以創建一個新的NodeWrapper並將其傳遞到您的功能,而不是foundNode

NodeWrapper wrapper = new NodeWrapper(); 
findGivenNode(root, wrapper, key, parentStack); 

然後你的函數,而不是內部:

foundNode = node; 

你說:

wrapper.foundNode = node; 

這樣你就可以保持整個NodeWrapper裏面的遞歸引用。含義:

NodeWrapper wrapper = new NodeWrapper(); 
findGivenNode(root, wrapper, key, parentStack); 
// at this point, wrapper.foundNode will hold the reference to the node you need 
// or null if the node wasn't found 

在另一方面,上面的方法,你有這樣的函數原型:

findGivenNode(root, key, foundNode, parentStack); 

好像有人還在使用C/C++ :)

這是Java不必要,你可以閱讀this question thread的推理背後,或只是谷歌它。

+0

謝謝澄清,但通過設置(foundNode =節點)我試圖獲得具有密鑰的節點的引用而不是節點本身。其次,foundNode只是一個引用變量,因此不能通過調用任何setter方法來設置該值。 – 2014-09-19 06:22:12

+0

第二部分,是的,它可以。 'foundNode'指向您想要更改的節點,以便可以訪問該節點的方法。 – nem035 2014-09-19 06:43:16

+0

但是改變節點不是將參考變量設置到該節點的要點。我需要的只是對該節點的引用。除非我做'foundNode = node; return foundNode;'將方法的返回類型從'void'改爲'Node'。 – 2014-09-19 07:07:06