提纲:深度遍历 DFS递归方法前序遍历
中序遍历
后序遍历
迭代方法前序遍历 先左后右
前序遍历 先右后左
中序遍历 先左后右
后序遍历 先左后右
后序遍历 先右后左
广度遍历 BFS递归方法
迭代方法
1. 深度遍历
最常考察的是树的深度遍历,同时写法也较多。
1.1 递归方法
最容易写的遍历方法,理解上也比较容易,简单过一遍。
1.1.1 前序
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def preorderTraversal(self, root: TreeNode) -> List[int]:
ans = []
def preRecursive(root):
if root is None:
return
ans.append(root.val)
preRecursive(root.left)
preRecursive(root.right)
preRecursive(root)
return ans
1.1.2 中序
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def inorderTraversal(self, root: TreeNode) -> List[int]:
ans = []
def inRecursive(root):
if root is None:
return
inRecursive(root.left)
ans.append(root.val)
inRecursive(root.right)
inRecursive(root)
return ans
1.1.3 后序
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def postorderTraversal(self, root: TreeNode) -> List[int]:
ans = []
def postRecursive(root):
if root is None:
return
postRecursive(root.left)
postRecursive(root.right)
ans.append(root.val)
postRecursive(root)
return ans
1.2 迭代方法
DFS的迭代写法主要是利用到了stack去实现,一般有两种实现方法。
一类是先左后右,类似于backtracking的思路,先把左节点一路压到底直到没有,再跳转到上一层的右侧子树。
一类是先右后左,先把右节点压入栈,再压入左节点。确保pop的时候,永远是左节点先出来。
1.2.1 前序 先左后右
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def preorderTraversal(self, root: TreeNode) -> List[int]:
if not root:
return []
stack = []
ans = []
while stack or root: # or root 用来处理根节点
while root:
stack.append(root)
ans.append(root.val) # 前序遍历,先访问left child
root = root.left
root = stack.pop() # 到底了,回到上一层
root = root.right # 转向右子树
return ans
1.2.2 前序 先右后左
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def preorderTraversal(self, root: TreeNode) -> List[int]:
if not root:
return []
stack = []
ans = []
stack.append(root)
while stack:
node = stack.pop()
ans.append(node.val)
if node.right:
stack.append(node.right) # 先把右侧压进去,左侧的才能先pop出来
if node.left:
stack.append(node.left)
return ans
1.2.3 中序 先左后右
中序先左后右的方法比较复杂,不推荐写。使用先左后右的方法,只许改变前序先左后右中打印的位置就好。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def inorderTraversal(self, root: TreeNode) -> List[int]:
if not root:
return []
stack = []
ans = []
while stack or root: # or root 用来处理根节点
while root:
stack.append(root)
root = root.left
root = stack.pop() # 到底了,回到上一层
ans.append(root.val) # 中序遍历,访问中间节点
root = root.right # 转向右子树
return ans
1.2.4 后序 先左后右
后序的先左后右不同于前序和中序,因为前序和中序在访问到左边节点和中间节点的时候,节点都是在stack中存储着了的,但是后序的时候,中间的节点是在之前已经被排出去了,所以无法访问到。
但是我们注意到后序的顺序是左,右,根,而前序的是根,左,右。我们只需先把后序的左右先倒置,变成右,左,根,再把整个序列的顺序倒置为根,左,右即可。把后序的左右先倒置只需要简单的把左右的位置换一下,把整个序列的顺序倒置则是把整个记录的结果倒置一下就好了。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def postorderTraversal(self, root: TreeNode) -> List[int]:
if not root:
return []
stack = []
ans = []
while stack or root: # or root 用来处理根节点
while root:
stack.append(root)
ans.insert(0, root.val) # 整个结果的倒置,后面来的插入到前面去
root = root.right # 先转向右边了
root = stack.pop() # 到底了,回到上一层
root = root.left # 再转向左边
return ans
1.2.5 后序 先右后左
思路和上个方法相似,先左右倒置,再把整个结果倒置。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def postorderTraversal(self, root: TreeNode) -> List[int]:
if not root:
return []
stack = []
ans = []
stack.append(root)
while stack:
node = stack.pop()
ans.insert(0, node.val) # 结果倒置
if node.left:
stack.append(node.left) # 左右倒置
if node.right:
stack.append(node.right)
return ans
2.1 广度遍历
2.1.1 递归方法
广度遍历的递归方法主要是利用了深度搜索+字典,将每一层的数值放到对应层的列表里即可。就好像把一堆书根据编码放到书架上的不同层一样。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def levelOrder(self, root: TreeNode) -> List[List[int]]:
ans = []
def dfs(root, cur_layer):
if not root: return
if len(ans) == cur_layer: # 新的一层
ans.append([])
ans[cur_layer].append(root.val) # 加入对应层数
dfs(root.left, cur_layer + 1)
dfs(root.right, cur_layer + 1)
dfs(root, 0)
return ans
2.1.2 迭代方法
广度遍历的迭代方法主要用queue队列来实现,一层一层的从左到右排好队记录即可。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def levelOrder(self, root: TreeNode) -> List[List[int]]:
if not root: return []
queue = []
ans = []
queue.append(root)
while queue:
next_queue= []
temp = []
for i in queue:
# 把这一层的值记录下来
temp.append(i.val)
# 把下一层从左到右排队放进去
if i.left:
next_queue.append(i.left)
if i.right:
next_queue.append(i.right)
ans.append(temp)
queue = next_queue# 转去下一层
return ans
参考资料:CSDN-专业IT技术社区-登录blog.csdn.net树3,用循环实现树的三种遍历www.jianshu.com