@@ -51,30 +51,39 @@ public List<Integer> postorderTraversal2(TreeNode root) {
51
51
}
52
52
return ans ;
53
53
}
54
+
54
55
// TODO
55
56
// 【非递归】【单栈】后序遍历
56
57
public static List <Integer > postorderTraversal1 (TreeNode root ) {
57
- List <Integer > ans = new ArrayList <>();
58
- if (null == root ) {
59
- return ans ;
58
+ List <Integer > result = new ArrayList <>();
59
+ if (root == null ) {
60
+ return result ;
60
61
}
62
+
61
63
Stack <TreeNode > stack = new Stack <>();
62
- TreeNode c ;
63
- TreeNode h = root ;
64
- stack .push (h );
65
- while (!stack .isEmpty ()) {
66
- c = stack .peek ();
67
- // 如果c的左孩子和有孩子都不为空,且上一个节点不是c的右孩子,说明是c是新加入的节点,把左孩子压栈
68
- if (c .left != null && h != c .left && h != c .right ) {
69
- stack .push (c .left );
70
- } else if (c .right != null && h != c .right ) {
71
- stack .push (c .right );
72
- } else {
73
- ans .add (stack .pop ().val );
74
- h = c ;
64
+ TreeNode current = root ; // 当前探索指针
65
+ TreeNode lastVisit = null ; // 记录上一个被访问的节点
66
+
67
+ while (current != null || !stack .isEmpty ()) {
68
+ // 1. 左链入栈:一直向左走,把所有左孩子压栈
69
+ while (current != null ) {
70
+ stack .push (current );
71
+ current = current .left ;
72
+ }
73
+
74
+ // 2. 查看栈顶节点(不弹出,先判断右子树)
75
+ TreeNode peekNode = stack .peek ();
76
+
77
+ // 3. 如果右子树存在且未被访问过,则转向右子树
78
+ if (peekNode .right != null && peekNode .right != lastVisit ) {
79
+ current = peekNode .right ; // 处理右子树
80
+ } // 4. 否则(右子树为空或已访问),可以访问当前节点
81
+ else {
82
+ result .add (peekNode .val ); // 访问节点
83
+ lastVisit = stack .pop (); // 记录已访问
75
84
}
76
85
}
77
- return ans ;
86
+ return result ;
78
87
}
79
88
80
89
// morris遍历实现后序遍历
0 commit comments