描述:
Given a binary tree, return the postorder traversal of its nodes' values.
For example:
Given binary tree {1,#,2,3}
,
1 \ 2 / 3
return [3,2,1]
.
Note: Recursive solution is trivial, could you do it iteratively?
思路:
刚开始的时候由于刚做出前序和中序的遍历,落入这两种遍历的窠臼,总以为在中序遍历的基础上改改就可以了,但是,改了好久,费了了好大的劲,走了好多弯路,in vain!最后联想到后序遍历不就是在中序遍历的基础上,经由子树根节点访问右子树,然后再访问根节点,不是么?所以,想到再多用一个栈来标记是否是第一次访问子树根节点,第二次访问子树根节点时(当然不算第一次将所有左子树入栈的那一次)就存储根节点的值。bravo!It's done!
代码:
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
public class _145_PostOrderTraverse {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<Integer>();
if (root == null)
return list;
Stack<TreeNode> st = new Stack<TreeNode>();
Stack<TreeNode> st1 = new Stack<TreeNode>();
st.push(root);
TreeNode top = null;
while (!st.empty()) {
top=st.peek();
while(top.left!=null)//达到页结点
{
st.push(top.left);
top=top.left;
}
while(!st.empty())
{
top=st.peek();
if(top.right==null)//无右子树时,访问结点
{
list.add(top.val);
st.pop();
}else
{
if(st1.empty()||(!st1.empty()&&st1.peek()!=top))//有右子树且第一次出现,将右子树入栈,并将结点在st1中标记一下
{
st1.push(top);
st.push(top.right);
break;//右子树入栈了,然后从右子树开始
}
else//有右子树,但是第二次出现了,访问该结点
{
list.add(top.val);
st1.pop();
st.pop();
}
}
}
}
return list;
}
}