数据结构迷宫与栈问题

求帮忙看看这个代码哪里有问题,打印不出来路径
代码如下:

#define STACK_H_INCLUDED  //定义栈 H 
#include         //定义输入输出函数 
#include        //标准库函数的定义 
#include          //定义数学函数



#define M 8
#define N 8

#define _CRT_SECURE_NO_WARNINGS    //定义CRT安全无警告 

#define OK 1
#define ERROR 0                    //ok为1  error为0 
#define TRUE 1 
#define FALSE 0                    //正确为1,错误为0
#define null  0 
#define STACK_INIT_SIZE 30         //初始栈的容量为30 
#define STACK_INCREMENT 10         //栈满后,每次扩充的容量为10(increment:定量的增长)
#define EXPRESS_MAX 1024           //后缀表达式 长度不能超过1024 

 
typedef struct SNode        //声明栈中结点的类型和指向结点的指针类型 
{
    int x,y;                //当前访问的迷宫格子的纵横坐标 
    int di;        
    struct SNode *next;     //栈结点的指针域,存的是下一个结点的地址 
    struct SNode *present;  //当前结点的地址 
}Box, *LinStackPtr;          

typedef int Status;        //typedef用来定义类型的别名,status i 就相当于int i 
typedef int EleType;       //typedef用来定义类型的别名,EleType e1 相当于 int e1  

typedef struct SeqStack     //栈的标准定义 
{   
    Box* top;              //栈顶指针
    Box* base;             //栈底指针 
    int stackSize;         //栈容量
}SeqStack;



typedef struct{
    //定义x,y方向上的增量
    int incX,incY; 
}Direction;
Direction direct[4];

//初始化栈,开辟空间  
Status InitStack(SeqStack* stack)   //创造一个空栈 
{
    stack->base = stack->top = (Box*)malloc(sizeof(Box));   //将放入栈的元素从栈顶位置放入 
    int i=0;                       
    for(i=0;i<50;i++)  
    {
        stack->top->next=(Box*)malloc(sizeof(Box));
        stack->top->next->present=stack->top;
        stack->top=stack->top->next;                         
    } 
    stack->top=stack->base;                                 //栈底元素==栈顶元素 
    if(!stack->base)                                        //如果没有元素放入栈中 
    {
        exit(0);    
    }
    stack->stackSize=STACK_INIT_SIZE;                     //设置栈的容量为定义的初始栈容量 
    return OK;     
} 


//入栈,又称为 “压栈 ” 
Status push(SeqStack* stack,EleType e1,EleType e2,EleType e3)       //定义要插入的元素e1,e2,e3 
{
    if(stack == null)
    {
        return ERROR;                                    //如果栈为空,返回错误 
    }
    //进行压栈操作前需检测容量是否够用 
    if((stack->top - stack->base)/sizeof(stack->stackSize))
    {
        //超出容量进行扩容,使用realloc函数(重新分配函数),会拷贝原内存中的内容
        stack->base=(Box*)realloc(stack->base,stack->stackSize+STACK_INCREMENT);
        if(!stack->base)
        {
            exit(0);    
        }
        stack->top=stack->base+stack->stackSize;
        stack->stackSize +=STACK_INCREMENT; //stack->stackSize=stack->stackSize + STACK_INCREMENT         
    } 
    (*(stack->top)).x=e1;                  //入栈的横坐标x为e1元素 
    (*(stack->top)).y=e2;                  //入栈的纵坐标y为e2元素
    (*(stack->top)).di=e3;
    stack->top=(*(stack->base)).next;
    return OK;     
} 


//出栈,又称为 “弹栈 ”
Status pop(SeqStack* stack,EleType *e1,EleType *e2,EleType *e3)
{
    if(stack==null)
    {
        return ERROR;                                   //如果栈为空,返回错误 
    } 
    if(stack->top==stack->base)
    {
        return ERROR;    
    } 
    stack->top=stack->top->present;
    *e1= (stack->top)->x;
    *e2= (stack->top)->y;
    *e3= (stack->top)->di;
    return OK;

} 

/*
获取栈顶元素
*/

Status GetTop(SeqStack* stack,EleType *e1,EleType *e2,EleType *e3)
{
    if(stack==null)
    {
        return ERROR;
    }
    *e1=(stack->top->present)->x;
    *e2=(stack->top->present)->y;
    *e3=(stack->top->present)->di;
    return OK;
}
 
/*
判断栈是否为空格
*/
int IsEmptyStack(SeqStack* stack)
{
    if(stack==null)
    {
        return ERROR;    
    }    
    if(stack->top==stack->base)
    {
        return TRUE;    
    } 
    return FALSE;
} 

/*
对栈进行销毁
*/
Status DestoryStack(SeqStack* stack)
{
    if(stack==null)
    {
        return ERROR;    
    }
    if(!stack->base)
    {
        free(stack->base);       //将栈中元素释放    
    }    
    stack->top=stack->base=null;
    stack->stackSize=0;          //栈的容量变为0
    return OK; 
} 
/*
bool findPath(int maze[M+2][N+2],Direction direct[], SeqStack &S)
{
    Box temp;
    int x,y,di;       //迷宫格子当前处理单元的纵横坐标和方向
    int line,col;     //迷宫数组下一单元的行坐标与列坐标
    maze[0][1]=-1;    //入口,将走过的地方用-1表示,防止走重复路线 
    //SeqStack S;
    SeqStack H;
    InitStack(&S);
    InitStack(&H);
    temp.x=0;
    temp.y=1;
    temp.di=-1;
                      //temp={0,1,-1}; 
                      //       x  y  di
                      // temp: 0  1  -1 
    
    push(&S,temp.x,temp.y,temp.di);     //将temp数据压入s栈中
    
    while(!IsEmptyStack(&S)){    //当S栈不是一个空栈时 
        pop(&S,&(temp.x),&(temp.y),&(temp.di));  //将栈中的数据弹出到temp中 
        x=temp.x;
        y=temp.y;
        di=temp.di;
        while(di<4){
            line=x+direct[di].incX;  //下一个结点的行坐标 
            col= y+direct[di].incY;  //下一个结点的纵坐标 
            if(maze[line][col]==0){  //判断迷宫此位置是否为通的 
                    x=temp.x;
                    y=temp.y;
                    di=temp.di;    //将上一部结点的保存到temp中 
                push(&S,temp.x,temp.y,temp.di);  //将temp的值压入堆栈中 
                x=line;
                y=col;                
                maze[line][col]=-1;  //表示经过了此位置
                if(x==M && y==N)
                {
                    //由于栈先入后出的特性这里重新定义一个栈目的就是能够正序输出其坐标
                    while(!IsEmptyStack(&S))
                    {
                        pop(&S,&(temp.x),&(temp.y),&(temp.di));   //int e1,e2,e3  GetTop(&S,&e1,&e2,&e3); 取栈顶元素
                        push(&H,temp.x,temp.y,temp.di);   //将从s栈中的元素取出放入h栈中 
                    } 
                    while(!IsEmptyStack(&H)) 
                    {
                        pop(&H,&(temp.x),&(temp.y),&(temp.di));
                        printf("(%d,%d),direct:%d\n",temp.x,temp.y,temp.di); 
                    }
                    return true; //当x=M,y=N(所在出口位置)证明迷宫有路 
                }
                 
                else di=0;      
            }
            else di++;     //如果迷宫不为空,进行di++ 
        } 
    } 
    return false; //如果迷宫走不通,堆栈会不断的回退,直到堆栈为空,证明迷宫没有路 
}

//栈中所保存的是一条迷宫通路 
//最终输出,将栈内元素从下往上输出 

*/







int main()
{    

    //EleType e,m;
    //迷宫是一个二维数组,我们可以采用坐标的形式 (i,j)
    
     
    //int Direction;     //定义方向Direction 
    
    //迷宫用一个二维数组表示 
    //通路:0  障碍:1 
    int maze[M+2][N+2]={{1,1,1,1,1,1,1,1,1,1},   //0行 
                        {1,0,0,1,0,0,0,1,0,1},   //1行 
                        {1,0,0,1,0,0,0,1,0,1},   //2行 
                        {1,0,0,0,0,1,1,0,0,1},   //3行 
                        {1,0,1,1,1,0,0,0,0,1},   //4行 
                        {1,0,0,0,1,0,0,0,0,1},   //5行
                        {1,0,1,0,0,0,1,0,0,1},   //6行
                        {1,0,1,1,1,0,1,1,0,1},   //7行
                        {1,1,0,0,0,0,0,0,0,1},   //8行
                        {1,1,1,1,1,1,1,1,1,1}};  //9//其中外围都设置1,只设置20,一个用来表示入口,一个用来表示出口 
    
    //将自己随机创立的迷宫进行输出 
    
    int i,j; 
     for(i = 0; i< M+2;i++)
    {
        for(j=0; j2;j++)
        {
            printf("%d",maze[i][j]);
        }
        printf("\n");
    }
    
    
    Direction direct[4]= {{0,1},{1,0},{0,-1},{-1,0}};
    printf("%d",direct[4].incX);
    
    
    Box temp;
    int x,y,di;       //迷宫格子当前处理单元的纵横坐标和方向
    int line,col;     //迷宫数组下一单元的行坐标与列坐标
    maze[1][1]=-1;    //入口,将走过的地方用-1表示,防止走重复路线 
    SeqStack S;
    SeqStack H;
    InitStack(&S);
    InitStack(&H);
    temp.x=1;
    temp.y=1;
    temp.di=-1;
                      //temp={0,1,-1}; 
                      //       x  y  di
                      // temp: 1  1  -1 
    
    push(&S,temp.x,temp.y,temp.di);     //将temp数据压入s栈中
    
    while(!IsEmptyStack(&S)){    //当S栈不是一个空栈时 
        pop(&S,&(temp.x),&(temp.y),&(temp.di));  //将栈中的数据弹出到temp中 
        x=temp.x;
        y=temp.y;
        di=temp.di;
        while(di<4){
            line=x+direct[di].incX;  //下一个结点的行坐标 
            col= y+direct[di].incY;  //下一个结点的纵坐标 
            if(maze[line][col]==0){  //判断迷宫此位置是否为通的 
                    x=temp.x;
                    y=temp.y;
                    di=temp.di;    //将上一部结点的保存到temp中 
                push(&S,temp.x,temp.y,temp.di);  //将temp的值压入堆栈中 
                x=line;
                y=col;                
                maze[line][col]=-1;  //表示经过了此位置
                if(x==M && y==N)
                {
                    //由于栈先入后出的特性这里重新定义一个栈目的就是能够正序输出其坐标
                    while(!IsEmptyStack(&S))
                    {
                        pop(&S,&(temp.x),&(temp.y),&(temp.di));   //int e1,e2,e3  GetTop(&S,&e1,&e2,&e3); 取栈顶元素
                        push(&H,temp.x,temp.y,temp.di);   //将从s栈中的元素取出放入h栈中 
                    } 
                    while(!IsEmptyStack(&H)) 
                    {
                        pop(&H,&(temp.x),&(temp.y),&(temp.di));
                        printf("(%d,%d),direct:%d\n",temp.x,temp.y,temp.di); 
                    }
                    return true; //当x=M,y=N(所在出口位置)证明迷宫有路 
                }
                 
                else 
                    di=0;      
            }
            else 
                              di++;     //如果迷宫不为空,进行di++ 
        } 
    } 
    return false; //如果迷宫走不通,堆栈会不断的回退,直到堆栈为空,证明迷宫没有路 

//栈中所保存的是一条迷宫通路 
//最终输出,将栈内元素从下往上输出 

    
} 

参考GPT和自己的思路:

经过代码的分析,主要问题是在入栈函数 push() 中的一个指针操作错误导致了元素的覆盖。具体来说是在修改栈顶指针的赋值操作时,应该将其指向新压入的元素,而不是原先栈顶元素的下一个。

修正代码如下:

//入栈,又称为 “压栈 ” 
Status push(SeqStack* stack,EleType e1,EleType e2,EleType e3)       //定义要插入的元素e1,e2,e3 
{
    if(stack == null)
    {
        return ERROR;                                    //如果栈为空,返回错误 
    }
    //进行压栈操作前需检测容量是否够用 
    if((stack->top - stack->base)/sizeof(stack->stackSize))
    {
        //超出容量进行扩容,使用realloc函数(重新分配函数),会拷贝原内存中的内容
        stack->base=(Box*)realloc(stack->base,stack->stackSize+STACK_INCREMENT);
        if(!stack->base)
        {
            exit(0);    
        }
        stack->top=stack->base+stack->stackSize;
        stack->stackSize +=STACK_INCREMENT; //stack->stackSize=stack->stackSize + STACK_INCREMENT         
    } 
    (*(stack->top)).x=e1;                  //入栈的横坐标x为e1元素 
    (*(stack->top)).y=e2;                  //入栈的纵坐标y为e2元素
    (*(stack->top)).di=e3;
    Box* new_top = stack->top + 1;  // 新的栈顶指针
    new_top->present = stack->top;
    stack->top = new_top;
    return OK;     
}

参考GPT和自己的思路:

在代码中,栈的入栈操作中有一个问题:

stack->top=(*(stack->base)).next;

应该改为:

stack->top++;
*(stack->top)).x=e1;                  //入栈的横坐标x为e1元素 
(*(stack->top)).y=e2;                  //入栈的纵坐标y为e2元素
(*(stack->top)).di=e3;

同时,迷宫的边界需要设置为障碍物,所以在代码中应该将迷宫数组的第一行和最后一行、第一列和最后一列都设置为1表示障碍物。此外,还需要将路径更新的条件从

if(maze[line][col]==0)

改为

if(maze[line][col]==0 || (line == M && col == N))

因为如果路径到达终点,也需要进行路径更新操作。

单步调试一下,看看你的程序怎么遍历路径的。