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

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值