【问题标题】:Binary tree throwing stack overflow exception while inorder traversing二叉树在中序遍历时抛出堆栈溢出异常
【发布时间】:2018-12-30 01:01:29
【问题描述】:

我正在学习数据结构,遇到了一个我无法解决的 pbm。有人可以帮忙吗?

我创建了一个TreeNode 类。在同一个包中,我创建了另一个类。这个类有两个方法。一个是 inorder 遍历,还有另一种方法(从现有的二叉树中创建一个新的二叉树)。我打电话给inorder 遍历,它工作得很好。但是如果我在我的其他方法之后调用inorder 遍历方法,我就会遇到异常。

另一种方法创建一个新的二叉树,但它独立于inorder遍历方法

public class TreeNode {
     public int val;
     public TreeNode left;
     public TreeNode right;
     TreeNode(int x) { val = x; }
}

In the same package I created another class.

package BST;
public class Check {
    TreeNode curr;
    TreeNode prev;

public void orderTraversal( TreeNode curr1) {

        if(curr1 == null)
            return;

        orderTraversal(curr1.left);

        if(curr == null ) {
            curr = curr1;
            prev = curr1;
        }
        else {
            prev.right = curr1;
            prev = curr1;
        }

        orderTraversal(curr1.right);
    }

    public static void main(String[] args) {
            // TODO Auto-gene`enter code here`rated method stub

        TreeNode root = new TreeNode(3);
        root.left = new TreeNode(9);
        root.right = new TreeNode(20);
        root.right.right = new TreeNode(15);

        Check check = new Check();  
        check.inOrder1(root);
        check.orderTraversal(root);
        check.inOrder1(root);
    }
    public  void inOrder1(TreeNode root) {
        if(root !=  null) {
            inOrder1(root.left); 
            System.out.printf("%d ",root.val);
            inOrder1(root.right);
        }

    }

}

When running the program , I am getting an exception in the method in the second call of inOrder1 . 

at sun.nio.cs.UTF_8.updatePositions(Unknown Source)
    at sun.nio.cs.UTF_8.access$200(Unknown Source)
    at sun.nio.cs.UTF_8$Encoder.encodeArrayLoop(Unknown Source)
    at sun.nio.cs.UTF_8$Encoder.encodeLoop(Unknown Source)
    at java.nio.charset.CharsetEncoder.encode(Unknown Source)
    at sun.nio.cs.StreamEncoder.implWrite(Unknown Source)
    at sun.nio.cs.StreamEncoder.write(Unknown Source)
    at java.io.OutputStreamWriter.write(Unknown Source)
    at java.io.BufferedWriter.flushBuffer(Unknown Source)
    at java.io.PrintStream.write(Unknown Source)
    at java.io.PrintStream.print(Unknown Source)
    at java.io.PrintStream.append(Unknown Source)

我知道 java 是通过值传递来工作的。第二种方法只引用实例变量。如果我注释掉check.orderTraversal(root),第二次调用InOrder1 工作正常。我不明白为什么会这样?有人可以帮忙吗?

谢谢!

【问题讨论】:

    标签: java data-structures tree binary-tree


    【解决方案1】:

    在你的方法orderTraversal 中你正在修改你的树

    prev.right = curr1;
    

    那是你的错误。我真的不知道你打算在那里做什么,但你不应该在树遍历中修改你的树。

    你说

    第二种方法只引用实例变量

    但是当您执行prev = curr1 时,您的实例变量prev 指向树中的一个节点。然后,当您执行prev.right = curr1 时,您修改了prev 指向的节点。

    因为你修改了你的树,你创建了一个循环引用。节点 3 将节点 9 作为其左孩子,但节点 9 再次将 3(他自己的父节点)作为其左孩子。这不再是一棵树了,这就是为什么您第二次调用inOrder1 时调用的次数是无限的,它以StackOverflowError 结尾。

    顺便说一句,使用调试器可以很容易地看到这一点,我建议你看看this page

    【讨论】:

    猜你喜欢
    • 2012-05-10
    • 2015-07-25
    • 1970-01-01
    • 1970-01-01
    • 2017-04-24
    • 2014-12-07
    • 2012-11-09
    • 2012-02-17
    • 2014-05-08
    相关资源
    最近更新 更多