我正在学习数据结构,遇到无法解决的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
的第二次调用工作正常。我不知道为什么会这样吗?谁能帮忙吗?
谢谢!
答案 0 :(得分:1)
在您的方法orderTraversal
中,您正在修改行上的树
prev.right = curr1;
那是你的错误。我真的不知道您打算在那里做什么,但是您不应该在遍历树时修改树。
您说
第二种方法仅引用实例变量
但是,当您执行prev = curr1
时,实例变量prev
指向树中的一个节点。然后,当您执行prev.right = curr1
时,您将修改prev
指向的节点。
由于修改了树,因此创建了循环引用。节点3将节点9作为他的左孩子,但是节点9又将3(他自己的父母)作为他的左孩子。这不再是一棵树了,这就是为什么您第二次调用inOrder1
并以StackOverflowError
结尾的情况下有无数的呼叫。
顺便说一下,使用调试器可以很容易地看到这一点,我建议您看一下this page。