Python算法——搜索(BFS和DFS)

一、 算法概述

1 BFS(广度优先搜索)

核心思想:逐层遍历,优先访问距离起始节点最近的节点。使用队列实现,确保按层次展开。 特点

保证找到无权图中的最短路径(边数最少) 
 

空间复杂度较高,需存储每一层的节点(O(b^d),b为分支因子,d为深度) 
 

2 DFS(深度优先搜索)

核心思想:沿路径尽可能深入,直到无法继续再回溯。使用(递归隐式调用栈或显式栈)实现。 特点

空间复杂度较低,仅需存储当前路径(O(d),d为深度) 
 

可能陷入无限循环(需通过标记已访问节点解决) 

二、部分实例的代码实现

P1443 马的遍历 - 洛谷

from collections import deque
n,m,x,y=map(int,input().split())
#马的行动路径,上下为一组
dx=[1,2,-1,-2,1,2,-1,-2]
dy=[2,1,2,1,-2,-1,-2,-1]
a=[[0]*(m+5) for _ in range(n+5)]
for i in range(n+5):
    for j in range(m+5):
        #无法到达的标记为-1
        a[i][j]=-1
#初始位置只需0步
a[x][y]=0

#建立双端队列(右进左出,先进先出),标记走过的位置,不再重复走
q=deque()
q.append([x,y])
while q:
    x,y=q.popleft()
    for i in range(8):
        xx=x+dx[i]
        yy=y+dy[i]
        #检验新位置是否合法
        if (1<=xx<=n and 1<=yy<=m and a[xx][yy]==-1):
            a[xx][yy]=a[x][y]+1
            q.append([xx,yy])
for i in range(1,n+1):
    for j in range(1,m+1):
        print(a[i][j],end=" ")
    print(end="\n")

P1135 奇怪的电梯 - 洛谷

from collections import deque
n,a,b=map(int,input().split())
k=[0]*201
k=list(map(int,input().split()))
#初始位置需要0次
k=[0]+k
#记录已经到过的位置,不再回来(集合自动去重)
v=set()
#设定最大次数
ans=100001
q=deque()
q.append([a,0])
v.add(a)
while q:
    now,cnt=q.popleft()
    #次数过多,认为无法到达
    if(cnt>=ans):
        break
    #到达目标楼层,跳出循环
    if now == b :
        ans= cnt
        break
    #判断新楼层是否合法(楼层合法,从未到达)
    if(1<=now+k[now]<=n and (now+k[now] not in v)):
        #记录到达的楼层
        v.add(now+k[now])
        #记录楼层对应的次数
        q.append([now+k[now],cnt+1])
    if(1<=now-k[now]<=n and (now-k[now] not in v)):
        v.add(now-k[now])
        q.append([now-k[now],cnt+1])
#无法到达,输出-1
if ans == 100001 :
    ans=-1
print(ans)

P1605 迷宫 - 洛谷

n,m,t=map(int,input().split())
sx,sy,fx,fy=map(int,input().split())
#记录路径,四种方向
dx=[0,1,-1,0]
dy=[1,0,0,-1]
a=[[0]*(m+1) for _ in range(n+1)]
#将障碍标记为1
for _ in range(t):
    x,y=map(int,input().split())
    a[x][y]=1
ans=0
def dfs(x,y):
    global ans
    #能够到达,次数+1
    if(x==fx and y==fy):
        ans+=1
        return
    #自身标记为1,看做障碍,不再回来
    a[x][y]=1
    for i in range(4):
        xx=x+dx[i]
        yy=y+dy[i]
        #判断是否合法(在迷宫里,不为障碍)
        if (1<=xx<=n and 1<=yy<=m and a[xx][yy]==0):
            dfs(xx,yy)
    a[x][y]=0
dfs(sx,sy)
print(ans)

三、应用场景

场景BFSDFS
最短路径最优解可能非最优
环路检测需要额外标记通过回溯检测
层次遍历按层输出无法保证层次顺序
大规模图空间开销大内存占用低

典型问题

BFS:社交网络关系链最短查找、棋盘游戏最少步数 
 

DFS:八皇后问题、图的着色问题、文件系统遍历 
 

四、性能与优化

时间复杂度:两者均为O(V+E)(V为顶点数,E为边数) 

空间优化

BFS可用双向BFS减少空间占用

DFS可用剪枝策略(如回溯法中的条件判断)提升效率 

五、总结

选择依据:优先BFS解决最短路径问题,DFS用于内存敏感或需深度探索的场景 
 

代码实现关键:标记已访问节点避免重复遍历,合理选择数据结构(队列/栈) 
 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值