走迷宫问题(深度优先遍历 + 广度优先遍历)

迷宫是许多小方格构成的矩形,在每个小方格中有的是墙(用1表示),有的是路(用0表示)。走迷宫就是从一个小方格沿上、下、左、右四个方向到邻近的方格,当然不能穿墙。设迷宫的入口是在左上角(1,1),出口是在右下角(8,8)。根据给定的迷宫,找出一条从入口到出口的路径。

解法一(深度优先遍历,打印所有可行的路径):

#include <iostream>
using namespace std;

int maze[8][8] = {{0,0,0,0,0,0,0,0},{0,1,1,1,1,0,1,0},{0,0,0,0,1,0,1,0},{0,1,0,0,0,0,1,0},
{0,1,0,1,1,0,1,0},{0,1,0,0,0,0,1,1},{0,1,0,0,1,0,0,0},{0,1,1,1,1,1,1,0}};
//下、右、上、左
const int fx[4] = {1,0,-1,0};
const int fy[4] = {0,1,0,-1};
//maze[i][j] = 3;//标识已走
//maze[i][j] = 2;//标识死胡同
//maze[i][j] = 1;//标识墙
//maze[i][j] = 0;//标识可以走

//打印路径
void printPath()
{
    for (int i=0;i<8;++i)
    {
        for (int j=0;j<8;++j)
        {
            if (3 == maze[i][j])
            {
                cout<<"V";
            }
            else
            {
                cout<<"*";
            }
        }
        cout<<endl;
    }
    cout<<endl;
}

void search(int i, int j)
{
    int newx;
    int newy;
    for (int k=0;k<4;++k)
    {
        newx = i+fx[k];
        newy = j+fy[k];
        //如果不是墙,且没有走过
        if (newx>=0 && newx <8 && newy>=0 && newy<8 && 0 == maze[newx][newy])
        {
            maze[newx][newy] = 3;
            if (7 == newx && 7 == newy)
            {
                printPath();
                maze[newx][newy] = 0;
            }
            else
            {
                search(newx,newy);
            }       
        }
    }
    **//回溯的时候将此点标记未访问,这样下一条路径也可以访问**
    maze[i][j] = 0;
}

int main()
{
    maze[0][0] = 3;
    search(0,0);
    return 0;
}

运行结果:
这里写图片描述

解法二(广度优先遍历):

#include <iostream>
#include <vector>
using namespace std;

int maze[8][8] = {{0,0,0,0,0,0,0,0},{0,1,1,1,1,0,1,0},{0,0,0,0,1,0,1,0},{0,1,0,0,0,0,1,0},
{0,1,0,1,1,0,1,0},{0,1,0,0,0,0,1,1},{0,1,0,0,1,0,0,0},{0,1,1,1,1,1,1,0}};
//下、右、上、左
const int fx[4] = {1,0,-1,0};
const int fy[4] = {0,1,0,-1};

struct sq{
    int x;
    int y;
    int pre;
};

//标记路径,正确的点值赋为3
void markPath(const vector<sq> &q, int index)
{
    sq tmp = q[index];
    maze[tmp.x][tmp.y] = 3;
    if ( 0 == tmp.x && 0 == tmp.y )
    {
        return ;
    }
    else
    {
        markPath(q, tmp.pre);
    }
}

//打印路径
void printPath()
{
    for (int i=0;i<8;++i)
    {
        for (int j=0;j<8;++j)
        {
            if (3 == maze[i][j])
            {
                cout<<"v";
            }
            else
            {
                cout<<"*";
            }
        }
        cout<<endl;
    }
    cout<<endl;
}

//检查点(i,j)是否满足
bool check(int i, int j)
{
    if (i >= 0 && i<8 && j>=0 && j<8 && 0 == maze[i][j])
    {
        return true;
    }
    return false;
}

void search()
{

    //模仿队列,之所以不用真正的队列,因为后面需要通过下标对队列进行随机访问
    vector<sq> q;
    int qh = 0;
    sq fnode;
    fnode.pre = -1;
    fnode.x = 0;
    fnode.y = 0;
    //标记已访问
    maze[fnode.x][fnode.y] = -1;
    q.push_back(fnode);
    int qe = 1;
    sq tmp;
    while (qh != qe)
    {
        //出队
        tmp = q[qh];
        ++qh;
        int newx, newy;
        for (int k=0;k<4;++k)
        {
            newx = tmp.x + fx[k];
            newy = tmp.y + fy[k];
            if (check(newx, newy))
            {
                sq n_node;
                n_node.pre = qh - 1;
                n_node.x = newx;
                n_node.y = newy;
                //入队
                q.push_back(n_node);
                ++qe;
                //找到出口,打印
                if (7 == newx && 7 == newy)
                {
                    markPath(q, qe-1);
                    printPath();
                    return;
                }
            }
        }
        //maze[tmp.x][tmp.y] = -1;
    }
}

int main()
{
    maze[0][0] = 3;
    search();
    return 0;
}

运行结果:
这里写图片描述

  • 15
    点赞
  • 73
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
广度优先遍历是一种基于队列的搜索算法,适用于求解最短路径或最小步数等问题。下面是使用广度优先遍历求解迷宫问题的C语言代码: ``` #include <stdio.h> #include <stdlib.h> #define ROW 5 #define COL 5 typedef struct { int row; // 行坐标 int col; // 列坐标 } Point; int maze[ROW][COL] = { {0, 1, 0, 0, 0}, {0, 1, 0, 1, 0}, {0, 0, 0, 0, 0}, {0, 1, 1, 1, 0}, {0, 0, 0, 1, 0} }; // 迷宫,0代表可,1代表障碍 int visited[ROW][COL] = {0}; // 记录是否已经访问过 int BFS(Point start, Point end); int main() { Point start = {0, 0}; // 起点 Point end = {ROW-1, COL-1}; // 终点 int steps = BFS(start, end); printf("从起点到终点的最短步数为:%d\n", steps); return 0; } int BFS(Point start, Point end) { Point queue[ROW*COL]; // 队列(使用数组模拟) int front = 0, rear = 0; // 队头和队尾 queue[rear++] = start; // 入队 visited[start.row][start.col] = 1; // 标记为已访问 int steps = 0; // 步数 while (front < rear) { // 队列非空 int size = rear - front; // 当前层的节点数 while (size-- > 0) { // 处理当前层的所有节点 Point cur = queue[front++]; // 出队 if (cur.row == end.row && cur.col == end.col) { // 到达终点 return steps; } // 向上 if (cur.row > 0 && maze[cur.row-1][cur.col] == 0 && visited[cur.row-1][cur.col] == 0) { Point next = {cur.row-1, cur.col}; queue[rear++] = next; // 入队 visited[next.row][next.col] = 1; // 标记为已访问 } // 向下 if (cur.row < ROW-1 && maze[cur.row+1][cur.col] == 0 && visited[cur.row+1][cur.col] == 0) { Point next = {cur.row+1, cur.col}; queue[rear++] = next; // 入队 visited[next.row][next.col] = 1; // 标记为已访问 } // 向左 if (cur.col > 0 && maze[cur.row][cur.col-1] == 0 && visited[cur.row][cur.col-1] == 0) { Point next = {cur.row, cur.col-1}; queue[rear++] = next; // 入队 visited[next.row][next.col] = 1; // 标记为已访问 } // 向右 if (cur.col < COL-1 && maze[cur.row][cur.col+1] == 0 && visited[cur.row][cur.col+1] == 0) { Point next = {cur.row, cur.col+1}; queue[rear++] = next; // 入队 visited[next.row][next.col] = 1; // 标记为已访问 } } steps++; // 层数加1 } return -1; // 无解的情况 } ``` 以上代码中,定义了一个`Point`结构体表示坐标,使用了两个二维数组`maze`和`visited`分别表示迷宫和是否已访问。在`BFS()`函数中,使用队列依次处理每一层的节点,直到到达终点或队列为空。在处理每个节点时,检查其上下左右四个方向是否可,若可则将其入队并标记为已访问。主函数中调用`BFS()`函数并输出最短步数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值