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?
1.递归算法的递归定义是:
若二叉树为空,则遍历结束;否则
⑴ 后序遍历左子树(递归调用本算法);
⑵ 后序遍历右子树(递归调用本算法) ;
⑶ 访问根结点 。
对有n个结点的二叉树,其时间复杂度均为O(n) 。
1 List<Integer> postOrder = new ArrayList<Integer>(); 2 public List<Integer> postorderRecursion(TreeNode root) { 3 if ((root != null) && (root.val != '#')) { 4 postorderRecursion(root.left); 5 postorderRecursion(root.right); 6 postOrder.add(root.val); 7 } 8 return postOrder; 9 }
2.非递归算法
在后序遍历中,根结点是最后被访问的。因此,在遍历过程中,当搜索指针指向某一根结点时,不能立即访问,而要先遍历其左子树,此时根结点进栈。当其左子树遍历完后再搜索到该根结点时,还是不能访问,还需遍历其右子树。所以,此根结点还需再次进栈,当其右子树遍历完后再退栈到到该根结点时,才能被访问。
因此,设立一个状态标志变量tag :{ 0 : 结点暂不能访问;1 : 结点可以被访问}。
其次,设两个堆栈S1、S2 ,S1保存结点,S2保存结点的状态标志变量tag 。S1和S2共用一个栈顶指针。
设T是指向根结点的指针变量,非递归算法是:
若二叉树为空,则返回;否则,令p=T;
⑴ 第一次经过根结点p,不访问:
p进栈S1 , tag 赋值0,进栈S2,p=p->Lchild 。
⑵ 若p不为空,转(1),否则,取状态标志值tag :
⑶ 若tag=0:对栈S1,不访问,不出栈;修改S2栈顶元素值(tag赋值1) ,取S1栈顶元素的右子树,即p=S1[top]->Rchild ,转(1);
⑷ 若tag=1:S1退栈,访问该结点;
直到栈空为止。
1 List<Integer> postOrder = new ArrayList<Integer>(); 2 public List<Integer> postorderTraversal(TreeNode p) { 3 Stack<TreeNode> stack = new Stack<TreeNode>(); 4 Stack<Boolean> tag = new Stack<Boolean>(); 5 while ((p != null) || !stack.isEmpty()) { 6 if (p != null) { 7 stack.push(p); 8 tag.push(false); 9 p = p.left; 10 } else { 11 boolean visit = tag.pop(); 12 if (visit) { 13 postOrder.add(stack.pop().val); 14 } else { 15 tag.push(true); 16 p = stack.peek().right; 17 } 18 } 19 } 20 return postOrder; 21 }
二叉树的三种遍历递归和非递归实现:递归实现都简单;非递归的前序和中序实现简单,后序采用2个栈来实现(参考严蔚敏的思路,比较容易理解)。代码如下:
1 import java.util.ArrayList; 2 import java.util.List; 3 import java.util.Stack; 4 5 import javax.swing.text.AbstractDocument.LeafElement; 6 7 /** 8 * Definition for binary tree public class TreeNode { int val; TreeNode left; 9 * TreeNode right; TreeNode(int x) { val = x; } } 10 */ 11 public class TreeNodeSolution { 12 13 public List<Integer> preorderRecursion(TreeNode root) { 14 List<Integer> preOrder = new ArrayList<Integer>(); 15 if ((root != null) && (root.val != '#')) { 16 preOrder.add(root.val); 17 postorderRecursion(root.left); 18 postorderRecursion(root.right); 19 } 20 return preOrder; 21 } 22 23 public List<Integer> inorderRecursion(TreeNode root) { 24 List<Integer> inOrder = new ArrayList<Integer>(); 25 if ((root != null) && (root.val != '#')) { 26 postorderRecursion(root.left); 27 inOrder.add(root.val); 28 postorderRecursion(root.right); 29 } 30 return inOrder; 31 } 32 33 public List<Integer> postorderRecursion(TreeNode root) { 34 List<Integer> postOrder = new ArrayList<Integer>(); 35 if ((root != null) && (root.val != '#')) { 36 postorderRecursion(root.left); 37 postorderRecursion(root.right); 38 postOrder.add(root.val); 39 } 40 return postOrder; 41 } 42 43 public List<Integer> inorderTraversal(TreeNode p) { 44 List<Integer> inOrder = new ArrayList<Integer>(); 45 Stack<TreeNode> stack = new Stack<TreeNode>(); 46 while ((p != null) || !stack.isEmpty()) { 47 if (p != null) { 48 stack.push(p); 49 p = p.left; 50 } else { 51 p = stack.pop(); 52 inOrder.add(p.val); 53 p = p.right; 54 } 55 } 56 return inOrder; 57 } 58 59 public List<Integer> preorderTraversal(TreeNode p) { 60 List<Integer> preOrder = new ArrayList<Integer>(); 61 Stack<TreeNode> stack = new Stack<TreeNode>(); 62 while ((p != null) || !stack.isEmpty()) { 63 if (p != null) { 64 preOrder.add(p.val); 65 stack.push(p); 66 p = p.left; 67 } else { 68 p = stack.pop(); 69 p = p.right; 70 } 71 } 72 return preOrder; 73 } 74 75 public List<Integer> postorderTraversal(TreeNode p) { 76 List<Integer> postOrder = new ArrayList<Integer>(); 77 Stack<TreeNode> stack = new Stack<TreeNode>(); 78 Stack<Boolean> tag = new Stack<Boolean>(); 79 while ((p != null) || !stack.isEmpty()) { 80 if (p != null) { 81 stack.push(p); 82 tag.push(false); 83 p = p.left; 84 } else { 85 boolean visit = tag.pop(); 86 if (visit) { 87 postOrder.add(stack.pop().val); 88 } else { 89 tag.push(true); 90 p = stack.peek().right; 91 } 92 } 93 } 94 return postOrder; 95 } 96 97 public static void main(String[] args) { 98 TreeNode t1 = new TreeNode(1); 99 TreeNode t2 = new TreeNode(2); 100 TreeNode t3 = new TreeNode(3); 101 t1.setRight(t2); 102 t1.setLeft(t3); 103 System.out.println(new TreeNodeSolution().postorderTraversal(t1)); 104 } 105 }