迷宫问题

如果要解决这个问题 ,,,我们就要使用到栈这个数据结构了 ,,,,栈结构的特点就是 后进先出 所以我们可以通过栈的这种特点来进行试着走通 道路,如果路通 , ,,,将这个位置压栈 ,,,,再来判断下一个位置 ,,,如果走不同的话 ,,我们可以通过取栈顶元素 为上次走的路径 ,然后出栈 ,,,, , ,知道在别的方位找到出路

话说的再多还是要实现代码才算回事!!!!!
下面就让我来手动实现一下这个迷宫问题的求解

这就是迷宫的地图的表示方法 , , , ,其中 1表示此路不通 ,, , , 0 表死该路可通
代码

#pragma once  
#include<iostream>  
#include<assert.h>  
#include<stack>  
#include<string>  
using namespace std;  
//声明一个数组 表示的所要压栈的元素的坐标  
struct Pos  
{  
    size_t row;//压栈位置的行  
    size_t col;//压栈位置的列  
};  

//初始化建立一个迷宫  其中1表示不通 ,, 0表示此路通  
void SetMaze(int **&maze,size_t &N)//传的参数maze表示的是表示迷宫的二位数组 ,N表示的是迷宫的大小  
{  
    FILE * fp = fopen("maze.txt", "r");//从文件中读取数据用来创建迷宫  
    assert(fp);  
    char str[15];  
    fgets(str, 256, fp);  
    N = atoi(str);//读取第一个数作为迷宫的大小 ,,赋值给N  
    maze = new int*[N];  
    for (size_t i = 0; i < N; i++)//动态开辟二维数组  
    {  
        maze[i] = new int[N];  
    }  
    for (size_t i = 0; i < N; i++)  
    {  
        for (size_t j = 0; j < N;)  
        {  
            int value = fgetc(fp);  
            if (value - '0' == 1 || value - '0' == 0)  
            {  
                maze[i][j] = value-'0';  
                ++j;  
            }  
            if (value == EOF)  
            {  
                assert(false);//若给的迷宫出现问题   例如数据缺失直接报错  
            }  
        }  
    }  
    fclose(fp);//用完后将文件关掉  
}  
//判断位置是不是可通  
bool checkPos(int **maze,Pos &next,size_t N)  
{  
    if (next.col < N && next.row < N  
        && next.col >= 0 && next.row >= 0  
        &&maze[next.row][next.col]==0)  
    {  
        return  true;  
    }  
    return false;  
}  
//栈求迷宫是否可通  

bool IsHasPath(int ** maze, size_t  N, stack<Pos> &path, Pos entry)  
{  
    path.push(entry);  
    maze[entry.row][entry.col] = 2;//将走过的路都赋值给2  
    while (!path.empty())  
    {  
        Pos cur = path.top();  
        Pos next;  
        if ((cur.row == N - 1 || cur.col == 0 || cur.row == 0 || cur.col == N - 1)  
            && cur.col != entry.col  &&  cur.row != entry.row)//判断是不是出口  
            return true;  
        //判断四面是否可tong  
        //上  
        next = cur;  
        next.row -= 1;  
        if (checkPos(maze, next, N))//判断此方向位置是不是可通  
        {  
            path.push(next);  
            maze[next.row][next.col] = 2;  
            continue;  
        }  
        //右  
        next = cur;  
        next.col += 1;  
        if (checkPos(maze, next, N))//判断此方向位置是不是可通  
        {  
            path.push(next);  
            maze[next.row][next.col] = 2;  
            continue;  
        }  
        //下  
        next = cur;  
        next.row += 1;  
        if (checkPos(maze, next, N))//判断此方向位置是不是可通  
        {  
            path.push(next);  
            maze[next.row][next.col] = 2;  
            continue;  
        }  
        //左  
        next = cur;  
        next.col -= 1;  
        if (checkPos(maze, next, N))//判断此方向位置是不是可通  
        {  
            path.push(next);  
            maze[next.row][next.col] = 2;  
            continue;  
        }  
        path.pop();//如果四面都不通的话  则将该坐标pop出去 ,,,以上一个位置再继续判断别的方向  
    }  
    return false;  
}  
//递归算法  
bool IsHasPath(int ** maze, size_t  N, stack<Pos> &path, Pos entry)  
{  
    path.push(entry);//将每次进行递归的入口压栈  
    maze[entry.row][entry.col] = 2;  
    Pos cur = entry;  
    Pos next;  
    if (cur.row == N - 1)//判断是否为出口   
        return true;  
        //判断四面是否可tong  
        //上  
    next = cur;  
    next.row -= 1;  
    if (checkPos(maze, next, N))  
    {  
        if(IsHasPath(maze, N, path, next))//如跳出递归 果找出出口 则层层回去  
            return true;  
    }  
        //右  
    next = cur;  
    next.col += 1;  
    if (checkPos(maze, next, N))  
    {  
        if (IsHasPath(maze, N, path, next))//如跳出递归 果找出出口 则层层回去  
            return true;  
    }  
        //下  
    next = cur;  
    next.row += 1;  
    if (checkPos(maze, next, N))  
    {  
        if (IsHasPath(maze, N, path, next))//如跳出递归 果找出出口 则层层回去  
            return true;  
    }  
        //左  
    next = cur;  
    if (checkPos(maze, next, N))  
    {  
        if (IsHasPath(maze, N, path, next))//如跳出递归 果找出出口 则层层回去  
            return  true;  
    }  
        path.pop();  
    return false;  
}  
//递归求最短路径  
int MinPath(int ** maze, size_t  N, stack<Pos> &path, Pos entry,stack<Pos> &min)  
{  
    path.push(entry);  
    maze[entry.row][entry.col] = 2;  
    Pos cur = entry;  
    Pos next;  
    if (cur.row == N - 1)  
    {  
        if (path.size() < min.size() || min.size() == 0)//如果这条路比最短路径的长度小 则赋值给最短路径存放的栈  
            min = path;  
    }  
    //判断四面是否可tong  
    //上  
    next = cur;  
    next.row -= 1;  
    if (checkPos(maze, next, N))  
    {  
        MinPath(maze, N, path, next,min);  
    }  
    //右  
    next = cur;  
    next.col += 1;  
    if (checkPos(maze, next, N))  
    {  
        MinPath(maze, N, path, next, min);  
    }  
    //下  
    next = cur;  
    next.row += 1;  
    if (checkPos(maze, next, N))  
    {  
        MinPath(maze, N, path, next, min);  
    }  
    //左  
    next = cur;  
    next.col -= 1;  
    if (checkPos(maze, next, N))  
    {  
        MinPath(maze, N, path, next, min);  
    }  
    maze[path.top().row][path.top().col] = 0;//将pop出来的位置的值再改回来 ,,,因为也有可能别的通路也走这条路   
    path.pop();  
    if (min.size())  
        return min.size();  
    else  
        return -1;  
}  
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值