用栈求解迷宫问题的所有路径及最短路径程序

目的:掌握栈在求解迷宫问题中的应用。

内容:编写一个程序,输出迷宫的所有路径,并求第一条最短路径长度及最短路径。

代码如下:

#include <iostream>
#include <cstdio>
#include <stack>
#include <cstdlib>
using namespace std;
#define inf 0x3f3f3f
const int MaxSize=1000;
int M=4,N=4;
int mg[6][6]={{1,1,1,1,1,1},{1,0,0,0,1,1},
                  {1,0,1,0,0,1},{1,0,0,0,1,1},
                  {1,1,0,0,0,1},{1,1,1,1,1,1}};
int vis[6][6];
typedef struct
{
    int i;//当前方块的行号
    int j;//当前方的列号
    int di;
}Box;
typedef struct
{
    Box data[MaxSize];
    int top;//栈顶指针
}SqStack;//顺序栈类型
void InitStack(SqStack *&s)//初始化栈
{
    s=(SqStack *)malloc(sizeof(SqStack));
    s->top=-1;
}
bool Push(SqStack *&s,Box e)//进栈
{
    if(s->top==MaxSize-1)
        return false;
    s->top++;
    s->data[s->top]=e;
}
bool StackEmpty(SqStack *s)//判断栈是否为空
{
    return (s->top==-1);
}
bool Pop(SqStack *&s,Box &e)//出栈
{
    if(s->top==-1)
        return false;
    e=s->data[s->top];
    s->top--;
    return true;
}
bool GetTop(SqStack *s,Box &e)//取出栈顶元素
{
    if(s->top==-1)
        return false;
    e=s->data[s->top];
    return true;
}
bool mgpath(int xi,int yi,int xe,int ye)
{
    int minn=inf,minum;
    int cont=1;
    int f=0;
    int i,j,di,i1,j1,k;
    bool _find=false;
    SqStack *st;//定义栈st
    InitStack(st);//初始化栈st
    Box e1,e;
    e1.i=xi;
    e1.j=yi;
    e1.di=-1;
    Push(st,e1);//方块e进栈
    vis[xi][yi]=-1;//将入口的迷宫值置为-1,避免重复走到该方块
    while(!StackEmpty(st))//栈不为空时循环
    {
        GetTop(st,e);
        //cout<<e.i<<" "<<e.j<<" "<<e.di<<endl;
        i=e.i;
        j=e.j;
        di=e.di;
        if(i==xe&&j==ye)//找到了出口,输出该路径
        {
            f=1;
            if(st->top<minn)
            {
                minn=st->top;
                minum=cont;
            }
            printf("迷宫路径%d为:\n",cont++);
            for(k=0;k<=st->top;k++)
                printf("(%d,%d)\t",st->data[k].i,st->data[k].j);
            printf("\n");
        }
        _find=false;
        while(di<4&&!_find)
        {
            di++;
            switch(di)
            {
                case 0:i1=i-1;j1=j;break;
                case 1:i1=i;j1=j+1;break;
                case 2:i1=i+1;j1=j;break;
                case 3:i1=i;j1=j-1;break;
            }
            if(vis[i1][j1]==0&&mg[i1][j1]==0) _find=true;
        }
        if(_find)
        {
            st->data[st->top].di=di;
            e.i=i1;
            e.j=j1;
            e.di=-1;
            Push(st,e);
            vis[i1][j1]=-1;
        }
        else
        {
            Pop(st,e);
            vis[e.i][e.j]=0;
        }
    }
    if(f==1)
    {
        printf("最短路径为路径%d\n",minum);
        printf("最短路径长度为%d\n",minn);
        return true;
    }
    return false;
}
int main()
{
    if(!mgpath(1,1,4,4))
        printf("该迷宫问题没有解!\n");
    return 0;
}

运行结果:

  • 39
    点赞
  • 167
    收藏
    觉得还不错? 一键收藏
  • 18
    评论
以下是使用栈求解迷宫问题的所有路径最短路径的C语言程序: ```c #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #define ROW 5 // 迷宫行数 #define COL 5 // 迷宫列数 struct Point { int x; // 横坐标 int y; // 纵坐标 }; struct Stack { struct Point data[ROW * COL]; // 数据 int top; // 顶指针 }; // 初始化 void initStack(struct Stack *s) { s->top = -1; } // 判断是否为空 bool isEmpty(struct Stack *s) { return s->top == -1; } // 判断是否已满 bool isFull(struct Stack *s) { return s->top == ROW * COL - 1; } // 入 void push(struct Stack *s, struct Point p) { if (isFull(s)) { printf("Stack is full!\n"); return; } s->top++; s->data[s->top] = p; } // 出 struct Point pop(struct Stack *s) { if (isEmpty(s)) { printf("Stack is empty!\n"); exit(-1); } struct Point p = s->data[s->top]; s->top--; return p; } // 判断当前位置是否合法 bool isValid(int maze[][COL], int x, int y) { if (x < 0 || x >= ROW || y < 0 || y >= COL || maze[x][y] == 1) { return false; } return true; } // 求解所有路径 void findAllPaths(int maze[][COL], int startX, int startY, int endX, int endY) { struct Stack s; initStack(&s); struct Point start = {startX, startY}; push(&s, start); while (!isEmpty(&s)) { struct Point cur = pop(&s); if (cur.x == endX && cur.y == endY) { // 到达终点,输出路径 for (int i = 0; i <= s.top; i++) { printf("(%d, %d) ", s.data[i].x, s.data[i].y); } printf("(%d, %d)\n", endX, endY); } else { // 继续搜索 maze[cur.x][cur.y] = 1; // 标记已经走过 if (isValid(maze, cur.x - 1, cur.y)) { // 上 struct Point next = {cur.x - 1, cur.y}; push(&s, next); } if (isValid(maze, cur.x, cur.y + 1)) { // 右 struct Point next = {cur.x, cur.y + 1}; push(&s, next); } if (isValid(maze, cur.x + 1, cur.y)) { // 下 struct Point next = {cur.x + 1, cur.y}; push(&s, next); } if (isValid(maze, cur.x, cur.y - 1)) { // 左 struct Point next = {cur.x, cur.y - 1}; push(&s, next); } maze[cur.x][cur.y] = 0; // 恢复标记 } } } // 求解最短路径 void findShortestPath(int maze[][COL], int startX, int startY, int endX, int endY) { struct Stack s1, s2; initStack(&s1); initStack(&s2); struct Point start = {startX, startY}; push(&s1, start); while (!isEmpty(&s1)) { struct Point cur = pop(&s1); if (cur.x == endX && cur.y == endY) { // 到达终点,输出路径 push(&s2, cur); for (int i = 0; !isEmpty(&s1); i++) { push(&s2, cur); cur = pop(&s1); } push(&s2, cur); while (!isEmpty(&s2)) { struct Point p = pop(&s2); printf("(%d, %d) ", p.x, p.y); } printf("\n"); return; } else { // 继续搜索 maze[cur.x][cur.y] = 1; // 标记已经走过 if (isValid(maze, cur.x - 1, cur.y)) { // 上 struct Point next = {cur.x - 1, cur.y}; push(&s1, next); } if (isValid(maze, cur.x, cur.y + 1)) { // 右 struct Point next = {cur.x, cur.y + 1}; push(&s1, next); } if (isValid(maze, cur.x + 1, cur.y)) { // 下 struct Point next = {cur.x + 1, cur.y}; push(&s1, next); } if (isValid(maze, cur.x, cur.y - 1)) { // 左 struct Point next = {cur.x, cur.y - 1}; push(&s1, next); } maze[cur.x][cur.y] = 0; // 恢复标记 } } } int main() { int maze[ROW][COL] = { // 迷宫地图,1表示障碍,0表示可以通过 {0, 1, 0, 0, 0}, {0, 1, 0, 1, 0}, {0, 0, 0, 0, 0}, {1, 1, 1, 0, 0}, {0, 0, 0, 0, 1} }; printf("All paths:\n"); findAllPaths(maze, 0, 0, 4, 4); printf("Shortest path:\n"); findShortestPath(maze, 0, 0, 4, 4); return 0; } ``` 上述程序中,我们使用了一个结构体`Point`来表示迷宫中的坐标,使用一个结构体`Stack`来表示。`findAllPaths`函数用来求解所有路径,`findShortestPath`函数用来求解最短路径。在搜索过程中,我们使用一个二维数组`maze`来标记哪些位置已经走过,避免重复搜索。
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值