学习内容
DFS和BFS算法,并用来解迷宫
学习收获
解迷宫题
BFS算法:
from collections import deque
#设置二维四向迷宫, 如果题目是多个小迷宫问题, 拆分多次调用脚本获取路径即可
maze = [['A', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '$'], ['$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '.', '.', '.', '.', '.', '.', '.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '.', '.', '.', '.', '.', '.', '.', '$', '$', '$', '$', '$'], ['$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '.', '.', '.', '.', '.', '.', '.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '.', '.', '.', '.', '.', '.', '.', '$', '$', '$', '$', '$'], ['$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.'], ['$', '$', '$', '$', '$', '$', '$', '.', '.', '.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '.', '.', '.', '.', '.', '.', '.', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '$', '.'], ['$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '.', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '$', '$', '$', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '$', '.'], ['$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '.', '.', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '.', '.', '.', '.', '.', '.', '.', '.', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '$', '.'], ['$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '.', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '.', '$', '.', '.', '.', '.', '.', '.', '.', '.', '.', '$', '.'], ['$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '.', '.', '.', '.', '.', '.', '.', '$', '$', '$', '$', '$', '.'], ['$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '.', '.', '.', '.', '.', '.', '.', '$', '$', '$', '$', '$', '.'], ['$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '.', '.', '.', '.', '.', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '.', '.', '.', '.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '.', '.', '.', '.', '.', '.', '.', '$', '$', '$', '$', '$', '.'], ['$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '.', '$', '$', '$', '$', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '$', '$', '$', '$', '$', '.'], ['$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '$', '.', '$', '$', '$', '.', '.', '.', '.', '.', '.', '$', '$', '$', '$', '$', '.'], ['$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '.'], ['$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.'], ['$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.'], ['$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.'], ['$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.'], ['$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '.'], ['$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '.', '.', '.', '.', '.', '.', '$'], ['$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '.', '$', '$', '.', '.'], ['$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '.', '$', '$', '$', '.'], ['$', '$', '.', '.', '.', '.', '.', '.', '.', '.', '.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '.', '$', '$', '$', '.'], ['.', '.', '.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '$', '.', '.', '.', '.', '.'], ['.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '.', '.', '.', '.', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.'], ['.', '$', '$', '$', '$', '$', '$', '$', '$', '.', '.', '.', '.', '.', '.', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.'], ['.', '$', '$', '$', '$', '$', '$', '$', '$', '.', '.', '.', '.', '.', '.', '.', '.', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '$', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '$', '.'], ['.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '.', '.', '.', '.', '.', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '.', '$', '.', '.', '.', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '.'], ['.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '$', '$', '$', '$', '.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '$', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.'], ['.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '$', '$', '$', '$', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '$', '.', 'B']]
path_len = 0x7fffffff#如果题目未给出终点坐标,则一定会指定路径的长度,在此处修改路径长度,否则请保留path_len的极大值
#进行BFS寻找路径
def bfs(start, end, barrier):
directions = [(0, 1), (1, 0), (0, -1), (-1, 0)] # 定义四个方向的移动
for i in range(len(maze)):#获取起点和终点在列表中的索引
for j in range(len(maze[i])):
if(maze[i][j] == start):
start = (i, j)
if(maze[i][j] == end):
end = (i, j)
#以下均是bfs算法套路
queue = deque()
queue.append((start, [start])) # (当前位置, 路径)
visited = set()
visited.add(start)
while queue:
position, path = queue.popleft()
if position == end:
return path
elif len(path)==path_len:
return path
for d in directions:
next_position = (position[0] + d[0], position[1] + d[1])
if 0 <= next_position[0] < len(maze) and 0 <= next_position[1] < len(maze[0]) and \
maze[next_position[0]][next_position[1]] != barrier and next_position not in visited:
queue.append((next_position, path + [next_position]))
visited.add(next_position)
return None
#执行BFS搜索并打印结果
if __name__ == '__main__':
#maze[起点x坐标][起点y坐标] = 'A' #如果题目给了起点终点的坐标,在这里直接给起点和终点添加特征
#maze[终点x坐标][终点y坐标] = 'B'
path = bfs('A', 'B', 1) #bfs函数传入参数代表起点、终点、障碍的特征(若题目给出的数据无特征, 手动添加特征即可, 通常障碍是1也有可能是0或其它字符如'#')
print("移动路径坐标:", path)
print("移动路径方位:{", end='')
for i in range(1 ,len(path)):
x1, y1, x2, y2 = path[i - 1][0], path[i - 1][1], path[i][0], path[i][1]
if(x1 > x2):#上
print("Y", end='')
elif(x1 < x2):#下
print("X", end='')
elif(y1 > y2):#左
print("C", end='')
elif(y1 < y2):#右
print("Z", end='')
print('}')
DFS算法:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAX_SIZE 100 // 迷宫最大尺寸
#define STACK_SIZE 10000 // 栈容量
// 坐标结构体
typedef struct {
int x;
int y;
} Point;
// 栈结构体
typedef struct {
Point data[STACK_SIZE];
int top;
} Stack;
// 方向枚举(Y-上,X-下,C-左,Z-右)
int dirs[4][2] = {{-1,0}, {1,0}, {0,-1}, {0,1}};
Stack* create_stack() {
Stack* s = (Stack*)malloc(sizeof(Stack));
s->top = -1;
return s;
}
void push(Stack* s, Point p) {
if (s->top >= STACK_SIZE-1) {
fprintf(stderr, "Error: Stack overflow\n");
exit(EXIT_FAILURE);
}
s->data[++s->top] = p;
}
Point pop(Stack* s) {
if (s->top < 0) {
fprintf(stderr, "Error: Stack underflow\n");
exit(EXIT_FAILURE);
}
return s->data[s->top--];
}
bool is_empty(Stack* s) {
return s->top == -1;
}
// 读取迷宫文件并初始化
static void read_maze(char maze[MAX_SIZE][MAX_SIZE], int* rows, int* cols, Point* start) {
FILE* fp = fopen("map.txt", "r");
if (!fp) {
fprintf(stderr, "Error: Failed to open map.txt\n");
exit(EXIT_FAILURE);
}
*rows = 0;
while (fgets(maze[*rows], MAX_SIZE, fp)) {
for (int i = 0; maze[*rows][i]; i++) {
if (maze[*rows][i] == 'A') {
start->x = *rows;
start->y = i;
}
}
(*rows)++;
}
*cols = strlen(maze[0]) - 1; // 去除换行符
fclose(fp);
}
// DFS寻路算法
void dfs_pathfinding(char maze[MAX_SIZE][MAX_SIZE], int rows, int cols, Point start) {
bool visited[MAX_SIZE][MAX_SIZE] = {false};
Stack* path = create_stack();
Stack* backtrack = create_stack();
push(path, start);
visited[start.x][start.y] = true;
while (!is_empty(path)) {
Point current = path->data[path->top];
// 到达终点
if (maze[current.x][current.y] == 'B') {
printf("Path found:\n");
char dirs_seq[STACK_SIZE] = {0}; // 存储方向序列
int dir_index = 0;
for (int i = 0; i <= path->top; i++) {
printf("(%d, %d) ", path->data[i].x, path->data[i].y);
// 生成方向序列(从第二个点开始)
if (i > 0) {
int dx = path->data[i].x - path->data[i-1].x;
int dy = path->data[i].y - path->data[i-1].y;
if(dx == -1) dirs_seq[dir_index++] = 'Y'; // 上
else if(dx == 1) dirs_seq[dir_index++] = 'X'; // 下
else if(dy == -1) dirs_seq[dir_index++] = 'C'; // 左
else if(dy == 1) dirs_seq[dir_index++] = 'Z'; // 右
}
if (maze[path->data[i].x][path->data[i].y] != 'B') {
maze[path->data[i].x][path->data[i].y] = '*';
}
}
printf("\nDirection sequence: %s\n", dirs_seq); // 新增方向序列输出
return;
}
bool found = false;
// 按照YXCZ顺序探索方向
for (int i = 0; i < 4; i++) {
int nx = current.x + dirs[i][0];
int ny = current.y + dirs[i][1];
if (nx >= 0 && nx < rows && ny >= 0 && ny < cols &&
!visited[nx][ny] && maze[nx][ny] != '$') {
Point next = {nx, ny};
push(path, next);
visited[nx][ny] = true;
found = true;
break;
}
}
if (!found) {
pop(path); // 回溯
}
}
printf("No path found!\n");
}
int main() {
char maze[MAX_SIZE][MAX_SIZE];
int rows, cols;
Point start;
read_maze(maze, &rows, &cols, &start);
dfs_pathfinding(maze, rows, cols, start);
// 打印带路径的迷宫
for (int i = 0; i < rows; i++) {
printf("%s", maze[i]);
}
return 0;
}
学习疑惑
DFS算法的脚本还要优化逻辑,还存在逻辑纰漏