树的迭代遍历
深度优先遍历(Depth-First-Search,DFS),沿着树的深度遍历树的节点,尽可能深的搜索树的分支。前序遍历和后序遍历是最常见的两种 DFS 方式,而 中序遍历一般用于平衡二叉树。
树的DFS的迭代方式实现,使用的数据结构是栈,配合双色标记法可以完成三种遍历方式的代码实现。下面以中序遍历实现为例:
实现思路:
- 使用颜色标记节点的状态,新节点为白色,已访问的节点为灰色。
- 如果遇到的节点为白色,则将其标记为灰色,然后将其右子节点、自身、左子节点依次入栈。
- 如果遇到的节点为灰色,则将节点的值输出。
注:如要实现前序、后序遍历,也只需要调整左右子节点的入栈顺序即可,其他部分是无需做任何变化。
代码实现:
import collections
class TreeNode(object):
"""
定义树的节点
"""
def __init__(self, val):
self.val = val
self.left = None
self.right = None
def dfs_in_order_traversal(root: TreeNode):
"""
树的深度优先遍历(以下简称 DFS)迭代方法实现(双色标记发)
:param root: 树的根节点
:return: 遍历结果
"""
# 以下代码以中序遍历为例,改变压栈顺序则相应为前、中、后序树的遍历
# 使用颜色标记节点的状态,白色表示未访问,灰色表示已访问
WHITE, GRAY = 0, 1
# 遍历结果存储列表
res = []
stack = [(WHITE, root)]
while stack:
color, node = stack.pop()
if node is None:
continue
# 如果遇到白色节点,则将其标记为灰色
# 然后将其右子节点、自身、左子节点依次压入栈中
# 注意改变压入栈的顺序则变为前序、后序遍历
if color is WHITE:
stack.append((WHITE, node.right))
stack.append((GRAY, node))
stack.append((WHITE, node.left))
else:
res.append(node.val)
return res
广度优先遍历(BFS)采用横向搜索的方式,BFS 比较适合解决最短距离/路径和某一个距离的目标的这样的问题。
实现思路:
- 首先将根节点放入队列中。
- 从队列中取出第一个节点,并检验它是否为目标:
如果找到目标,则结束搜索并回传结果。
否则将它所有尚未检验过的直接子节点加入队列中。- 若队列为空,表示整张图都检查过了——亦即图中没有欲搜索的目标。结束搜索并回传“找不到目标”。
- 重复步骤 2。
代码实现:
import collections
class TreeNode(object):
"""
定义树的节点
"""
def __init__(self, val):
self.val = val
self.left = None
self.right = None
def bfs_tree_traversal(root: TreeNode, k):
"""
使用双端队列操作树的广度优先搜索(BFS)
双端队列限制一头出队、入队则变成栈,限制一头只出队,另一个头只入队,则变成普通队列
bfs适合用来查找最短距离或路径、距离某一个目标的长度
数组删除元素的时间复杂度是O(N)
k是满足条件的距离长度,大于或小于k也是用这个模板的代码
"""
# 双端队列(两边都可以插入和删除)位于collections包下
# deque默认右端是队尾,左端是队头
# 默认方法是右端,即队尾
queue = collections.deque([root])
# 记录层数,即标记层
step = 0
# 满足条件需要返回的节点存储在列表中
ans = []
while queue:
# 当前层节点个数就是队列的长度
size = len(deque)
# 遍历当前层的所有节点
for _ in range(size):
# 数据出队操作,左侧是队头
node = queue.popleft()
# 判断是否满足条件
if (step == k):
ans.append(node)
# 检查当前节点它的下一层子节点,如果存在插入队列中
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
# 遍历完当前层的节点后,记录层的标记step自增1
step += 1
# 返回结果
return ans
参考文献:
https://leetcode-solution-leetcode-pp.gitbook.io/leetcode-solution/thinkings/tree#shu-de-bian-li-die-dai-xie-fa