序言
BFS算法–广度优先搜索
BFS是广度优先搜索算法。图形搜索算法。从根节点出发 沿着树的宽度遍历树的节点,等发现目标,则终止
先用字典录入每一个节点,以及相连的其他节点;如下:
dic =
{
"A";["B","C"],
"B":["A","C","D"],
"C":["A","B","D","E"],
"D":["B","C","E","F"],
"E":["C","D"];
"F":["D"]
}
#开始定义BFS
def bfs(dic, start):
queue = []
#动态的存入用append()
#动态的取出用pop()
#存入初始值
queue.append(start)
#记录走过的节点
see = set()
see.add(start)
while len(queue)>0:
#先走一步,把队列的第一个元素作为vertex
vertex = queue.pop(0)
#取出队列中第一个元素
nodes = dic[vertex]
for i in nodes:
if i not in see:
queue.append(i)
seen.add(i)
print(vertex)
bfs(dic,"E")
如果数据类型是链表的格式,用链表的形式做BFS
用例子来说明这个算法:
给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)
二叉树:[3,9,20,null,null,15,7]
3
/ \
9 20
/ \
15 7
输出:
[
[3],
[9,20],
[15,7]
]
比如首先定义一个二叉树 ,
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
层序遍历一个二叉树。就是从左到右一层一层的去遍历二叉树。
队列先进先出,符合一层一层遍历的逻辑,而是用栈先进后出适合模拟深度优先遍历也就是递归的逻辑。
def levelOrder(root: TreeNode):
#如果root是空集,则return []
if not root: return []
queue = []
queue.append(root)
ans = []
while len(queue)>0:
#把queue这一层的value录入ans
ans.append([node.val for node in queue])
#为了录入下一层的nodes,创建空list
seen = []
for node in queue:
if node.left :
#如果i的left有值,录入seen
seen.append(node.left)
if node.right:
#如果i的right有值,录入seen
seen.append(node.right)
#把这一层的nodes 放入队列
queue = seen
return ans
再来几道BFS题目
给定一棵二叉树,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
二叉树的右视图
输入: [1,2,3,null,5,null,4]
输出: [1, 3, 4]
解释:
1 <---
/ \
2 3 <---
\ \
5 4 <---
def rightSideView(root: TreeNode):
#如果空集,则return []
if not root: return []
queue = []
queue.append(root)
ans = []
while len(queue)>0:
#把queue的最后一个node的数据录入ans
#最后一个就是右视图
ans.append(queue[-1].val)
#记录每一层的nodes
seen = []
for node in queue:
if node.left:
seen.append(node.left)
if node.right:
seen.append(node.right)
queue = seen
return ans
给定一个二叉树,返回其节点值自底向上的层序遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
给定二叉树 [3,9,20,null,null,15,7]
3
/ \
9 20
/ \
15 7
输出:
[
[15,7],
[9,20],
[3]
]
这个跟前面那道题差不多,只要把结果倒叙就行
使用倒叙的方式是用户[:,:,-1]
例子如下:
arr = [1,2,3,4,3,4]
print arr[::-1]
输出:
[4, 3, 4, 3, 2, 1]
def largestValues(root: TreeNode):
#如果root是空集,则return []
if not root: return []
queue = []
queue.append(root)
ans = []
while len(queue)>0:
#把queue这一层的最大值的value录入ans
tmp = []
for node in queue:
tmp.append(node.val)
ans.append(max(tmp))
#为了录入下一层的nodes,创建空list
seen = []
for node in queue:
if node.left :
#如果i的left有值,录入seen
seen.append(node.left)
if node.right:
#如果i的right有值,录入seen
seen.append(node.right)
#把这一层的nodes 放入队列
queue = seen
return ans
您需要在二叉树的每一行中找到最大的值。
输入:
1
/ \
3 2
/ \ \
5 3 9
输出: [1, 3, 9]
#如果root是空集,则return []
if not root: return []
queue = []
queue.append(root)
ans = []
while len(queue)>0:
#把queue这一层的value录入ans
ans.append([node.val for node in queue])
#为了录入下一层的nodes,创建空list
seen = []
for node in queue:
if node.left :
#如果i的left有值,录入seen
seen.append(node.left)
if node.right:
#如果i的right有值,录入seen
seen.append(node.right)
#把这一层的nodes 放入队列
queue = seen
return ans
N叉树的前序遍历
N叉树 ,现在不是二叉树了。所以之前二叉树的定义也不一样了
N叉树的定义如下:
class Node:
def __init__(self, val=None, children=None):
self.val = val
self.children = children
给定一个 N 叉树,返回其节点值的层序遍历。(即从左到右,逐层遍历)。
树的序列化输入是用层序遍历,每组子节点都由 null 值分隔(参见示例)
输入:root = [1,null,3,2,4,null,5,6]
输出:[[1],[3,2,4],[5,6]]
def levelOrder(root: 'Node'):
if not root: return []
queue = []
queue.append(root)
ans = []
while len(queue) >0:
ans.append([node.val for node in queue])
seen = []
for node in queue:
for child in node.children:
seen.append(child)
queue = seen
return ans