簡體   English   中英

從遞歸方法返回時需要幫助

[英]Need help in returning from a recursive method

我試圖在二叉樹(不是二叉搜索樹)中跟蹤節點的路徑。 給定一個節點,我試圖從根打印路徑的值。

替代文字

我寫了以下程序。

package dsa.tree;

import java.util.Stack;

public class TracePath {
    private Node n1;

    public static void main(String args[]){
        TracePath nodeFinder = new TracePath();
        nodeFinder.find();
    }

    public void find(){
        Tree t = getSampleTree();
        tracePath(t,n1);
    }

    private Tree getSampleTree() {
        Tree bsTree = new BinarySearchTree();
        int randomData[] = {43,887,11,3,8,33,6,0,46,32,78,76,334,45};
        for(int i=0;i<randomData.length;i++){
            bsTree.add(randomData[i]);
        }
        n1 = bsTree.search(76);
        return bsTree;
    }

    public void tracePath(Tree t, Node node){
        trace(t,node);
    }

    Stack<Node> mainStack = new Stack<Node>();

    public void trace(Tree t, Node node){
        trace(t.getRoot(),node);
    }

    private void trace(Node parent, Node node){
        mainStack.push(parent);
        if(node.data == parent.data){
            for(Node iNode:mainStack){
                System.out.println(iNode.data);
            }
            return;
        }
        if(parent.left != null){
            trace(parent.left, node);
        }
        if(parent.right!=null){
            trace(parent.right, node);
        }
        mainStack.pop();
    }
}

我正確地得到了輸出。 但它有點凌亂。 如果你看到方法跟蹤(節點,節點),我打印的是我不應該做的值。 我希望跟蹤方法正確完成。 至少,我應該在遇到if條件的階段殺死遞歸結構。

請指教。

好的,你需要在找到節點后終止遞歸。 很簡單。 更改trace方法以返回一個布爾值,告訴我們是否找到了節點。 這樣,我們在找到節點后立即回到樹上。

private boolean trace(Node parent, Node node){
    mainStack.push(parent);
    if(node.data == parent.data){
        for(Node iNode:mainStack){
            System.out.println(iNode.data);
        }
        return true;
    }
    if(parent.left != null){
        if (trace(parent.left, node)) return true;
    }
    if(parent.right!=null){
        if (trace(parent.right, node)) return true;
    }
    mainStack.pop();
    return false;
}

我認為這是作業,所以我會給出一些指針而不是一些代碼。

  • trace方法執行遞歸下降,因此不需要堆棧 - 您可以在從找到的節點返回時構建路徑結構
  • 如果您的方法使用布爾值或列表返回值,您可以在返回時打印路徑,或者在搜索方法返回后構建包含要打印的節點的列表

編輯 :如果需要到root的路徑節點,則一個簡單的布爾返回就足夠了:

private boolean trace(Node parent, Node node) {
    boolean found = (node.data == parent.data)

    if (!found && parent.left != null) {
        found = trace(parent.left, node);
    }
    if (!found && parent.right != null){
        found = trace(parent.right, node);
    }

    if (found) {
        System.out.println(parent.data);
    }

    return found;
}

如果需要從根到節點的路徑,可以傳遞List以按順序接收節點:

private boolean trace(Node parent, Node node, List path) {
    boolean found = (node.data == parent.data)

    if (!found && parent.left != null) {
        found = trace(parent.left, node);
    }
    if (!found && parent.right != null){
        found = trace(parent.right, node);
    }

    if (found) {
        path.add(0, parent);
    }

    return found;
}

或者你可以在回來的路上建立路徑並作為列表返回。

private List trace(Node parent, Node node) {
    List path = null;

    if (null != node) {
        if (node.data == parent.data) {

            path = new ArrayList();
        } else {
            path = trace(parent.left, node);

            if (null == path) {
                path = trace(parent.right, node);
            }
        }
        if (null != path) {
            path.add(0, parent);
        }
    }
    return path;
}

像這樣的東西?

public Stack<Node> findPath(Node src, Node dest, Stack<Node> alreadyCollected) {
    if (src == dest) 
        return alreadyCollected;
    if (src.left == null && src.right == null)
        return null;
    if (src.left != null) {
        Stack<Node> toTheLeft = new Stack<Node>(alreadyCollected);
        toTheLeft.push(src.left);
        Stack<Node> result = findPath(src.left, dest, toTheLeft);
        if (result != null)
            return result;
    }
    List<Node> toTheRight = new Stack<Node>(alreadyCollected);
    return findPath(src.right, dest, toTheRight);
}

這是一個沒有任何堆棧使用的遞歸函數。 遞歸相當於堆棧技術,並且在進行recusrion時不需要堆棧。

PS:我正在寫一個偽代碼。 自己重寫它來編譯:)

bool trace(Node curr, Node n, Path path){
    if(curr == null)
        return;
    if(n == curr){
        path.insertAtEnd(curr);
        return true;
    }

    if(trace(curr.left, n, path)){
        path.insertAtEnd(curr);
        return true;
    }
    if(trace(curr.right, n, path)){
        path.insertAtEnd(curr);
        return true;
    }
    return false
}

從跟蹤返回一個布爾值,並根據遞歸調用返回的值決定是否繼續搜索。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM