问题描述
给定一个迷宫(二维数组),其中 0 表示通路,1 表示墙壁,S 表示起点,E 表示终点。需要找出一条从起点到终点的路径。
1、深度优先搜索(DFS)
深度优先搜索是一种用于遍历或搜索树或图的算法。它沿着树的深度遍历节点,尽可能深的搜索分支节点。
#include <stdio.h> #include <stdbool.h> #define ROW 4 #define COL 4 int maze[ROW][COL] = { { 'S', 0, 1, 0 }, { 0, 0, 1, 0 }, { 1, 0, 0, 'E' }, { 1, 1, 0, 1 } }; int dir[4][2] = { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } }; bool isValid(int x, int y) { return (x >= 0 && x < ROW && y >= 0 && y < COL && (maze[x][y] == 0 || maze[x][y] == 'E')); } bool dfs(int x, int y) { if (maze[x][y] == 'E') { return true; } maze[x][y] = -1; for (int i = 0; i < 4; i++) { int newX = x + dir[i][0]; int newY = y + dir[i][1]; if (isValid(newX, newY) && dfs(newX, newY)) { return true; } } maze[x][y] = 0; return false; } int main() { int startX, startY; for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { if (maze[i][j] == 'S') { startX = i; startY = j; break; } } } if (dfs(startX, startY)) { printf("找到一条从起点到终点的路径。\n"); } else { printf("没有找到从起点到终点的路径。\n"); } return 0; }
2、广度优先搜索(BFS)
广度优先搜索是一种用于遍历或搜索树或图的算法。它从树的根节点开始,沿着树的宽度遍历节点。
#include <stdio.h> #include <stdbool.h> #include <stdlib.h> #define ROW 4 #define COL 4 typedef struct { int x, y; } Point; typedef struct { Point *data; int front, rear, size, capacity; } Queue; Queue* createQueue(int capacity) { Queue *queue = (Queue *)malloc(sizeof(Queue)); queue->capacity = capacity; queue->front = queue->size = 0; queue->rear = capacity - 1; queue->data = (Point *)malloc(queue->capacity * sizeof(Point)); return queue; } bool isFull(Queue *queue) { return (queue->size == queue->capacity); } bool isEmpty(Queue *queue) { return (queue->size == 0); } void enqueue(Queue *queue, Point item) { if (isFull(queue)) return; queue->rear = (queue->rear + 1) % queue->capacity; queue->data[queue->rear] = item; queue->size = queue->size + 1; } Point dequeue(Queue *queue) { if (isEmpty(queue)) { Point p = {-1, -1}; return p; } Point item = queue->data[queue->front]; queue->front = (queue->front + 1) % queue->capacity; queue->size = queue->size - 1; return item; } int maze[ROW][COL] = { { 'S', 0, 1, 0 }, { 0, 0, 1, 0 }, { 1, 0, 0, 'E' }, { 1, 1, 0, 1 } }; int dir[4][2] = { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } }; bool isValid(int x, int y) { return (x >= 0 && x < ROW && y >= 0 && y < COL && (maze[x][y] == 0 || maze[x][y] == 'E')); } bool bfs(int startX, int startY) { Queue *queue = createQueue(ROW * COL); Point start = {startX, startY}; enqueue(queue, start); maze[startX][startY] = -1; while (!isEmpty(queue)) { Point curr = dequeue(queue); if (maze[curr.x][curr.y] == 'E') { return true; } for (int i = 0; i < 4; i++) { int newX = curr.x + dir[i][0]; int newY = curr.y + dir[i][1]; if (isValid(newX, newY)) { Point next = {newX, newY}; enqueue(queue, next); maze[newX][newY] = -1; } } } return false; } int main() { int startX, startY; for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { if (maze[i][j] == 'S') { startX = i; startY = j; break; } } } if (bfs(startX, startY)) { printf("找到一条从起点到终点的路径。\n"); } else { printf("没有找到从起点到终点的路径。\n"); } return 0; }
3、递归回溯法
递归回溯法是一种探索所有可能路径的算法,适用于求解迷宫等问题。
#include <stdio.h> #include <stdbool.h> #define ROW 4 #define COL 4 int maze[ROW][COL] = { { 'S', 0, 1, 0 }, { 0, 0, 1, 0 }, { 1, 0, 0, 'E' }, { 1, 1, 0, 1 } }; int dir[4][2] = { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } }; bool isValid(int x, int y) { return (x >= 0 && x < ROW && y >= 0 && y < COL && (maze[x][y] == 0 || maze[x][y] == 'E')); } bool backtrack(int x, int y) { if (maze[x][y] == 'E') { return true; } maze[x][y] = -1; for (int i = 0; i < 4; i++) { int newX = x + dir[i][0]; int newY = y + dir[i][1]; if (isValid(newX, newY) && backtrack(newX, newY)) { return true; } } maze[x][y] = 0; return false; } int main() { int startX, startY; for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { if (maze[i][j] == 'S') { startX = i; startY = j; break; } } } if (backtrack(startX, startY)) { printf("找到一条从起点到终点的路径。\n"); } else { printf("没有找到从起点到终点的路径。\n"); } return 0; }