145.Binary Tree Postorder Traversal(Java)
##Stack##, ##Tree##
题解
二叉树后序遍历,即左=>右=>根的顺序遍历
采用非递归方法时,需要借助栈
后续遍历的反序列为根=>右=>左,因此可以将该反序列看作是“不一样”的前序遍历,正常的前序遍历为根=>左=>右
可以对该树进行一次根=>右=>左的非递归遍历,最后将遍历结果翻转得到左=>右=>根的遍历结果,java种采用Collections.reverse()
方法
**时间复杂度:**O(n)
递归
class Solution {
List<Integer> res = new LinkedList<Integer>();
public List<Integer> postorderTraversal(TreeNode root) {
traversal(root);
return res;
}
private void traversal(TreeNode root) {
if (root == null) return;
traversal(root.left);
traversal(root.right);
res.add(root.val);
}
}
迭代法
class Solution {
List<Integer> res = new LinkedList<>();
Stack<TreeNode> sta = new Stack<TreeNode>();
public List<Integer> postorderTraversal(TreeNode root) {
if (root == null) return res;
sta.push(root);
while (!sta.isEmpty()) {
TreeNode curr = sta.pop();
if (curr == null) continue;
res.add(curr.val);
sta.push(curr.left);
sta.push(curr.right);
}
Collections.reverse(res);
return res;
}
}
通用迭代法
**Reference:**https://www.acwing.com/solution/content/176/
https://mp.weixin.qq.com/s/WKg0Ty1_3SZkztpHubZPRg
需要解决的问题是访问结点(遍历结点)和处理结点(将元素放入结果集)的处理时间不一致的问题
即访问到某结点时,并不会立即加入结果集,而是需要先遍历完其左子树在加入结果集的问题
因此,可以将访问的结点都放入栈中,但是将需要处理的结点做标记
标记的方法为在需要处理的结点放入栈后,紧接着放一个空指针作为标记
二叉树前序遍历(通用迭代法)
二叉树中序遍历(通用迭代法)
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
LinkedList<Integer> res = new LinkedList<>();
Stack<TreeNode> sta = new Stack<>();
if (root == null) return res;
sta.push(root);
while (!sta.isEmpty()) {
TreeNode curr = sta.pop();
if (curr != null) {
sta.push(curr);
sta.push(null);
if (curr.right != null) sta.push(curr.right);
if (curr.left != null) sta.push(curr.left);
} else {
curr = sta.pop();
res.add(curr.val);
}
}
return res;
}
}