1.图的宽度优先搜索代码非常容易实现,如果你会二叉树的层序遍历,那么图的宽度优先搜索就是在层序遍历的基础之上,引入visited集合,每当入队时,首先考虑入队结点是否处于visited集合中,如果在,说明曾经入队,就跳过。
我们先看一下二叉树的层序遍历
class Solution:
def levelOrder(self, root: TreeNode) -> List[List[int]]:
if not root:
return []
res = []
queue = [root]
while queue:
cur_level = []
cur_len = len(queue)
for _ in range(cur_len):
cur = queue.pop(0)
cur_level.append(cur.val)
if cur.left:
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
res.append(cur_level)
return res
图的宽度优先搜索
class Solution:
def levelOrder(self, root: TreeNode) -> List[List[int]]:
if not root:
return []
res = []
queue = [root]
node_set = {root}
while queue:
cur_level = []
cur_len = len(queue)
for _ in range(cur_len):
cur = queue.pop(0)
cur_level.append(cur.val)
for next_node in cur.next:
if next_node not in node_set:
queue.append(next_node)
node_set.append(next_node)
res.append(cur_level)
return res
实际上就是增加了一个集合set用于判断是否曾经遍历过,以防止重复遍历。
2.图的深度优先搜索可以联系二叉树的先序和后续遍历
我们先来看一下先序遍历代码
class Solution:
def preorderTraversal(self, root: TreeNode) -> List[int]:
if not root:
return
stack = [root]
res = []
while stack:
cur_node = stack.pop()
res.append(cur_node.val)
if cur_node.right:
stack.append(cur_node.right)
if cur_node.left:
stack.append(cur_node.left)
return res
同样的,图的深度优先遍历需要一个set来保证不重复遍历,不过和树的先序遍历不同的是,图的深度优先遍历需要将当前结点重复压回栈中,以存储之前的状态。
class Solution:
def deepTraversal(self, root: TreeNode) -> List[int]:
if not root:
return
stack = [root]
res = [root]
set = {root}
while stack:
cur_node = stack.pop()
for next_node in cur_node.next:
if next_node not in set:
stack.append(cur_node)
stack.append(next_node)
set.append(next_node)
res.append(next_node.val)
break
return res