Java 这个递归是如何工作的&;如何让它打印出根目录?

Java 这个递归是如何工作的&;如何让它打印出根目录?,java,recursion,tostring,Java,Recursion,Tostring,所以我做了一个BST的实现 private String toStringHelper(Node node) { if (node == null) { return ""; } if (node.left != null) { System.out.println(node.left.value); toStringHelp

所以我做了一个BST的实现

private String toStringHelper(Node node) {


            if (node == null) {
                return "";
            }
            if (node.left != null) {
                System.out.println(node.left.value);
                toStringHelper(node.left);

            }

            if (node.right != null) {
                System.out.println(node.right.value);
                toStringHelper(node.right);

            }


            return "";
        }
我想使用递归。问题是它不会打印作为我的根的元素,否则它似乎可以工作(开始编辑)。 插入以下值100、-12、-13、-1、0、12、10、123、122、124时。它将按以下顺序返回它们: -12 -13 -1 0 12 10 123 122 124显然根本没有订购。 (编辑结束)


问题是,我不完全确定递归部分是如何工作的,我希望对此进行解释,以便我也可以获得在适当位置打印根的方法。

看起来您将其传递到开始节点,然后打印左、右子树。您需要打印出作为参数传递给该方法的节点上的值,然后在该节点的左、右子节点上调用该方法

private String toStringHelper(Node node) {

        if (node == null) {
            return "";
        }
        //print the value of the current node
        System.out.println(node.value);
        if (node.left != null) {
            //System.out.println(node.left.value);
            toStringHelper(node.left);

        }

        if (node.right != null) {
            //System.out.println(node.right.value);
            toStringHelper(node.right);

        }


        return "";
    }

编辑:根据OLE V.V.的更正将print语句移动到空检查后

看起来您将其传递到开始节点,然后打印左、右子树。您需要打印出作为参数传递给该方法的节点上的值,然后在该节点的左、右子节点上调用该方法

private String toStringHelper(Node node) {

        if (node == null) {
            return "";
        }
        //print the value of the current node
        System.out.println(node.value);
        if (node.left != null) {
            //System.out.println(node.left.value);
            toStringHelper(node.left);

        }

        if (node.right != null) {
            //System.out.println(node.right.value);
            toStringHelper(node.right);

        }


        return "";
    }

编辑:根据OLE V.V.的更正将打印语句移动到空检查后

虽然原始问题的答案非常简单,其他海报已经指出了这一点,但我想提供一个关于递归树遍历的更详细的答案,也许这将对本帖的未来访问者有所帮助。 有许多不同的树遍历方法,有些是“自然”递归的,有些不是。(有关更多详细信息,请参阅。)以下代码说明了基于OP中代码的订单前/订单中/订单后深度优先和宽度优先搜索。 由于递归(堆栈溢出)的实际限制,深度优先和广度优先都应该使用循环实现,使用堆栈或队列作为底层数据结构,除非实现是尾部递归的,平台可以将其优化为循环,但Java编译器不支持这一点。 在下面的代码中,我带来了递归示例,因为最初的问题是关于递归,而不是树遍历

// depth first pre-order
// root
// left child
// left child of left child
// right child of left child
// right child
// left child of right child
// right child of right child
private String toStringHelperDepthFirst(Node node) {
    if (node == null) {
        return "";
    }
    System.out.println(node.value);
    toStringHelper(node.left);
    toStringHelper(node.right); 
}

// depth first in-order
// left child of left child
// left child
// right child of left child
// root
// left child of right child
// right child
// right child of right child
private String toStringHelperDepthFirst(Node node) {
    if (node == null) {
        return "";
    }
    toStringHelper(node.left);
    System.out.println(node.value);
    toStringHelper(node.right); 
}

// depth first post-order
// left child of left child
// right child of left child
// left child
// left child of right child
// right child of right child
// right child
// root
private String toStringHelperDepthFirst(Node node) {
    if (node == null) {
        return "";
    }
    toStringHelper(node.left);
    System.out.println(node.value);
    toStringHelper(node.right); 
}

// breadth-first
// root
// left child
// right child
// left child of left child
// right child of left child
// left child of right child
// right child of right child
private void toStringHelperBreadthFirst(Node node) {
    if(node != null) {
        Queue<Node> queue = new LinkedList<>();
        queue.add(node);
        breadhFirst(queue);
    }
}

private <E> void breadthFirst(Queue<E> queue) {
    if(queue.isEmpty()) {
        return;
    }
    Node node = queue.pop();
    System.err.println(node.value);
    if(node.left != null) {
        queue.add(node.left);
    }
    if(node.right != null) {
        queue.add(node.right)
    }
    breadhFirst(queue);
}
//深度优先预订单
//根
//左撇子
//左子的左子
//左子右子
//对的孩子
//右子的左子
//正确儿童的正确儿童
私有字符串到字符串HelperDepthFirst(节点){
if(node==null){
返回“”;
}
System.out.println(节点值);
toStringHelper(节点左);
toStringHelper(右节点);
}
//深度优先顺序
//左子的左子
//左撇子
//左子右子
//根
//右子的左子
//对的孩子
//正确儿童的正确儿童
私有字符串到字符串HelperDepthFirst(节点){
if(node==null){
返回“”;
}
toStringHelper(节点左);
System.out.println(节点值);
toStringHelper(右节点);
}
//深度优先后序
//左子的左子
//左子右子
//左撇子
//右子的左子
//正确儿童的正确儿童
//对的孩子
//根
私有字符串到字符串HelperDepthFirst(节点){
if(node==null){
返回“”;
}
toStringHelper(节点左);
System.out.println(节点值);
toStringHelper(右节点);
}
//广度优先
//根
//左撇子
//对的孩子
//左子的左子
//左子右子
//右子的左子
//正确儿童的正确儿童
私有void到stringHelperReadthFirst(节点){
如果(节点!=null){
Queue Queue=new LinkedList();
添加(节点);
第一名(排队);
}
}
专用空位宽度优先(队列){
if(queue.isEmpty()){
返回;
}
Node=queue.pop();
System.err.println(节点值);
if(node.left!=null){
queue.add(node.left);
}
if(node.right!=null){
queue.add(node.right)
}
第一名(排队);
}

虽然原始问题的答案非常简单,其他海报也已经指出了这一点,但我想提供一个关于递归树遍历的更详细的答案,也许这对本帖的未来访问者有所帮助。 有许多不同的树遍历方法,有些是“自然”递归的,有些不是。(有关更多详细信息,请参阅。)以下代码说明了基于OP中代码的订单前/订单中/订单后深度优先和宽度优先搜索。 由于递归(堆栈溢出)的实际限制,深度优先和广度优先都应该使用循环实现,使用堆栈或队列作为底层数据结构,除非实现是尾部递归的,平台可以将其优化为循环,但Java编译器不支持这一点。 在下面的代码中,我带来了递归示例,因为最初的问题是关于递归,而不是树遍历

// depth first pre-order
// root
// left child
// left child of left child
// right child of left child
// right child
// left child of right child
// right child of right child
private String toStringHelperDepthFirst(Node node) {
    if (node == null) {
        return "";
    }
    System.out.println(node.value);
    toStringHelper(node.left);
    toStringHelper(node.right); 
}

// depth first in-order
// left child of left child
// left child
// right child of left child
// root
// left child of right child
// right child
// right child of right child
private String toStringHelperDepthFirst(Node node) {
    if (node == null) {
        return "";
    }
    toStringHelper(node.left);
    System.out.println(node.value);
    toStringHelper(node.right); 
}

// depth first post-order
// left child of left child
// right child of left child
// left child
// left child of right child
// right child of right child
// right child
// root
private String toStringHelperDepthFirst(Node node) {
    if (node == null) {
        return "";
    }
    toStringHelper(node.left);
    System.out.println(node.value);
    toStringHelper(node.right); 
}

// breadth-first
// root
// left child
// right child
// left child of left child
// right child of left child
// left child of right child
// right child of right child
private void toStringHelperBreadthFirst(Node node) {
    if(node != null) {
        Queue<Node> queue = new LinkedList<>();
        queue.add(node);
        breadhFirst(queue);
    }
}

private <E> void breadthFirst(Queue<E> queue) {
    if(queue.isEmpty()) {
        return;
    }
    Node node = queue.pop();
    System.err.println(node.value);
    if(node.left != null) {
        queue.add(node.left);
    }
    if(node.right != null) {
        queue.add(node.right)
    }
    breadhFirst(queue);
}
//深度优先预订单
//根
//左撇子
//左子的左子
//左子右子
//对的孩子
//右子的左子
//正确儿童的正确儿童
私有字符串到字符串HelperDepthFirst(节点){
if(node==null){
返回“”;
}
System.out.println(节点值);
toStringHelper(节点左);
toStringHelper(右节点);
}
//深度优先顺序
//左子的左子
//左撇子
//左子右子
//根
//右子的左子
//对的孩子
//正确儿童的正确儿童
私有字符串到字符串HelperDepthFirst(节点){
if(node==null){
返回“”;
}
toStringHelper(节点左);
System.out.println(节点值);
toStringHelper(右节点);
}
//深度优先后序
//左子的左子
//左子右子
//左撇子
//右子的左子
//正确儿童的正确儿童
//对的孩子
//根
私有字符串到stringhelperdepthfirst(节点n