@@ -240,14 +240,14 @@ class Solution {
240
240
# 前序遍历-迭代-LC144_二叉树的前序遍历
241
241
class Solution :
242
242
def preorderTraversal (self , root : TreeNode) -> List[int ]:
243
- # 根结点为空则返回空列表
243
+ # 根节点为空则返回空列表
244
244
if not root:
245
245
return []
246
246
stack = [root]
247
247
result = []
248
248
while stack:
249
249
node = stack.pop()
250
- # 中结点先处理
250
+ # 中节点先处理
251
251
result.append(node.val)
252
252
# 右孩子先入栈
253
253
if node.right:
@@ -262,19 +262,23 @@ class Solution:
262
262
# 中序遍历-迭代-LC94_二叉树的中序遍历
263
263
class Solution :
264
264
def inorderTraversal (self , root : TreeNode) -> List[int ]:
265
- stack = [] # 不能提前将root结点加入stack中
265
+
266
+ if not root:
267
+ return []
268
+ stack = [] # 不能提前将root节点加入stack中
269
+
266
270
result = []
267
271
cur = root
268
272
while cur or stack:
269
- # 先迭代访问最底层的左子树结点
273
+ # 先迭代访问最底层的左子树节点
270
274
if cur:
271
275
stack.append(cur)
272
276
cur = cur.left
273
- # 到达最左结点后处理栈顶结点
277
+ # 到达最左节点后处理栈顶节点
274
278
else :
275
279
cur = stack.pop()
276
280
result.append(cur.val)
277
- # 取栈顶元素右结点
281
+ # 取栈顶元素右节点
278
282
cur = cur.right
279
283
return result
280
284
```
@@ -289,7 +293,7 @@ class Solution:
289
293
result = []
290
294
while stack:
291
295
node = stack.pop()
292
- # 中结点先处理
296
+ # 中节点先处理
293
297
result.append(node.val)
294
298
# 左孩子先入栈
295
299
if node.left:
@@ -301,6 +305,44 @@ class Solution:
301
305
return result[::- 1 ]
302
306
```
303
307
308
+ #### Python 后序遍历的迭代新解法:
309
+ * 本解法不同于前文介绍的` 逆转前序遍历调整后的结果 ` ,而是采用了对每个节点直接处理。这个实现方法在面试中不容易写出来,在下一节,我将改造本代码,奉上代码更简洁、更套路化、更容易实现的统一方法。
310
+
311
+ ``` python
312
+ class Solution :
313
+ def postorderTraversal (self , root : Optional[TreeNode]) -> List[int ]:
314
+ values = []
315
+ stack = []
316
+ popped_nodes = set () # 记录值已经被收割了的 nodes,这是关键,已经被收割的节点还在树中,还会被访问到,但逻辑上已经等同于 null 节点。
317
+ current = root
318
+
319
+ while current or stack:
320
+ if current: # 一次处理完一个节点和他的左右儿子节点,不处理孙子节点,孙子节点由左右儿子等会分别处理。
321
+ stack.append(current) # 入栈自己
322
+
323
+ if current.right:
324
+ stack.append(current.right) # 入栈右儿子
325
+
326
+ if current.left: # 因为栈是后进先出,后序是‘左右中’,所以后加左儿子
327
+ stack.append(current.left) # 入栈左儿子
328
+
329
+ current = None # 会导致后面A处出栈
330
+ continue
331
+
332
+ node = stack.pop() # A处,出的是左儿子,如果无左儿子,出的就是右儿子,如果连右儿子也没有,出的就是自己了。
333
+
334
+ # 如果 node 是叶子节点,就可以收割了;如果左右儿子都已经被收割了,也可以收割
335
+ if (node.left is None or node.left in popped_nodes) and \
336
+ (node.right is None or node.right in popped_nodes):
337
+ popped_nodes.add(node)
338
+ values.append(node.val)
339
+ continue
340
+
341
+ current = node # 不符合收割条件,说明 node 下还有未入栈的儿子,就去入栈
342
+
343
+ return values
344
+ ```
345
+
304
346
### Go:
305
347
306
348
> 迭代法前序遍历
0 commit comments