深度优先搜索(DFS)和广度优先搜索(BFS)——c#实现
一、深度优先搜索(DFS)
原理:
-
沿着分支尽可能深入,直到到达叶子节点,然后回溯探索其他分支
-
类似走迷宫时优先选择一条路走到黑,碰壁再回退
-
数据结构:栈(Stack)或递归实现
-
时间复杂度:O(V+E)(顶点数+边数)
-
// 递归实现(推荐) public void DFS(Node node, HashSet<Node> visited) { if (node == null || visited.Contains(node)) return; visited.Add(node); Console.Write(node.Value + " "); // 处理当前节点 foreach (var neighbor in node.Neighbors) { DFS(neighbor, visited); // 递归访问相邻节点 } } // 栈实现 public void DFS_Stack(Node root) { var stack = new Stack<Node>(); var visited = new HashSet<Node>(); stack.Push(root); while (stack.Count > 0) { var current = stack.Pop(); if (visited.Contains(current)) continue; visited.Add(current); Console.Write(current.Value + " "); // 注意:邻接节点要反向入栈(保持顺序) foreach (var neighbor in current.Neighbors.Reverse()) { stack.Push(neighbor); } } }
二、广度优先搜索(BFS)
原理:
-
逐层向外扩展搜索,先访问离起点最近的节点
-
类似水波纹扩散的效果
-
数据结构:队列(Queue)
-
时间复杂度:O(V+E)
-
public void BFS(Node root) { var queue = new Queue<Node>(); var visited = new HashSet<Node>(); queue.Enqueue(root); while (queue.Count > 0) { var current = queue.Dequeue(); if (visited.Contains(current)) continue; visited.Add(current); Console.Write(current.Value + " "); foreach (var neighbor in current.Neighbors) { queue.Enqueue(neighbor); } } }
三、核心区别对比
特性 深度优先搜索(DFS) 广度优先搜索(BFS) 数据结构 栈/递归 队列 空间复杂度 O(h)(树高) O(w)(最大宽度) 适用场景 拓扑排序、连通性检测 最短路径、层级遍历 解的性质 不一定最短路径 保证找到最短路径(无权图) 内存消耗 通常较小 可能较大(存储层级节点)
DFS 应用:
// 深度优先生成迷宫
private void GenerateMaze(int x, int y)
{
var current = Cells[x, y];
current.Visited = true;
var directions = GetRandomDirections(); // 随机方向
foreach (var dir in directions)
{
// 递归深入相邻单元格
if (CanMove(x, y, dir))
GenerateMaze(newX, newY);
}
}
BFS 应用(路径查找优化):
// 广度优先查找最短路径
public List<Point> FindShortestPath(MazeCell start, MazeCell end)
{
var queue = new Queue<MazeCell>();
var visited = new HashSet<MazeCell>();
var parentMap = new Dictionary<MazeCell, MazeCell>();
queue.Enqueue(start);
while (queue.Count > 0)
{
var current = queue.Dequeue();
if (current == end) break;
foreach (var neighbor in GetAccessibleNeighbors(current))
{
if (!visited.Contains(neighbor))
{
parentMap[neighbor] = current;
queue.Enqueue(neighbor);
visited.Add(neighbor);
}
}
}
return ReconstructPath(parentMap, end);
}
五、选择依据
需要最短路径 → 选BFS(如迷宫求解)
内存敏感/深度优先特性 → 选DFS(如迷宫生成)
层级关系分析 → 选BFS(如社交网络层级分析)
存在性验证 → 两者均可(如节点是否可达)
两种算法在您的迷宫项目中可以配合使用:DFS生成随机迷宫,BFS寻找最优路径,这正是大多数迷宫算法的经典实现方式。