后续遍历的非递归方法更加复杂要用到辅助栈
通过上一篇的先序遍历我们知道它是通过变换头节点,先压入右孩子再压入左孩子做到的头左右的打印顺序
那么后续的遍历是打印左右头,我们要做的是把头先攒住,打完左右孩子再打印头,不要像之前那样变换的头进栈又出栈,但是这样很麻烦的一点在于我不知道啥时候改打头,我不知道啥时候右孩子被打完了
但是我们用辅助栈就可以做到这一点,我们先调整先序的只有进栈的顺序,把先序的先压右孩子再压左孩子,改成先压左孩子再压右孩子,最终可以得到头右左的顺序 存入辅助栈,再倒出来就得到的是左右头的后续了
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) { this.val = val; } * TreeNode(int val, TreeNode left, TreeNode right) { * this.val = val; * this.left = left; * this.right = right; * } * } */ class Solution { public List<Integer> postorderTraversal(TreeNode root) { List<Integer> list=new ArrayList<>(); Stack<TreeNode> stack=new Stack<TreeNode>(); Stack<TreeNode> s=new Stack<TreeNode>(); if(root==null){return list;} s.add(root); while(!s.isEmpty()){ root=s.pop(); stack.push(root); if(root.left!=null){ s.add(root.left); } if(root.right!=null){ s.add(root.right); } } while(!stack.isEmpty()){ list.add(stack.pop().val); } return list; } }
当然也有不用辅助栈的做法 !
我们之前不是说不知道啥时候右孩子到头吗?
那么后续的遍历是打印左右头,我们要做的是把头先攒住,打完左右孩子再打印头,不要像之前那样变换的头进栈又出栈,但是这样很麻烦的一点在于我不知道啥时候改打头,我不知道啥时候右孩子被打完了
我们可以用c来记录栈顶元素,root用来跟踪刚弹出的节点
如果c是刚到的:1.c(栈顶元素)的左孩子不为null
2.root(刚弹出的节点)不是c(栈顶元素)的左孩子
3.root(刚弹出的节点)不是c(栈顶元素)的右孩子
即if语句对应的条件左树没有被处理的情况,把栈顶c的左孩子压栈
elseif即右树没有被处理的条件1.栈顶的右孩子不为空2.刚弹出的节点root不是栈顶元素c的右孩子
那么把栈顶右孩子压栈
其他情况栈顶元素出栈,root跟踪这个出来了的元素
比如
这棵树按后序遍历结果是
[4,5,2,6,7,3,1]
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> list=new ArrayList<>();
if(root!=null){
Stack<TreeNode> stack=new Stack<TreeNode>();
stack.push(root);//压头入栈
TreeNode c=null;
while(!stack.isEmpty()){
c=stack.peek();
//左树没处理的逻辑,c如果是新到的
if(c.left!=null&&root!=c.left&&root!=c.right){
stack.push(c.left);
}else if(c.right!=null&&root!=c.right){//右树没被处理的情况
stack.push(c.right);
}else{
list.add(stack.pop().val);
root=c;
}
}
}return list;
}
}