如何使用二叉树中的递归完成回溯

时间:2014-04-14 11:39:28

标签: java recursion binary-tree

我正在尝试插入二进制节点。我的代码很复杂,没有希望拯救它,所以我打算重写它(基本上我没有考虑回溯,并且没有仔细考虑算法)。

我正在尝试使用顺序遍历插入二进制节点,但我不明白我应该如何回溯。

     D
    / \
   B   E 
  / \ / \
 A  C F 

如何搜索根D的左子树,然后返回并搜索正确的子树?这可能是一个愚蠢的问题,但我很难过。我能想到的最好的是这样的:

 if (!root.hasLeftChild) {
      root = root.getLeftChild(); 
      recurse(root); 
 } 

但是当我到达底部时,我无法回到根部。此外,它没有解决问题,如果我到达左下方节点,我必须在开始回溯之前填充该节点的两个子节点。

我想我正在以错误的方式思考这个问题。

3 个答案:

答案 0 :(得分:5)

树:

     D
    / \
   B   E 
  / \ / \
 A  C F 

递送:

使用InOrder Traverse

  if (root == null) 
    return;

      recurse(root.getLeftChild()); 
      int rootData = root.getData();
      recurse(root.getRightChild()); 

现在,它如何递归:

root.getLeftChild()将继续以递归方式调用左子子,除非它到达null节点(所以控件不会转到recurse(root.getRightChild());,除非null节点被击中

到目前为止,树已走过:

         D
        / 
       B    
      / 
     A  
    /
  null <-- current Position

一旦它到达节点AA.left == null,它就会递归到node A(将节点的值赋给rootData

     D
    / 
   B
  / 
 A  <-- current Position

然后,它进入下一个递归调用,recurse(root.getRightChild());

         D
        / 
       B    
      / 
     A  
      \
      null <-- current Position

现在,由于遍历了leftright A,控件将返回节点B(称为b.left = A)并且将会寻找B.right


以此堆栈为例,对于下面的树节点

     A
    / \
   B   E 
  / \ / \
 C  D F 

步骤:

  • A调用其左B,因此A推入堆栈
  • B调用其左C,因此B推入堆栈
  • C调用其左null,因此C推入堆栈
  • 现在C同时将leftright都设为null ...所以这标志着此节点的递归结束,因此它的pop已经从堆栈< / LI>
  • 现在,C被完全遍历,因此,当B称为C时,控制返回到B并检查哪一行称为此命令
  • b.left被执行后,它现在将转到B.rightpush D ...... ,这将继续,这称为递归堆栈

答案 1 :(得分:0)

试试这个例子。它通过使用递归来按顺序访问所有节点:

public class Example {

    public static void main(String[] args) {
        visitInOrder(new Node("D",
            new Node("B", new Node("A"), new Node("C")),
            new Node("F", new Node("E"))));
    }

    public static void visitInOrder(Node node) {
        if (node != null) {
            visitInOrder(node.left());
            System.out.println(node.name());
            visitInOrder(node.right());
        }
    }
}

class Node {

    private final String name;
    private Node left;
    private Node right;

    public Node(String name) {
        this(name, null);
    }

    public Node(String name, Node left) {
        this(name, left, null);
    }

    public Node(String name, Node left, Node right) {
        this.name = name;
        this.left = left;
        this.right = right;
    }

    public String name() { return name; }    

    public Node left() { return left; }

    public Node right() { return right; }
}

输出:

A
B
C
D
E
F

答案 2 :(得分:0)

因此,您正在尝试进行深度优先搜索 - 您可以在任意数量的书籍或维基百科上找到它。

它们的关键在本质上是你的函数以递归方式调用每个子节点。 e.g:

public Node findSpot(Node node, List<Node> visits){
    visits.add(node);
    //condition check, return this node if its the right node.
    Node result = null;
    for(Node child : node.getListChildren()){
        if((result findSpot(child)) != null){
             return result
        }
    }
    return null;
}

因此,这会以递归方式检查节点,在树中为每个深度层添加一个新方法。然后它会检查下一个分支,如果它找不到它想要的东西。访问列表将让您了解它访问节点的顺序,以便您查看。这将帮助您了解它的工作原理。