一、 算法概述
1 BFS(广度优先搜索)
核心思想:逐层遍历,优先访问距离起始节点最近的节点。使用队列实现,确保按层次展开。 特点:
保证找到无权图中的最短路径(边数最少)
空间复杂度较高,需存储每一层的节点(O(b^d),b为分支因子,d为深度)
2 DFS(深度优先搜索)
核心思想:沿路径尽可能深入,直到无法继续再回溯。使用栈(递归隐式调用栈或显式栈)实现。 特点:
空间复杂度较低,仅需存储当前路径(O(d),d为深度)
可能陷入无限循环(需通过标记已访问节点解决)
二、部分实例的代码实现
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")
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)
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)
三、应用场景
场景 | BFS | DFS |
最短路径 | 最优解 | 可能非最优 |
环路检测 | 需要额外标记 | 通过回溯检测 |
层次遍历 | 按层输出 | 无法保证层次顺序 |
大规模图 | 空间开销大 | 内存占用低 |
典型问题:
BFS:社交网络关系链最短查找、棋盘游戏最少步数
DFS:八皇后问题、图的着色问题、文件系统遍历
四、性能与优化
时间复杂度:两者均为O(V+E)(V为顶点数,E为边数)
空间优化:
BFS可用双向BFS减少空间占用
DFS可用剪枝策略(如回溯法中的条件判断)提升效率
五、总结
选择依据:优先BFS解决最短路径问题,DFS用于内存敏感或需深度探索的场景
代码实现关键:标记已访问节点避免重复遍历,合理选择数据结构(队列/栈)