Binary Tree Postorder Traversal

描述

Given a binary tree, return the postorder traversal of its nodes' values.

For example:Given binary tree {1,#,2,3},

  1. 1
  2. \
  3. 2
  4. /
  5. 3

return [3,2,1].

Note: Recursive solution is trivial, could you do it iteratively?

分析

用栈或者Morris遍历。

  1. // Binary Tree Postorder Traversal
  2. // 使用栈,时间复杂度O(n),空间复杂度O(n)
  3. class Solution {
  4. public List<Integer> postorderTraversal(TreeNode root) {
  5. ArrayList<Integer> result = new ArrayList<>();
  6. Stack<TreeNode> s = new Stack<>();
  7. /* p,正在访问的结点,q,刚刚访问过的结点*/
  8. TreeNode p = root;
  9. TreeNode q = null;
  10. do {
  11. while (p != null) { /* 往左下走*/
  12. s.push(p);
  13. p = p.left;
  14. }
  15. q = null;
  16. while (!s.empty()) {
  17. p = s.pop();
  18. /* 右孩子不存在或已被访问,访问之*/
  19. if (p.right == q) {
  20. result.add(p.val);
  21. q = p; /* 保存刚访问过的结点*/
  22. } else {
  23. /* 当前结点不能访问,需第二次进栈*/
  24. s.push(p);
  25. /* 先处理右子树*/
  26. p = p.right;
  27. break;
  28. }
  29. }
  30. } while (!s.empty());
  31. return result;
  32. }
  33. }

Morris后序遍历

  1. // Binary Tree Postorder Traversal
  2. // Morris后序遍历,时间复杂度O(n),空间复杂度O(1)
  3. class Solution {
  4. public List postorderTraversal(TreeNode root) {
  5. ArrayList result = new ArrayList<>();
  6. TreeNode dummy = new TreeNode(-1);
  7. dummy.left = root;
  8. TreeNode cur = dummy;
  9. TreeNode prev = null;
  10. while (cur != null) {
  11. if (cur.left == null) {
  12. prev = cur; /* 必须要有 */
  13. cur = cur.right;
  14. } else {
  15. TreeNode node = cur.left;
  16. while (node.right != null && node.right != cur)
  17. node = node.right;
  18. if (node.right == null) { /* 还没线索化,则建立线索 */
  19. node.right = cur;
  20. prev = cur; /* 必须要有 */
  21. cur = cur.left;
  22. } else { /* 已经线索化,则访问节点,并删除线索 */
  23. visit_reverse(cur.left, prev, result);
  24. prev.right = null;
  25. prev = cur; /* 必须要有 */
  26. cur = cur.right;
  27. }
  28. }
  29. }
  30. return result;
  31. }
  32. // 逆转路径
  33. private static void reverse(TreeNode from, TreeNode to) {
  34. TreeNode x = from;
  35. TreeNode y = from.right;
  36. TreeNode z = null;
  37. if (from == to) return;
  38. while (x != to) {
  39. z = y.right;
  40. y.right = x;
  41. x = y;
  42. y = z;
  43. }
  44. }
  45. // 访问逆转后的路径上的所有结点
  46. private static void visit_reverse(TreeNode from, TreeNode to,
  47. List result) {
  48. TreeNode p = to;
  49. reverse(from, to);
  50. while (true) {
  51. result.add(p.val);
  52. if (p == from)
  53. break;
  54. p = p.right;
  55. }
  56. reverse(to, from);
  57. }
  58. }

相关题目

原文: https://soulmachine.gitbooks.io/algorithm-essentials/content/java/binary-tree/traversal/binary-tree-postorder-traversal.html