BFS/DFS python模板与实现
BFS模板
1. 无需分层遍历
while queue 不空:
cur = queue.pop()
for 节点 in cur的所有相邻节点:
if 该节点有效且未访问过:
queue.push(该节点)
树的遍历
'''
树的遍历
'''
from collections import deque
# Definition for a binary tree node.
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
def level_order_tree(root, result):
if not root:
return
# 这里借助python的双向队列实现队列
# 避免使用list.pop(0)出站的时间复杂度为O(n)
queue = deque([root])
while queue:
node = queue.popleft()
# do somethings
result.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
return result
if __name__ == "__main__":
tree = TreeNode(4)
tree.left = TreeNode(9)
tree.right = TreeNode(0)
tree.left.left = TreeNode(5)
tree.left.right = TreeNode(1)
print(level_order_tree(tree, []))
# [4, 9, 0, 5, 1]
图的遍历
'''
图的遍历
'''
from collections import deque
def bsf_graph(root):
if not root:
return
# queue和seen为一对好基友,同时出现
queue = deque([root])
# seen避免图遍历过程中重复访问的情况,导致无法跳出循环
seen = set([root])
while queue:
head = queue.popleft()
# do somethings with the head node
# 将head的邻居都添加进来
for neighbor in head.neighbors:
if neighbor not in seen:
queue.append(neighbor)
seen.add(neighbor)
return xxx
2. 确定当前遍历到了哪一层
level = 0
while queue 不空:
size = queue.size()
while (size --) {
cur = queue.pop()
for 节点 in cur的所有相邻节点:
if 该节点有效且未被访问过:
queue.push(该节点)
}
level ++;
'''
树的遍历
'''
def level_order_tree(root):
if not root:
return
q = [root]
while q:
new_q = []
for node in q:
# do somethins with this layer nodes...
# 判断左右子树
if node.left:
new_q.append(node.left)
if node.right:
new_q.append(node.right)
# 记得将旧的队列替换成新的队列
q = new_q
# 最后return想要返回的东西
return xxx
'''
图的遍历
'''
def bsf_graph(root):
if not root:
return
queue = [root]
seen = set([root])
while queue:
new_queue = []
for node in queue:
# do somethins with the node
for neighbor in node.neighbors:
if neighbor not in seen:
new_queue.append(neighbor)
seen.add(neighbor)
return xxx
DFS
DFS尽可能深的搜索每个树枝,一直搜索到最深的那一个为止。
DFS原理
当DFS走到一条死路(再也没有可能的合法移动的方式)时,它会沿着树返回直到该节点有路可走。然后继续往深处探索。
DFS用的是栈。搜了k层的点a,再搜k+1层的点b,再 搜k+2层的点c。搜到c时,当前点标记为b,搜完c若返回false,那么就会回来从b再向下别的方向进行搜索。搜索了这个点,还可能回来再搜这个点向下的别的方向。
-
模板
'''
递归
'''
visited = set()
def dfs(node, visited):
if node in visited:
return
visited.add(node)
for next_node in node.children():
if not next_node in visited:
dfs(next_node, visited)
def DFS(self, tree):
if tree.root is None:
return []
visited, stack = [], [tree.root]
while stack:
node = stack.pop()
visited.add(node)
process(node)
nodes = generate_related_nodes(node)
stack.push(nodes)
练习
给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。
示例:
二叉树:[3,9,20,null,null,15,7]
,3 / \ 9 20 / \ 15 7
返回其层序遍历结果:
[ [3], [9,20], [15,7] ]
使用BFS
from collections import deque
class Solution:
# N is the size of tree
# Time Complexity: O(N)
# Space Complexity: O(N)
def levelOrder(self, root: TreeNode) -> List[List[int]]:
result = []
if root is None:
return result
q = deque([])
q.append(root)
while len(q) > 0:
size = len(q)
level = []
while size > 0:
cur = q.popleft()
level.append(cur.val)
if cur.left is not None:
q.append(cur.left)
if cur.right is not None:
q.append(cur.right)
size = size - 1
result.append(level)
return result
使用DFS
class Solution:
def levelOrder(self, root: TreeNode) -> List[List[int]]:
result = []
if root is None:
return result
self.dfs(root, result, 0)
return result
def dfs(self, node, result, level):
if node is None:
return
if level > len(result) - 1:
result.append([])
result[level].append(node.val)
if node.left is not None:
self.dfs(node.left, result, level + 1)
if node.right is not None:
self.dfs(node.right, result, level + 1)
难度简单168
给定二叉搜索树的根结点
root
,返回值位于范围[low, high]
之间的所有结点的值的和。
输入:root = [10,5,15,3,7,null,18], low = 7, high = 15 输出:32
递归
class Solution:
# N is the size of Tree
# H is the height of Tree
# Time Complexity: O(N)
# Space Complexity: O(H)
def rangeSumBST(self, root: TreeNode, low, high):
result=0
if root is None:
return result
leftSum = self.rangeSumBST(root.left, low, high)
rightSum = self.rangeSumBST(root.right, low, high)
result = leftSum + rightSum
if (root.val >= low and root.val <= high):
result = result + root.val
return result
class Solution:
def rangeSumBST(self, root: TreeNode, low, high):
def dfs(node):
if node:
if low <= node.val <= high:
self.ans += node.val
if low < node.val:
dfs(node.left)
if node.val < high:
dfs(node.right)
self.ans = 0
dfs(root)
return self.ans
迭代实现深度优先搜索
class Solution:
def rangeSumBST(self, root: TreeNode, low, high):
ans = 0
stack = [root]
while stack:
node = stack.pop()
if node:
if low <= node.val <= high:
ans += node.val
if low < node.val:
stack.append(node.left)
if node.val < high:
stack.append(node.right)
return ans
BFS
class Solution:
def rangeSumBST(self, root: TreeNode, low, high):
result=0
if root is None:
return 0
q = deque([])
q.append(root)
while len(q) > 0:
size = len(q)
while size > 0:
cur = q.popleft()
if cur.val<=high and cur.val >=low:
result+=cur.val
if cur.left is not None:
q.append(cur.left)
if cur.right is not None:
q.append(cur.right)
size = size - 1
return result
参考链接 https://www.jianshu.com/p/453c3850a9d2