C语言-迷宫问题解法,用栈实现

/*
定义一个二维数组 N*M ,如 5 × 5 数组下所示:
int maze[5][5] = {
0, 1, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 1, 0,
};

它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,
不能斜着走,要求编程序找出从左上角到右下角的路线。入口点为[0,0],既第一格是可以走的路。
数据范围:
2≤n,m≤10 , 输入的内容只包含
0≤val≤1

输入描述:
输入两个整数,分别表示二维数组的行数,列数。再输入相应的数组,
其中的1表示墙壁,0表示可以走的路。数据保证有唯一解,不考虑有多解的情况,
即迷宫只有一条通道。

输出描述:
左上角到右下角的最短路径,格式如样例所示。

示例1
输入
5 5
0 1 0 0 0
0 1 1 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0
输出
(0,0)
(1,0)
(2,0)
(2,1)
(2,2)
(2,3)
(2,4)
(3,4)
(4,4)*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MaxSize 100
#define false 0
#define true 1
//静态栈结构体,用数组实现
typedef struct StaticStack
{
    int Data[MaxSize];
    int pop;
}Sstack;
//栈的初始化,栈顶指针指向-1,栈中无任何元素
void initStack(Sstack *stack)
{
    memset(stack,0,sizeof(Sstack));
    stack->pop = -1;
}
//获取栈的栈顶指向,实则数组下标
int GetPoP(Sstack *stack)
{
    return stack->pop;
}
//获取栈顶元素的值
int GetData(Sstack *stack)
{
    if(stack->pop == -1)
        return -1;
    return stack->Data[stack->pop];
}
//出栈 
int Pop(Sstack *stack)
{
    if(stack->pop < 0)
        return 0;//Õ»¿Õ
    stack->pop--;
    return 1;
}
//入栈
int Push(Sstack *stack,int data)
{
    if(stack->pop == MaxSize-1)
        return 0;//Õ»Âú
    stack->pop++;
    stack->Data[stack->pop] = data;
    return 1;
}
//输出栈中所有元素
int printStack(Sstack stack)
{
    int i;
    if(stack.pop < 0)
        return 0;//Õ»¿Õ
    for(i = 0;i <= stack.pop;i++)
        printf("%d ",stack.Data[i]);
    return 1;
}
//递归函数,寻找路径
int search(int *array,int i,int j,int n,int m,Sstack *Rowst,Sstack *Colst)
{
    if(i>=n)return false;
    if(i<0)return false;
    if(j>=m)return false;
    if(j<0)return false;//(当前节点不在迷宫内,返回false)
    if(*(array+i*m+j) == 1)return false;//当前节点是墙,返回false
    int beforeRow,beforeCol;
    beforeRow = GetData(Rowst);
    beforeCol = GetData(Colst);//获取上个节点坐标
    if(*(array+i*m+j) == 0)//将当前节点入栈
    {
        Push(Rowst,i);
        Push(Colst,j);
        //printf("%d %d\n",i,j);
    }
    if((i == n-1)&&(j == m-1))return true;//达到终点返回true
    int L_status,R_status,U_status,D_status;
    //一个节点四个方向能否行进,false不能,true能
    if((beforeRow == -1)&&(beforeCol == -1))//上个节点为起点,只向右和下走
    {
        R_status = search(array,i,j+1,n,m,Rowst,Colst);
        if(R_status == true)
            return true;
        D_status = search(array,i+1,j,n,m,Rowst,Colst);
        if(D_status == true)
            return true;
        Pop(Rowst);//前进不了,将当前节点坐标出栈
        Pop(Colst);
    }

    if((beforeRow == i+1)&&(beforeCol == j))//上个节点为下方节点,不走下方
    {
        R_status = search(array,i,j+1,n,m,Rowst,Colst);
        if(R_status == true)
            return true;
        L_status = search(array,i,j-1,n,m,Rowst,Colst);
        if(L_status == true)
            return true;
        U_status = search(array,i-1,j,n,m,Rowst,Colst);
        if(U_status == true)
            return true;
        Pop(Rowst);
        Pop(Colst);
    }
    if((beforeRow == i-1)&&(beforeCol == j))
    {
        R_status = search(array,i,j+1,n,m,Rowst,Colst);
        if(R_status == true)
            return true;
        L_status = search(array,i,j-1,n,m,Rowst,Colst);
        if(L_status == true)
            return true;
        D_status = search(array,i+1,j,n,m,Rowst,Colst);
        if(D_status == true)
            return true;
        Pop(Rowst);
        Pop(Colst);
    }
    if((beforeRow == i)&&(beforeCol == j+1))
    {
        D_status = search(array,i+1,j,n,m,Rowst,Colst);
        if(D_status == true)
            return true;
        L_status = search(array,i,j-1,n,m,Rowst,Colst);
        if(L_status == true)
            return true;
        U_status = search(array,i-1,j,n,m,Rowst,Colst);
        if(U_status == true)
            return true;
        Pop(Rowst);
        Pop(Colst);
    }
    if((beforeRow == i)&&(beforeCol == j-1))
    {
        R_status = search(array,i,j+1,n,m,Rowst,Colst);
        if(R_status == true)
            return true;
        D_status = search(array,i+1,j,n,m,Rowst,Colst);
        if(D_status == true)
            return true;
        U_status = search(array,i-1,j,n,m,Rowst,Colst);
        if(U_status == true)
            return true;
        Pop(Rowst);
        Pop(Colst);
    }
    return false;

}
int main()
{
    Sstack Rowstack,Colstack;
    Sstack *Rowst = &Rowstack;
    Sstack *Colst = &Colstack;
    int n,m;
    int *array_map;
   /* int array_map[25] = {0,1,0,0,0,
                         0,1,0,1,0,
                         0,0,0,0,1,
                         0,1,1,1,0,
                         0,0,0,0,0};*/
    //测试使用
    int i,j;
    while(scanf("%d %d",&n,&m)!=EOF)
    {
//        m = 5;//测试使用
//        n = 5;
        array_map = (int *)malloc(m*n*sizeof(int));
        for(i = 0;i < m;i++)
        {
            for(j = 0;j < n; j++)
            {
                scanf("%d",array_map+i*m+j);
            }
        }
//        printf("\n");//测试使用
//        for(i = 0;i < m;i++)
//        {
//            for(j = 0;j < n; j++)
//            {
//                printf("%d ",*(array_map+i*m+j));
//            }
//            printf("\n");
//        }
        initStack(Rowst);
        initStack(Colst);
        if(search(array_map,0,0,n,m,Rowst,Colst) == true)
            for(i = 0;i<=GetPoP(Rowst);i++)
                printf("(%d,%d)\n",Rowst->Data[i],Colst->Data[i]);
        //printStack(Rowstack);//测试使用
        //printf("\n");
        //printStack(Colstack);
        //printf("\n");
        free(array_map);
    }
    return 0;
}
  • 9
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值