迷宫问题(文件保存)

这是一个使用C++实现的BFS(广度优先搜索)算法,用于在5x5的二维数组迷宫中寻找从右下角到左上角的最短路径。程序定义了一个结构体来存储坐标信息,并通过一个二维数组记录最短路径的父节点。通过一个队列进行广度优先遍历,同时使用一个二维数组标记已访问过的节点。最后,通过跟踪父节点数组打印出最短路径。
摘要由CSDN通过智能技术生成

代码如下

#include<stdio.h>
#include<string.h>
#include<queue>
#include<iostream>
#include<cstring>
#include <fstream>
using namespace std;

// 定义的一个结构体w,x和y表示一个点的坐标
typedef struct point_s
{
    int x;
    int y;
} point_t;

/* 定义一个结构体二维数组
father[x][y].x存的是最短路径的坐标为(x,y)点的下一个坐标的横坐标x
father[x][y].y存的是最短路径的坐标为(x,y)点的下一个坐标的纵坐标y */
point_t father[6][6];

//一个5X5的二维数组表示地图
int maze[5][5];
/* 因为是找最短的路径,所以之前走过的路不能再走,当visited[X][Y]=0时,
表示之前没走过(x,y)这个点,同理,为1时,表示走过 */
int visited[6][6];

/*每一个点能走上下左右4个方向
move[1][0]表示向下走时x坐标该加的值(x+1)
move[1][1]表示向下走时y坐标该加的值(y不变)
move[2][0],move[2][1]表示向右走时,x和y对应的坐标变化
*/
int move[4][2] = {1, 0, 0, 1, 0, -1, -1, 0};

int check(int x, int y) //定义一个检查函数,来检查能不能走到(x,y)这个点,能返回1,不能返回0;
{
    /* 能走到这个点满足的条件有
    1:该点没被走过,对应的代码是     visited[x][y]==0
    2:该点不是墙,是路,对应的代码是 maze[x][y]==0
    3:该点 属于5X5的这个迷宫内部,对应的代码是 x<=4&&y<=4&&x>=0&&y>=0
    */
    if (visited[x][y] == 0 && maze[x][y] == 0 && x <= 4 
        && y <= 4 && x >= 0 && y >= 0) {
        //当以下3点满足时,返回1,表示能走到这个点
        return 1;
    }

    //如果前面没有return,代表不能走到这个点,于是返回0
    return 0;
}

//主要的BFS搜索函数
void bfs()
{
    //定义2个w结构体,point1表示第一个点,point2表示由point1这个点走到的一个点
    point_t point1, point2;

    //从右下角往前面搜,搜到左上角就结束,所以第一个点为(4,4)
    point1.x = 4;
    point1.y = 4;

    //定义一个结构体队列q
    queue<point_t> q;

    //将第一个点(4,4)加入队列
    q.push(point1);

    // 当这个队列没空时,就一直循环
    while (!q.empty())
    {
        //取出队列的首端并赋值给point1结构体
        point1 = q.front();
        //删除队列的首端元素
        q.pop();
        //当point1为(0,0)时,说明找到了出口,函数结束
        if (point1.x == 0 && point1.y == 0)
            break;

        // 临时变量
        int i, tmp_x, tmp_y;

        //因为一个点可能能走4步,所以i从0到3,4次循环
        for (i = 0; i < 4; i++)
        {
            tmp_x = point1.x + move[i][0];
            //(tmp_x,tmp_y)表示由point1这个点可能 能够走到的所有点
            tmp_y = point1.y + move[i][1];

            //检查(tmp_x,tmp_y)这个点到底能不能走到,上面有check函数的解释
            if (check(tmp_x, tmp_y))
            {
                //把(tmp_x,tmp_y)这个点赋给point2
                point2.x = tmp_x;
                point2.y = tmp_y;

                //更新father结构体数组中的数据,该数组的意义上面有解释
                father[point2.x][point2.y].x = point1.x;
                father[point2.x][point2.y].y = point1.y;
                //把point2这个点赋为1,表示走过该点
                visited[point2.x][point2.y] = 1;
                //把point2这个点放进队列中
                q.push(point2);
            }
        }
    }

}

//打印答案的函数
void printf()
{
    //起点为(0,0)
    int x = 0, y = 0;

    //当坐标不为(4,4)时,也就是当没走到右下角时,一直循环
    while (!(x == 4 && y == 4))
    {
        //打印该点坐标,最开始打印(0,0)
        printf("(%d, %d)\n", x, y);

        //tmp_x,tmp_y表示最短路径时(x,y)这个点的下一个点的坐标
        int tmp_x, tmp_y;

        //赋值给tmp_x,tmp_y
        tmp_x = father[x][y].x;
        tmp_y = father[x][y].y;

        //现在的(x,y)就是这个循环中打印的那个(x,y)的走到的下一个点坐标
        x = tmp_x;
        y = tmp_y;
    }

    // 当(x,y)为(4,4)时退出循环,
    //当然也要打印最后一个点
    printf("(%d, %d)\n", x, y);
}

int main()
{
    int i, j;
    //输入迷宫maze
    for (i = 0; i < 5; i++)
    {
        for (j = 0; j < 5; j++)
            scanf("%d", &maze[i][j]);
    }
//    std::ofstream outFile;
//    //打开文件
//    outFile.open("C:\\Test.txt");
//    for(i = 0; i < 5; i++)
//    {for(j=0;j<5;j++)
//        //写入数据
//        outFile << maze[i][j];
//    }
//    //关闭文件
//    outFile.close();
ofstream out("out.txt");
    if (out.is_open())
    {    for(i = 0; i < 5; i++)
       {for(j=0;j<5;j++)
        //写入数据
        out << maze[i][j]<<;
}
        out.close();
    
}


    // 将visited数组全部赋值为0,表示最开始都没走过
    for (i = 0; i < 6; i++)
    {
        for (j = 0; j < 6; j++)
            visited[i][j] = 0;
    }

    //搜索
    bfs();
    //打印答案
    printf();
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值