新手学习算法----二叉树(后序遍历)
这种算法只用到了一次入栈一次出栈就可以了,
//首先将根节点的左节点所有的节点入栈,一直到叶子节点,先将最右的叶子节点入栈,然后判断是否已到了叶子节点,如果是则将节点的value值入栈,接着将此节点出栈,因为它没用了 public ArrayList<Integer> postorderTraversal(TreeNode root) { // write your code here Stack<TreeNode> s = new Stack<TreeNode>(); ArrayList<Integer> Result = new ArrayList<Integer>(); if(root == null) return Result; TreeNode cur; TreeNode pre = null; s.push(root); //对于所有的节点都先入栈 while(!s.empty()){ cur = s.peek(); //当前操作数为栈的顶部元素 if((cur.left==null&&cur.right==null)||(pre !=null&&(pre==cur.left||pre==cur.right))){ //如果当前操作数左右都为空,或者P存在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了,说明可以访问该节点了,然后此节点就没用了可以出栈了 Result.add(cur.val); s.pop(); pre = cur; //先保留一会儿当前的节点,留着用来判断是否该访问他的父节点。 }else { if(cur.right!=null) s.push(cur.right); //如果当前节点右节点不为空就入栈,只有先让右节点入栈才可以保证访问的顺序是对的, if(cur.left!=null) s.push(cur.left);//如果左孩子不为空,左孩子最后入栈 } } return Result; }
九章算法:
Stack<TreeNode> s = new Stack<TreeNode>(); ArrayList<Integer> r = new ArrayList<Integer>(); if(root ==null) return r; TreeNode pre = null; TreeNode cur; s.push(root); while(!s.empty()){ cur = s.peek(); if(pre==null||pre.left ==cur||pre.right==cur){ //先从上往下遍历到叶子节点 if(cur.left!=null){ s.push(cur.left); //将每一个左子树节点入栈 }else if(cur.right!=null){ //如他的左子节点为空判断右节点,如果不为空就将右节点入栈 s.push(cur.right); } }else if(cur.left==pre){ //开始从左子树的底部往上遍历,当cur.left==pre说明已经到达了左子树的底部他的左子树已经遍历了,执行这一步的时候说明该节点的左孩子已经遍历到了且出栈了 if(cur.right!=null){ //这时需要做的是将右孩子入栈待遍历 s.push(cur.right); } }else { //从右子树的底部往上遍历 r.add(cur.val); s.pop(); } pre=cur; } return r;
递归实现:
ArrayList<Integer> r = new ArrayList<Integer>(); if(root ==null){ return r; } r.addAll(postorderTraversal(root.left)); r.addAll(postorderTraversal(root.right)); r.add(root.val); return r;