后序遍历二叉树(题目来源于leetcode)
后序遍历二叉树
模板为
class Solution {
public List postorderTraversal(TreeNode root) {
}
}
我的思路
使用stack控制访问的顺序
从根节点出发,依次遍历左子树,加入stack中
使用hashMap记入分支节点的访问次数每一个分支节点应当访问两次,且第一次访问时,不能直接加入list中,需等到第二次才可以
linkedListleetcode优解list = new linkedList<>(); if(root==null)return list; //postorder-traversal:left--right---root //使用栈控制访问顺序 //从根节点出发,依次遍历左子树,加入stack中 Stack stack = new Stack<>(); while(root!=null){ stack.add(root); root=root.left; } //使用hashMap记入分支节点的访问次数 HashMap hashMap = new HashMap<>(); while(!stack.isEmpty()){ TreeNode elem = stack.peek(); //elem右孩子为空,直接加入list,无需考虑访问次数 if(elem.right==null)list.add(stack.pop().val); else{ //3. 第二次访问elem,则加入list中 if(hashMap.containsKey(elem)){ list.add(stack.pop().val); } } //1. 首次访问分支节点elem,且hashmap中没有记入 if(elem.right!=null&&!hashMap.containsKey(elem)){ //2. 第一次访问,加入hashmap hashMap.put(elem,1); //从当前节点出发,依次遍历左子树,加入stack中 TreeNode node = elem.right; while (node != null) { stack.add(node); node=node.left; } } } return list;
看完真可谓是巧夺天工!!!
从根节点出发,依次遍历右子树(直接反过来),加入stack中,并直接加入list中
对于栈顶元素处理判断有无左孩子,如果有,从左孩子出发,依次遍历右子树(直接反过来),加入stack中,并直接加入list中
最终来个翻转List例子说明 执行玩第一个while循环res= new ArrayList (); Deque stack = new ArrayDeque (); while(!stack.isEmpty() || root != null){ while(root != null){ stack.offerLast(root); res.add(root.val); root = root.right; } root = stack.pollLast(); root = root.left; } Collections.reverse(res); return res;
root = stack.pollLast();
root=6
root = root.left;
root=null
root = stack.pollLast();
root=3
root = root.left;
root=null
root = stack.pollLast();
root=1
root = root.left;
root=2
第三次循环结束后root = stack.pollLast();
root=2
root = root.left;
root=4
执行完第四次循环后 第五次循环root = stack.pollLast();
root=4
root = root.left;
root=null------》结束循环
第六次循环root = stack.pollLast();
root=4
root = root.left;
root=null------》结束循环
此时list
再翻转,perfect!!!!



