今天在思考一道leetcode上的题时,忽然要用到了二叉树的中序遍历,于是我便写下了下面这样的代码,这完全是凭借记忆写下来的,但是完全没有想到我竟然要用两个小时来找出其中的bug,这真的很让我希望,没想到学了那么久都没学到精髓。
第一次版本
public void inOrder(TreeNode root, List<TreeNode> res) {
if(root==null)
return;
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while(!stack.empty()) {
TreeNode r = stack.pop();
while(r!=null) {
stack.push(r);
r = r.left;
}
if(!stack.empty()) {
r = stack.pop();
res.add(r);
if(r.right!=null)
stack.push(r.right);
}
}
}
//其中root 的定义为
TreeNode rNode= new TreeNode(2);
TreeNode e = new TreeNode(3);
TreeNode t = new TreeNode(4);
rNode.left=e;rNode.right=t;
这上面的bug在于如果二叉树的形状为
这个程序会一直输出3,因为在把节点压入栈内时,它总是检查有没有左孩子,如果再把树的形状定义为
TreeNode rNode= new TreeNode(2);
TreeNode e = new TreeNode(3);
TreeNode t = new TreeNode(4);
rNode.left=e;rNode.right=t;
e.right = new TreeNode(6);
它就会一直输出3和6,这个程序的问题在于
正确的程序是
public void helper(TreeNode root, List<TreeNode> res) {
if(root==null)
return;
Stack<TreeNode> stack = new Stack<>();
TreeNode r = root;;
while(!stack.empty()||r!=null) {
while(r!=null) {
stack.push(r);
r = r.left;
}
if(!stack.empty()) {
r = stack.pop();
System.out.println(r.val);
//if(r.right!=null)
r = r.right;
}
}
}
如果把注释的去掉也是不对的