【问题标题】:In order recursion in binary trees为了在二叉树中递归
【发布时间】:2014-07-14 04:54:38
【问题描述】:

有人可以向我解释一下递归在顺序遍历中的工作原理吗?这是我的 inOrder() 方法。

public void inOrder(BinaryNode p){
        if(p.left!=null){
            inOrder(p.left);
        }

        visit(p);

        if(p.right!=null){
            inOrder(p.right);
        }


    }
    public void visit(BinaryNode p){
        System.out.println(p.element);
    }

BinaryTree t=new BinaryTree();
        t.insert(5);
        t.insert(t.root,4);
        t.insert(t.root,6);
        t.insert(t.root,60);
        t.insert(t.root,25);
        t.insert(t.root,10);
        t.inOrder(t.root);  

inOrder() 方法可以正确打印元素,但我不明白它是如何工作的。
当我调用 t.inOrder(t.root); 时,因为 root 的值为 5,它类似于 inOrder(5); 并且有一个左节点,所以 if(p.left!=null){ inOrder(p.left); }

将被执行。递归调用将是inOrder(4);
由于 4 的左侧指向 null,因此 visit(4) 是执行打印值 4 的行。
但是在那之后如何打印 5。虽然最初当 t.inOrder(t.root); 调用该方法时,局部变量 p 被分配了值为 5 的 BinaryNode,现在 p 为 4。然后在打印出 4 之后,下一行可以被执行是

if(p.right!=null){ inOrder(p.right); }
但是由于 p.right 现在在 BinaryNode 中引用了元素 4 的 right 并且 4 的 right 为空,所以这也不会被执行。
那么递归是如何维护的呢?
它如何打印出 5 和其余的节点?

【问题讨论】:

  • 没有图纸这很难解释......也许在网上找到一个视频......但让我试试。我认为您的问题是您将值与节点混淆了; inOrder(root) 与 inOrder(5) 不太一样……根是一个节点,它有 5,但也有左和右
  • 至于如何实现,一般有栈;当你调用一个函数时,参数被推入堆栈,也是返回的地方;返回时,将结果入栈,取出调用者的地址,返回到那个地方。
  • @okaram:我知道 inOrder(root) 是一个 BinaryNode 作为参数。我写 inOrder(5) 只是为了方便解释
  • 好的,那么让我来解释一下......当你调用一个函数(递归与否)时,编译器会生成代码来推送参数和当前地址;因此,当您调用 inOrder(root) 时,编译器会将 root 推入堆栈,然后是当前地址;当您进入函数内部时,您调用 inOrder(left),si 游览他的那个值,以及当前地址(现在在函数内部)......这一直持续到 left 为空。此时您返回到最后一个呼叫者,然后从那里继续。顺便说一句,您可能应该发送指针...
  • @okaram:所以当递归最终达到其基本情况时,所有中间递归调用都被评估了吗?我仍然没有正确理解这个概念

标签: java recursion data-structures binary-tree inorder


【解决方案1】:

这很难说..这取决于你的实现..

我添加了按顺序遍历的实现。希望对您有所帮助

class BinaryTreeSearch{
 public enum State{
 Visited, Unvisited,Visiting;

}
//this is the Node used in the tree
  static class Node{
    private int data;
    private Node left;
    private Node right;
    public Node(int data){
        this.data = data;
        left = null;
        right = null;
    }
    public void setLeft(Node left){
        this.left = left;
    }
    public void setRight(Node right){
        this.right = right;
    }
    public Node getLeft(){
        return this.left;
    }       
    public Node getRight(){
        return this.right;
    }
    public int getData(){
        return this.data;
    }
    public boolean equals(Node n){
        if(this.data ==(int) n.getData()) return true;
        else
            return false;
    }
}
public static void main(String[] args){
    BinaryTreeSearch bts = new BinaryTreeSearch();
    bts.run();
}
//execute the test case
public void run(){
    Node root = new Node(10);
    insert(root,new Node(20));
    insert(root,new Node(5));
    insert(root,new Node(4));
    insert(root,new Node(5));
    insert(root,new Node(15));

    inOrderTraverse(root);
    System.out.println("\n" + binarySearch(root,new Node(10)));
}

// insert a node to the binary search tree
public void insert(Node root, Node n){
    if(root == null|| n == null) return;

    if(root.getData() > n.getData()){
        if(root.getLeft() == null){
            root.setLeft(n);
             System.out.println("Added node to left of "+root.getData()+" of value "+n.getData());           
        }else{
            insert(root.getLeft(),n);
        }

    }else if(root.getData() < n.getData()){
        if(root.getRight() == null){
            root.setRight(n);
            System.out.println("Added node to Right of "+root.getData()+" of value "+n.getData());     
        }else{
            insert(root.getRight(),n);
        }

    }
}
//in-order Traversal
public void inOrderTraverse(Node root){
    if(root != null){
        inOrderTraverse(root.getLeft());
        System.out.print("  "+root.getData());
        inOrderTraverse(root.getRight());
    }

}
//binary search
public boolean binarySearch(Node root,Node n){
    if(root == null || n == null) {
        return false;
    }
    System.out.println("  Testing out "+root.getData()+" for value "+n.getData());
    if(root.getData() > n.getData()){
       return  binarySearch(root.getLeft(),n);
    }else if(root.getData() < n.getData()){
       return  binarySearch(root.getRight(),n);
    }
    return true;
}
} 

【讨论】:

    【解决方案2】:

    我已经解释了没有图片我能做到的最好的事情。 do print(i) 表示打印 i 并且做 inorder(i) 意味着 inorder(i) 被扩展为 inorder(left of i) > print (i) > inorder(right of i)

    inorder(5) 调用

    待办事项:inorder(4) > 打印 5 > inorder(6)

    按顺序做(4)

    待办事项:inorder(4 的左边)=nothing > print(4) > inorder(4 的右边)=nothing > print(5)

    顺序 6

    打印 4

    打印 5

    按顺序 6

    待办事项:inorder(6 的左边)=nothing > print 6 > inorder(60)

    打印 6

    按顺序 60

    tod​​o: inorder(25) > print 60 > inorder(60 的右边)=nothing

    按顺序执行 25

    tod​​o: inorder(10) > 打印 25 > inorder(25 的右边)=nothing > 打印 60

    按顺序执行 10

    待办事项:inorder(10 的左边)=nothing > print 10 >inorder(10 的右边)=nothing >print 25>print 60

    打印 10

    打印 25

    打印 60

    所以如果你看到它的打印顺序是 4 5 6 10 25 60

    【讨论】:

      猜你喜欢
      • 2016-04-19
      • 2014-03-29
      • 1970-01-01
      • 2010-12-07
      • 2020-09-15
      • 1970-01-01
      • 1970-01-01
      • 2015-01-05
      • 2011-05-08
      相关资源
      最近更新 更多