一、思路
- 前/后序遍历:因为遍历的节点和当前要处理的节点不一样,所以可以采用两个路线的方法,其一是栈,负责记录遍历的顺序,处理当前弹出栈的元素,其二数组,负责将当前处理的元素添加进来。以前序遍历为例,根节点入栈→处理栈顶元素即弹出→右孩子入栈→左孩子入栈(先右后左才能使得下一个循环弹出顺序为先左后右)。
- 中序遍历:由于遍历的节点就是当前要处理的节点,因此采用三个路线的方法,前俩和上述基本一致,其三是需要有一个“指针”角色跟随当前遍历的节点。
二、代码
1、前序遍历
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
# 根结点为空则返回空列表
if not root:
return []
stack = [root]
result = []
while stack:
node = stack.pop()
# 中结点先处理
result.append(node.val)
# 右孩子先入栈
if node.right:
stack.append(node.right)
# 左孩子后入栈
if node.left:
stack.append(node.left)
return result
2、后序遍历
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
# 根结点为空则返回空列表
if not root:
return []
stack = [root]
result = []
while stack:
node = stack.pop()
# 中结点先处理
result.append(node.val)
# 左孩子先入栈
if node.left:
stack.append(node.left)
# 右孩子后入栈
if node.right:
stack.append(node.right)
return result[::-1]
3、中序遍历
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
if not root:
return []
stack = [] # 不能提前将root结点加入stack中
result = []
cur = root
while cur or stack:
# 先迭代访问最底层的左子树结点
if cur:
stack.append(cur)
cur = cur.left
# 到达最左结点后处理栈顶结点
else:
cur = stack.pop()
result.append(cur.val)
# 取栈顶元素右结点
cur = cur.right
return result
三、总结
- 有一说一还是有点绕,需要仔细想想
- 后序遍历和前序遍历基本一样,只需要改一下左右结点的处理顺序即可,返回的时候把顺序颠倒过来
部分内容参考代码随想录