遍历二叉树

非递归实现

中序遍历

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution:
def inorderTraversal(self, root: TreeNode) -> List[int]:
cur = root #借助临时的cur,不要修改root
res = []
stack = []
while cur or stack:
if cur: # 一直往左走,全部入栈
stack.append(cur)
cur = cur.left
else: # 取出栈顶节点,处理,再处理该节点的右子树
cur = stack.pop()
res.append(cur.val)
cur = cur.right
return res

前序遍历

写法一

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution:
def preorderTraversal(self, root: TreeNode) -> List[int]:
cur = root
res = []
stack = []
while cur or stack:
if cur:
stack.append(cur) # 每一个节点都放入栈中
res.append(cur.val)
cur = cur.left
else:
cur = stack.pop() # 这里pop出来的是已经访问过的节点
cur = cur.right # 还需要指向右子树
return res

写法二:

1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution:
def preorderTraversal(self, root: TreeNode) -> List[int]:
cur = root
res = []
stack = []
while cur or stack:
if cur:
stack.append(cur.right) # 栈中直接放入已访问节点的右子树
res.append(cur.val)
cur = cur.left
else:
cur = stack.pop() # 取到的就是右子树根节点
return res

😐写法三:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Solution(object):
def preorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
if root is None:
return []
stack, output = [root], []

while stack:
root = stack.pop()
if root is not None:
output.append(root.val)
if root.right is not None: #右子树先入栈,左子树后入栈
stack.append(root.right)
if root.left is not None:
stack.append(root.left)

return output

后序遍历

https://leetcode-cn.com/problems/binary-tree-postorder-traversal/

对于当前节点,只有其右子树已经处理没有右子树时,才能处理它。

👀这里要记录一个last_visited节点​​

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Solution:
def postorderTraversal(self, root: TreeNode) -> List[int]:
cur = root
res = []
stack = []
last_visited = None
while cur or stack:
if cur:
stack.append(cur)
cur = cur.left
else:
tmp = stack[-1] # 定位根节点,这个地方不能pop(),因为可能有右子树
if not tmp.right or tmp.right == last_visited:
# 没有右子树或者已经访问过了,处理当前根节点
res.append(tmp.val)
last_visited = tmp
stack.pop()
else:
cur = tmp.right # 右子树未访问,处理右子树
return res

后序遍历可以借前序遍历的一个变体实现,先根右左,再倒置

1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution:
def preorderTraversal(self, root: TreeNode) -> List[int]:
cur = root
res = []
stack = []
while cur or stack:
if cur:
stack.append(cur.left) # 栈中直接放入已访问节点的左子树
res.append(cur.val)
cur = cur.right
else:
cur = stack.pop() # 取到的就是左子树根节点
return res[::-1]