BFS和DFS的python实现(要记住)

这篇博客介绍了BFS(广度优先搜索)和DFS(深度优先搜索)在Python中实现树和图遍历的基本模板。对于二叉树的层序遍历,可以通过BFS或DFS实现,而图的遍历同样可以利用这两种方法。在二叉树的层序遍历问题中,给出了BFS和DFS的具体代码实现,同时展示了如何在搜索过程中限制节点的访问范围,如在二叉搜索树中查找特定范围内的节点。这些基本模板对于理解和解决相关算法问题非常有帮助。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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)

练习

102. 二叉树的层序遍历

给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。

示例:
二叉树:[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)

 

938. 二叉搜索树的范围和

难度简单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

 

### 实现深度优先搜索(DFS)Python中,可以通过递归方式来实现深度优先搜索。对于每一个未访问的节点,调用递归函数`dfs_util(v, visited)`,该函数会遍历所有相邻且未被访问过的节点,并继续深入直到无法再前进为止[^2]。 ```python from collections import defaultdict class Graph: def __init__(self): self.graph = defaultdict(list) def addEdge(self, u, v): self.graph[u].append(v) def dfs_util(self, v, visited): visited.add(v) print(v, end=' ') for neighbour in self.graph[v]: if neighbour not in visited: self.dfs_util(neighbour, visited) def DFS(self, v): visited = set() self.dfs_util(v, visited) ``` 此代码定义了一个名为Graph的类,其中包含了添加边的方法以及执行DFS所需的功能。通过创建实例并调用相应的方法即可完成对指定图结构上的深度优先遍历操作。 ### 实现广度优先搜索(BFS) 相比之下,广度优先搜索则更倾向于层次化地探索图形数据结构。为了达到这一目的,在Python里可以利用队列的数据特性——先进先出来帮助管理待处理节点列表;每当取出一个元素时就将其邻接点加入到队尾等待后续处理[^1]。 ```python def bfs(graph, start_vertex): visited = set([start_vertex]) queue = [start_vertex] while queue: vertex = queue.pop(0) print(vertex, end=" ") for adjacent in graph[vertex]: if adjacent not in visited: visited.add(adjacent) queue.append(adjacent) ``` 上述程序片段展示了如何基于给定的graph字典对象来进行标准形式下的BFS迭代过程。这里假设输入参数graph是以顶点作为键而其对应的邻居们构成值集合的形式存储着整个无向连通网络的信息。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值