1. 迭代二叉树
注意3个点则迭代正确:
确定递归函数的参数和返回值:确定哪些参数是递归的过程中需要处理的
确定终止条件
确定单层递归的逻辑
二叉树的前中后序遍历,看的是中间root节点的处理顺序
# 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]:
res=[]
def mid_tree(x):
if not x: return
res.append(x.val)
mid_tree(x.left)
mid_tree(x.right)
mid_tree(root)
return res
#中序遍历
def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
res=[]
def mid_tree(x):
if not x: return
mid_tree(x.left)
res.append(x.val)
mid_tree(x.right)
mid_tree(root)
return res
#后序遍历
def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
res=[]
def mid_tree(x):
if not x: return
mid_tree(x.left)
mid_tree(x.right)
res.append(x.val)
mid_tree(root)
return res
迭代写法:
手动把递归栈逻辑展开,需要自己单写一个显式stack
前序:
弹出root,处理root,先押right,后押left,这样先弹出left后弹出right
# 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]:
res=[]
if not root:return []
stack=[root]
while stack:
x=stack.pop()
res.append(x.val)
if x.right:
stack.append(x.right)
if x.left:
stack.append(x.left)
return res
中序遍历:
先访问root,但不能,要依次走左,直到最左,弹出最左,处理最左,找右,继续弹出次左,处理次左,找右
需要一个指针,指向访问的,栈用来确定处理的,此时访问的和处理的不一样(前序后序对root访问即处理,访问和处理是一样的,不需要等子节点完成再处理)
# 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 []
res=[]
stack=[]
cur=root
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
后序遍历:
实在是不好一直单拎着root,直接先left后right按照前序走,然后全结果颠倒
# 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 []
res=[]
stack=[root]
while stack:
node=stack.pop()
res.append(node.val)
if node.left:
stack.append(node.left)
if node.right:
stack.append(node.right)
return res[::-1]
统一迭代法:
一个也不处理,能遍历完全遍历完,到它该处理再押入一个None,弹出的时候遇到None就给res
前序:
class Solution:
def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
if not root:return []
res=[]
stack=[root]
while stack:
node=stack.pop()
if node:
if node.right:
stack.append(node.right)
if node.left:
stack.append(node.left)
stack.append(node)
stack.append(None)
else:
node=stack.pop()
res.append(node.val)
return res
中序:
# 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 []
res=[]
stack=[root]
while stack:
node=stack.pop()
if node:
if node.right:
stack.append(node.right)
stack.append(node)
stack.append(None)
if node.left:
stack.append(node.left)
else:
node=stack.pop()
res.append(node.val)
return res
后序:
后序也不用颠倒了,按照栈的先入后出,先把root压进去,且到root的时候就该处理了
# 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 []
res=[]
stack=[root]
while stack:
node=stack.pop()
if node:
stack.append(node)
stack.append(None)
if node.right:
stack.append(node.right)
if node.left:
stack.append(node.left)
else:
node=stack.pop()
res.append(node.val)
return res