鱼C论坛

 找回密码
 立即注册
查看: 1953|回复: 7

[已解决]迷宫问题-栈-空指针

[复制链接]
发表于 2023-7-9 22:26:12 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 墨笠阳 于 2023-7-9 22:35 编辑

需求:以一个m×n的长方阵表示迷宫,0和1分别表示迷宫中的通路和障碍。设计一个程序,对任意设定的迷宫,求出一条从入口到出口的通路,获得出没有通路的结论。

程序设计思路:定义一个position类型的结构体来储存迷宫元素,用栈来存储迷宫maze 和通路path ,定义了两个指针p、per,分别指向在迷宫中遍历的当前位置和下一位置,通过“FindPath“函数的返回值判断,是否有通路,若有,则用for循环,将通路坐标自path栈输出,若无,则输出无通路的结论。
“FindPath“函数
操作1.依照”上、左、下、右”顺序从当前起点位置 p 开始对迷宫进行深度遍历,当下一位置per 未越边界、无障碍 且未被访问时,使 *per入通路栈path,并对其进行标记,表示已访问,再以per为新起点,进行深度遍历,直到下一位置per不满足入path栈的条件,
操作2.此时判断栈顶元素是否是出口,若是,则return 1;若不是,则判断是否是入口,若是,则return 0,若不是,使path栈栈顶元素出栈,实现回退,以新栈顶元素为新起点,重复操作1,操作2
问题:初始化及构建maze栈完成后,将maze栈的首地址赋给指针p,经检验,赋值后,指针p仍为空指针,与预期不符,求各位大佬不吝赐教
  1. InitStack_FindPath(path);//初始化通路栈
  2. InitStack_maze(maze);//初始化迷宫栈
  3. cout << "请输入行数:" ;
  4. cin >> row;
  5. cout << "\n请输入列数:";
  6. cin >> col
  7. cout << endl;
  8. Creat_maze(maze,row,col);//创造迷宫
  9. start = maze.base;//将迷宫入口的地址赋给指针start
  10. end = maze.top - 1;//将迷宫出口的地址赋给指针end
  11. p = maze.base;//将迷宫入口的地址赋给指针p
  12. p->step = 1;

  13. //验证指针p是否为空
  14. if (p) {
  15. cout << "NULL";
  16. cout << "\tx= " << p->x << "\ty= " << p->y << "\tpos= " << p->pos << "\tstep= " << p->step << endl;
  17. }

复制代码
输入:
5
5
0 1 0 1 1
0 0 1 1 1
1 0 1 0 1
1 0 0 0 1
1 0 1 0 0
输出:NULL    x= 0    y= 0    pos= 0  step= 0
  1. <blockquote>
复制代码


最佳答案
2023-7-9 22:33:01
我理解您正在使用一个栈结构和深度优先搜索算法来寻找一个迷宫的路径。在您提供的代码片段中,我看到您使用了一个栈类型的结构体来存储迷宫和路径,并定义了两个指针p和per来分别指向在迷宫中遍历的当前位置和下一个位置。您的问题似乎是在初始化迷宫栈并赋值给p指针后,发现p指针仍为空。

首先,对于问题的解决,这可能涉及到对栈的初始化和赋值的实现方式。你可能需要检查  InitStack_maze(maze) ,  Creat_maze(maze,row,col) ,以及  maze.base  的实现,以确保他们都在正确的位置初始化和分配内存,并确保  maze.base  正确地指向了栈底部的内存地址。

然后,你也需要注意的是,你的输出表示p是NULL,但是后面的字段显示x,y,pos,step有具体的值。这有可能是  if(p)  的逻辑判断有问题。如果  p  为空,那么  if(p)  的结果应该是false,所以应该不会执行下面的  cout  语句,这就产生了矛盾。你应该检查你的  if  条件判断的正确性,以确保它的逻辑是正确的。

最后,可以使用一些调试技巧,比如在创建迷宫后打印栈的情况,检查栈是否已经正确初始化和填充。同时,你也可以打印  maze.base  和  maze.top  的值,看看他们是否正确地指向了栈的底部和顶部。

如果你可以提供更多关于  InitStack_maze(maze) ,  Creat_maze(maze,row,col) ,以及  maze.base  的实现细节,我可能可以提供更具体的建议。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-7-9 22:49:07 | 显示全部楼层
  1. //struct.h
  2. #include<malloc.h>
  3. #define MAX_STACK_FindPath_SIZE 1275
  4. #define MAX_ROW 50
  5. #define MAX_COL 50

  6. //位置
  7. typedef struct  position {
  8.     int x = 0;//横坐标
  9.     int y = 0;//纵坐标
  10.     int pos = 1;//1,有障碍        0 无障碍        
  11.     int step = 0;//1 已访问 0 未访问,-1 回退时再次访问
  12. }position;

  13. typedef struct {
  14.     position* base;
  15.     position* top;
  16.     int stacksize;
  17. }Stack;

  18. //初始化
  19. int InitStack_FindPath(Stack& S) {
  20.     S.base = new position[MAX_STACK_FindPath_SIZE];
  21.     if (!S.base)
  22.         return 0;
  23.     else {
  24.         S.top = S.base;
  25.         S.stacksize = MAX_STACK_FindPath_SIZE;
  26.         return 1;
  27.     }
  28. }

  29. int InitStack_maze(Stack& S) {
  30.     int max = MAX_ROW * MAX_COL;
  31.     S.base = new position[max];
  32.     if (!S.base)
  33.         return 0;
  34.     else {
  35.         S.top = S.base;
  36.         S.stacksize = max;
  37.         return 1;
  38.     }
  39. }

  40. //入栈
  41. int Push(Stack& S, position p) {
  42.     if (S.top - S.base == S.stacksize)//栈满
  43.         return 0;
  44.     else {
  45.         *S.top = p;
  46.         S.top++;
  47.         return 1;
  48.     }
  49. }

  50. //出栈
  51. int Pop(Stack& S, position& p) {
  52.     if (S.top == S.base)
  53.         return 0;
  54.     else {
  55.         p = *(S.top - 1);
  56.         S.top--;
  57.         return 1;
  58.     }
  59. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-7-9 22:51:35 | 显示全部楼层
本帖最后由 墨笠阳 于 2023-7-9 22:53 编辑
  1. #include<iostream>
  2. #include"struct.h"
  3. using namespace std;

  4. void Creat_maze(Stack& maze, int row,int col);
  5. int FindPath(Stack& maze, Stack& path, position* p, position* start,position* end,int row,int col);
  6. int main() {
  7.         Stack maze;
  8.         Stack path;
  9.         position* p;
  10.         position* start, * end;
  11.         int row, col;
  12.         InitStack_FindPath(path);
  13.         InitStack_maze(maze);
  14.         cout << "请输入行数:" ;
  15.         cin >> row;
  16.         cout << "\n请输入列数:";
  17.         cin >> col;
  18.         cout << endl;
  19.         Creat_maze(maze,row,col);
  20.         start = maze.base;
  21.         end = maze.top - 1;
  22.         p = maze.base;

  23.         if (p) {
  24.                 cout << "NULL";
  25.                 cout << "\tx= " << p->x << "\ty= " << p->y << "\tpos= " << p->pos << "\tstep= " << p->step << endl;
  26.         }

  27.         p->step = 1;
  28.         if (FindPath(maze, path, p, start,end,row, col)) {
  29.                 p = path.base;
  30.                 while (p!=path.top) {                       
  31.                         cout << "(" << p->x << "," << p->y << ")" << endl;
  32.                         p++;
  33.                 }
  34.                 return 1;
  35.         }
  36.         else {
  37.                 cout << "此迷宫无通路!" << endl;               
  38.                 return 0;
  39.         }
  40. }
  41. void Creat_maze(Stack& maze, int row, int col) {
  42.         int i, j;
  43.         position p;
  44.         for (i = 0; i < row; i++) {
  45.                 p.x = i;
  46.                 for (j = 0; j < col; j++) {
  47.                         p.y = j;
  48.                         cin >> p.pos;
  49.                         Push(maze, p);
  50.                 }
  51.         }
  52. }
  53. int FindPath(Stack& maze, Stack& path, position* p,  position* start, position* end, int row, int col) {
  54.         position* per;
  55.          {
  56.                 //向上
  57.                 {
  58.                         per = p - col;
  59.                        
  60.                         /* // 验证per是否空
  61.                         if (per) {
  62.                                 cout << "NULL";
  63.                                 cout << "\tx= " << per->x << "\ty= " << per->y << "\tpos= " << per->pos << "\tstep= " << per->step<<endl;
  64.                         }/**/
  65.                         /**
  66.                         if (p) {
  67.                                 cout << "NULL";
  68.                                 cout << "\tx= " << per->x << "\ty= " << per->y << "\tpos= " << per->pos << "\tstep= " << per->step << endl;
  69.                         }/**/
  70.                         if (!per && per->pos == 0 && per->step == 0) {
  71.                                 //!per 未越上边界
  72.                                 //per->pos == 0 无障碍
  73.                                 //per->step == 0 未被访问
  74.                                 Push(path, *per);
  75.                                 per->step = 1;
  76.                                 if (FindPath(maze, path, per, start, end, row, col)) {
  77.                                         return 1;
  78.                                 }
  79.                                 else {
  80.                                         return 0;
  81.                                 }
  82.                         }
  83.                 }
  84.                 //向左
  85.                 {
  86.                         per = p - 1;
  87.                         /*
  88.                         if (per) {
  89.                                 cout << "NULL";
  90.                                 cout << "\tx= " << per->x << "\ty= " << per->y << "\tpos= " << per->pos << "\tstep= " << per->step << endl;
  91.                         }/**/
  92.                         if (!per && p->x == per->x && per->pos == 0 && per->step == 0) {
  93.                                 //!per && p->x == per->x 未越界
  94.                                 Push(path, *per);
  95.                                 per->step = 1;
  96.                                 if (FindPath(maze, path, per, start, end, row, col)) {
  97.                                         return 1;
  98.                                 }
  99.                                 else {
  100.                                         return 0;
  101.                                 }
  102.                         }
  103.                        
  104.                 }
  105.                 //向下
  106.                 {
  107.                         per = p + col;
  108.                         if (!(per->x == 0 && per->y == 0 && per->pos == 1) && per->pos == 0 && per->step == 0) {
  109.                                 //per->x == 0 && per->y == 0 && per->pos == 1 是position类型元素的默认值,表示maze栈外元素
  110.                                 Push(path, *per);
  111.                                 per->step = 1;
  112.                                 if (FindPath(maze, path, per, start, end, row, col)) {
  113.                                         return 1;
  114.                                 }
  115.                                 else {
  116.                                         return 0;
  117.                                 }
  118.                         }
  119.                 }
  120.                 //向右
  121.                 {
  122.                         per = p + 1;
  123.                         if (p->x == per->x && !(per->x == 0 && per->y == 0 && per->pos == 1) && per->pos == 0 && per->step == 0) {
  124.                                 Push(path, *per);
  125.                                 per->step = 1;
  126.                                 if (FindPath(maze, path, per, start, end, row, col)) {
  127.                                         return 1;
  128.                                 }
  129.                                 else {
  130.                                         return 0;
  131.                                 }
  132.                         }
  133.                 }

  134.                 //判断,是出口,return 1
  135.                 if (p == end) {
  136.                         return 1;
  137.                 }
  138.                        
  139.                 //不是出口
  140.                 else{
  141.                         //判断,是入口,return 0
  142.                         if (p == start) {
  143.                                 return 0;
  144.                         }
  145.                         //不是入口,回退,
  146.                         else {
  147.                                 position tem;
  148.                                 Pop(path, tem);
  149.                                 //以栈顶元素为新起点再遍历
  150.                                 per = (maze.base + (path.top - 1)->x * col + (path.top - 1)->y);
  151.                                 if (FindPath(maze, path, per, start, end, row, col)) {
  152.                                         return 1;
  153.                                 }
  154.                                 else {
  155.                                         return 0;
  156.                                 }
  157.                         }
  158.                 }

  159.         }

  160. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-7-9 22:33:01 | 显示全部楼层    本楼为最佳答案   
我理解您正在使用一个栈结构和深度优先搜索算法来寻找一个迷宫的路径。在您提供的代码片段中,我看到您使用了一个栈类型的结构体来存储迷宫和路径,并定义了两个指针p和per来分别指向在迷宫中遍历的当前位置和下一个位置。您的问题似乎是在初始化迷宫栈并赋值给p指针后,发现p指针仍为空。

首先,对于问题的解决,这可能涉及到对栈的初始化和赋值的实现方式。你可能需要检查  InitStack_maze(maze) ,  Creat_maze(maze,row,col) ,以及  maze.base  的实现,以确保他们都在正确的位置初始化和分配内存,并确保  maze.base  正确地指向了栈底部的内存地址。

然后,你也需要注意的是,你的输出表示p是NULL,但是后面的字段显示x,y,pos,step有具体的值。这有可能是  if(p)  的逻辑判断有问题。如果  p  为空,那么  if(p)  的结果应该是false,所以应该不会执行下面的  cout  语句,这就产生了矛盾。你应该检查你的  if  条件判断的正确性,以确保它的逻辑是正确的。

最后,可以使用一些调试技巧,比如在创建迷宫后打印栈的情况,检查栈是否已经正确初始化和填充。同时,你也可以打印  maze.base  和  maze.top  的值,看看他们是否正确地指向了栈的底部和顶部。

如果你可以提供更多关于  InitStack_maze(maze) ,  Creat_maze(maze,row,col) ,以及  maze.base  的实现细节,我可能可以提供更具体的建议。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2023-7-9 22:45:31 | 显示全部楼层
本帖最后由 墨笠阳 于 2023-7-9 23:22 编辑
isdkz 发表于 2023-7-9 22:33
我理解您正在使用一个栈结构和深度优先搜索算法来寻找一个迷宫的路径。在您提供的代码片段中,我看到您使用 ...


谢谢您的回复,问题已解决,确实是if(p)的逻辑判断出了问题
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-7-9 22:50:52 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-7-9 22:57:05 | 显示全部楼层

报错了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-7-9 23:19:08 | 显示全部楼层
调试过后发现确实是if(p) 的逻辑判断出问题了,
//越边界时,per为空,if(per)==if(false);未越界时,if(per)==if(true),
问题已解决,谢谢大家
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-4-22 08:32

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表