21
21
22
22
<p ><strong >进阶:</strong >  ; 递归算法很简单,你可以通过迭代算法完成吗?</p >
23
23
24
-
25
24
## 解法
26
25
27
26
<!-- 这里可写通用的实现逻辑 -->
28
27
29
- 递归遍历或利用栈实现非递归遍历。
28
+ ** 1. 递归遍历**
29
+
30
+ 先递归左右子树,再访问根节点。
31
+
32
+ ** 2. 栈实现非递归遍历**
30
33
31
34
非递归的思路如下:
32
35
33
36
先序遍历的顺序是:头、左、右,如果我们改变左右孩子的顺序,就能将顺序变成:头、右、左。
34
37
35
- 我们先不打印头节点,而是存放到另一个收集栈 s2 中,最后遍历结束,输出收集栈元素,即是后序遍历:左、右、头。
38
+ 我们先不打印头节点,而是存放到另一个收集栈 res 中,最后遍历结束,输出收集栈元素,即是后序遍历:左、右、头。收集栈是为了实现结果列表的逆序。我们也可以直接使用链表,每次插入元素时,放在头部,最后直接返回链表即可,无需进行逆序。
39
+
40
+ ** 3. Morris 实现后序遍历**
41
+
42
+ Morris 遍历无需使用栈,空间复杂度为 O(1)。核心思想是:
43
+
44
+ 遍历二叉树节点,
45
+
46
+ 1 . 若当前节点 root 的右子树为空,** 将当前节点值添加至结果列表 res** 中,并将当前节点更新为 ` root.left `
47
+ 2 . 若当前节点 root 的右子树不为空,找到右子树的最左节点 next(也即是 root 节点在中序遍历下的后继节点):
48
+ - 若后继节点 next 的左子树为空,** 将当前节点值添加至结果列表 res** 中,然后将后继节点的左子树指向当前节点 root,并将当前节点更新为 ` root.right ` 。
49
+ - 若后继节点 next 的左子树不为空,将后继节点左子树指向空(即解除 next 与 root 的指向关系),并将当前节点更新为 ` root.left ` 。
50
+ 3 . 循环以上步骤,直至二叉树节点为空,遍历结束。
51
+ 4 . 最后返回结果列表的逆序即可。
52
+
53
+ > Morris 后序遍历跟 Morris 前序遍历思路一致,只是将前序的“根左右”变为“根右左”,最后逆序结果即可变成“左右根”。
36
54
37
55
<!-- tabs:start -->
38
56
51
69
# self.right = right
52
70
class Solution :
53
71
def postorderTraversal (self , root : TreeNode) -> List[int ]:
72
+ res = []
73
+
54
74
def postorder (root ):
55
75
if root:
56
76
postorder(root.left)
57
77
postorder(root.right)
58
78
res.append(root.val)
59
- res = []
79
+
60
80
postorder(root)
61
81
return res
62
82
```
63
83
64
- 非递归:
84
+ 栈实现非递归:
85
+
86
+ ``` python
87
+ # Definition for a binary tree node.
88
+ # class TreeNode:
89
+ # def __init__(self, val=0, left=None, right=None):
90
+ # self.val = val
91
+ # self.left = left
92
+ # self.right = right
93
+ class Solution :
94
+ def postorderTraversal (self , root : TreeNode) -> List[int ]:
95
+ res = []
96
+ if root:
97
+ s = [root]
98
+ while s:
99
+ node = s.pop()
100
+ res.append(node.val)
101
+ if node.left:
102
+ s.append(node.left)
103
+ if node.right:
104
+ s.append(node.right)
105
+ return res[::- 1 ]
106
+ ```
107
+
108
+ Morris 遍历:
65
109
66
110
``` python
67
111
# Definition for a binary tree node.
@@ -72,18 +116,23 @@ class Solution:
72
116
# self.right = right
73
117
class Solution :
74
118
def postorderTraversal (self , root : TreeNode) -> List[int ]:
75
- if not root:
76
- return []
77
- s1 = [root]
78
- s2 = []
79
- while s1:
80
- node = s1.pop()
81
- s2.append(node.val)
82
- if node.left:
83
- s1.append(node.left)
84
- if node.right:
85
- s1.append(node.right)
86
- return s2[::- 1 ]
119
+ res = []
120
+ while root:
121
+ if root.right is None :
122
+ res.append(root.val)
123
+ root = root.left
124
+ else :
125
+ next = root.right
126
+ while next .left and next .left != root:
127
+ next = next .left
128
+ if next .left is None :
129
+ res.append(root.val)
130
+ next .left = root
131
+ root = root.right
132
+ else :
133
+ next .left = None
134
+ root = root.left
135
+ return res[::- 1 ]
87
136
```
88
137
89
138
### ** Java**
@@ -109,26 +158,63 @@ class Solution:
109
158
* }
110
159
*/
111
160
class Solution {
112
-
113
- private List<Integer > res;
114
-
115
161
public List<Integer > postorderTraversal (TreeNode root ) {
116
- res = new ArrayList<> ();
117
- postorder(root);
162
+ List< Integer > res = new ArrayList<> ();
163
+ postorder(root, res );
118
164
return res;
119
165
}
120
166
121
- private void postorder (TreeNode root ) {
167
+ private void postorder (TreeNode root , List< Integer > res ) {
122
168
if (root != null ) {
123
- postorder(root. left);
124
- postorder(root. right);
169
+ postorder(root. left, res );
170
+ postorder(root. right, res );
125
171
res. add(root. val);
126
172
}
127
173
}
128
174
}
129
175
```
130
176
131
- 非递归:
177
+ 栈实现非递归:
178
+
179
+ ``` java
180
+ /**
181
+ * Definition for a binary tree node.
182
+ * public class TreeNode {
183
+ * int val;
184
+ * TreeNode left;
185
+ * TreeNode right;
186
+ * TreeNode() {}
187
+ * TreeNode(int val) { this.val = val; }
188
+ * TreeNode(int val, TreeNode left, TreeNode right) {
189
+ * this.val = val;
190
+ * this.left = left;
191
+ * this.right = right;
192
+ * }
193
+ * }
194
+ */
195
+ class Solution {
196
+ public List<Integer > postorderTraversal (TreeNode root ) {
197
+ LinkedList<Integer > res = new LinkedList<> ();
198
+ if (root != null ) {
199
+ Deque<TreeNode > s = new LinkedList<> ();
200
+ s. offerLast(root);
201
+ while (! s. isEmpty()) {
202
+ TreeNode node = s. pollLast();
203
+ res. addFirst(node. val);
204
+ if (node. left != null ) {
205
+ s. offerLast(node. left);
206
+ }
207
+ if (node. right != null ) {
208
+ s. offerLast(node. right);
209
+ }
210
+ }
211
+ }
212
+ return res;
213
+ }
214
+ }
215
+ ```
216
+
217
+ Morris 遍历:
132
218
133
219
``` java
134
220
/**
@@ -148,25 +234,115 @@ class Solution {
148
234
*/
149
235
class Solution {
150
236
public List<Integer > postorderTraversal (TreeNode root ) {
151
- if (root == null ) {
152
- return Collections . emptyList();
237
+ LinkedList<Integer > res = new LinkedList<> ();
238
+ while (root != null ) {
239
+ if (root. right == null ) {
240
+ res. addFirst(root. val);
241
+ root = root. left;
242
+ } else {
243
+ TreeNode next = root. right;
244
+ while (next. left != null && next. left != root) {
245
+ next = next. left;
246
+ }
247
+ if (next. left == null ) {
248
+ res. addFirst(root. val);
249
+ next. left = root;
250
+ root = root. right;
251
+ } else {
252
+ next. left = null ;
253
+ root = root. left;
254
+ }
255
+ }
153
256
}
154
- Deque<TreeNode > s1 = new ArrayDeque<> ();
155
- List<Integer > s2 = new ArrayList<> ();
156
- s1. push(root);
157
- while (! s1. isEmpty()) {
158
- TreeNode node = s1. pop();
159
- s2. add(node. val);
160
- if (node. left != null ) {
161
- s1. push(node. left);
257
+ return res;
258
+ }
259
+ }
260
+ ```
261
+
262
+ ### ** C++**
263
+
264
+ ``` cpp
265
+ /* *
266
+ * Definition for a binary tree node.
267
+ * struct TreeNode {
268
+ * int val;
269
+ * TreeNode *left;
270
+ * TreeNode *right;
271
+ * TreeNode() : val(0), left(nullptr), right(nullptr) {}
272
+ * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
273
+ * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
274
+ * };
275
+ */
276
+ class Solution {
277
+ public:
278
+ vector<int > postorderTraversal(TreeNode * root) {
279
+ vector<int > res;
280
+ while (root)
281
+ {
282
+ if (root->right == nullptr)
283
+ {
284
+ res.push_back(root->val);
285
+ root = root->left;
162
286
}
163
- if (node. right != null ) {
164
- s1. push(node. right);
287
+ else
288
+ {
289
+ TreeNode * next = root->right;
290
+ while (next->left && next->left != root)
291
+ {
292
+ next = next->left;
293
+ }
294
+ if (next->left == nullptr)
295
+ {
296
+ res.push_back(root->val);
297
+ next->left = root;
298
+ root = root->right;
299
+ }
300
+ else
301
+ {
302
+ next->left = nullptr;
303
+ root = root->left;
304
+ }
165
305
}
166
306
}
167
- Collections . reverse(s2 );
168
- return s2 ;
307
+ reverse(res.begin(), res.end() );
308
+ return res ;
169
309
}
310
+ };
311
+ ```
312
+
313
+ ### **Go**
314
+
315
+ ```go
316
+ /**
317
+ * Definition for a binary tree node.
318
+ * type TreeNode struct {
319
+ * Val int
320
+ * Left *TreeNode
321
+ * Right *TreeNode
322
+ * }
323
+ */
324
+ func postorderTraversal(root *TreeNode) []int {
325
+ var res []int
326
+ for root != nil {
327
+ if root.Right == nil {
328
+ res = append([]int{root.Val}, res...)
329
+ root = root.Left
330
+ } else {
331
+ next := root.Right
332
+ for next.Left != nil && next.Left != root {
333
+ next = next.Left
334
+ }
335
+ if next.Left == nil {
336
+ res = append([]int{root.Val}, res...)
337
+ next.Left = root
338
+ root = root.Right
339
+ } else {
340
+ next.Left = nil
341
+ root = root.Left
342
+ }
343
+ }
344
+ }
345
+ return res
170
346
}
171
347
```
172
348
0 commit comments