|
| 1 | +packageAlgorithms.tree; |
| 2 | + |
| 3 | +importjava.util.ArrayList; |
| 4 | +importjava.util.List; |
| 5 | +importjava.util.Stack; |
| 6 | + |
| 7 | + |
| 8 | +publicclassInorderTraversal { |
| 9 | +publicstaticList<Integer>inorderTraversal(TreeNoderoot) { |
| 10 | +ArrayList<Integer>ret =newArrayList<Integer>(); |
| 11 | +inorderTraversal(root,ret); |
| 12 | +returnret; |
| 13 | + } |
| 14 | + |
| 15 | +publicstaticvoidinorderTraversalRec(TreeNoderoot,ArrayList<Integer>ret) { |
| 16 | +if (root ==null) { |
| 17 | +return; |
| 18 | + } |
| 19 | + |
| 20 | +inorderTraversalRec(root.left,ret); |
| 21 | + |
| 22 | +ret.add(root.val); |
| 23 | + |
| 24 | +inorderTraversalRec(root.right,ret); |
| 25 | + } |
| 26 | + |
| 27 | +publicstaticvoidinorderTraversal(TreeNoderoot,ArrayList<Integer>ret) { |
| 28 | +if (root ==null) { |
| 29 | +return; |
| 30 | + } |
| 31 | + |
| 32 | +TreeNodecur =root; |
| 33 | +Stack<TreeNode>s =newStack<TreeNode>(); |
| 34 | + |
| 35 | +while (true) { |
| 36 | +// 因为是inorder,所以要一直先处理左节点,所以我们必须找到最最左边这一个节点, |
| 37 | +// 否则是不处理的,也就是一直压栈。 |
| 38 | +while (cur !=null) { |
| 39 | +s.push(cur); |
| 40 | +cur =cur.left; |
| 41 | + } |
| 42 | + |
| 43 | +// 如果栈空,表明没有任何需要处理的元素了. |
| 44 | +if (s.isEmpty()) { |
| 45 | +break; |
| 46 | + } |
| 47 | + |
| 48 | +/* |
| 49 | + * 1 |
| 50 | + * / \ |
| 51 | + * 2 6 |
| 52 | + * / \ |
| 53 | + * 3 5 |
| 54 | + * / |
| 55 | + * 4 |
| 56 | + * |
| 57 | + * 例如:1, 2, 3, 4会入栈。 |
| 58 | + * 4,3,2陆续弹出 |
| 59 | + * |
| 60 | + * 然后会转向2的右节点,5. 5处理完后,会继续弹栈,也就是1. |
| 61 | + * 最后处理6. |
| 62 | + * |
| 63 | + * */ |
| 64 | + |
| 65 | +// 因为所有的左节点全部已经加入栈中了,开始处理栈顶的元素, |
| 66 | +// 或者是右子树是空的,那么弹出一个之前的节点来处理 |
| 67 | +cur =s.pop(); |
| 68 | + |
| 69 | +// 处理当前节点(左节点与根节点 ) |
| 70 | +ret.add(cur.val); |
| 71 | + |
| 72 | +// 处理了左节点与根节点,再处理右子树。 |
| 73 | +cur =cur.right; |
| 74 | + } |
| 75 | + } |
| 76 | +} |