/* 这个解法可能是最佳实践,思路清晰,易于理解。
* 核心思想是用栈做辅助空间,先从根往左一直入栈,直到为空,然后判断栈顶元素的右孩子,如果不为空且未被访问过,
* 则从它开始重复左孩子入栈的过程;否则说明此时栈顶为要访问的节点(因为左右孩子都是要么为空要么已访问过了),
* 出栈然后访问即可,接下来再判断栈顶元素的右孩子...直到栈空。
*/
import java.util.Stack;
import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> postorderTraversal(TreeNode root) {
TreeNode p = root, r = null; //P记录当前节点,r用来记录上一次访问的节点
Stack<TreeNode> s = new Stack<TreeNode>();
ArrayList<Integer> list = new ArrayList<Integer>();
while(p != null || !s.isEmpty()) {
if(p != null) { //左孩子一直入栈,直到左孩子为空
s.push(p);
p = p.left;
} else {
p = s.peek();
p = p.right;
if(p != null && p != r) { //如果栈顶元素的右孩子不为空,且未被访问过
s.push(p); //则右孩子进栈,然后重复左孩子一直进栈直到为空的过程
p = p.left;
} else {
p = s.pop(); //否则出栈,访问,r记录刚刚访问的节点
list.add(p.val);
r = p;
p = null;
}
}
}
return list;
}
}
* 核心思想是用栈做辅助空间,先从根往左一直入栈,直到为空,然后判断栈顶元素的右孩子,如果不为空且未被访问过,
* 则从它开始重复左孩子入栈的过程;否则说明此时栈顶为要访问的节点(因为左右孩子都是要么为空要么已访问过了),
* 出栈然后访问即可,接下来再判断栈顶元素的右孩子...直到栈空。
*/
import java.util.Stack;
import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> postorderTraversal(TreeNode root) {
TreeNode p = root, r = null; //P记录当前节点,r用来记录上一次访问的节点
Stack<TreeNode> s = new Stack<TreeNode>();
ArrayList<Integer> list = new ArrayList<Integer>();
while(p != null || !s.isEmpty()) {
if(p != null) { //左孩子一直入栈,直到左孩子为空
s.push(p);
p = p.left;
} else {
p = s.peek();
p = p.right;
if(p != null && p != r) { //如果栈顶元素的右孩子不为空,且未被访问过
s.push(p); //则右孩子进栈,然后重复左孩子一直进栈直到为空的过程
p = p.left;
} else {
p = s.pop(); //否则出栈,访问,r记录刚刚访问的节点
list.add(p.val);
r = p;
p = null;
}
}
}
return list;
}
}