1.任务:
[问题描述]
利用栈操作实现迷宫问题求解。
[基本要求]
(1)从文件中读取数据,生成模拟迷宫地图,不少于20行20列。
(2)给出任意入口和出口,显示输出迷宫路线。若没有路线应输出“无线路”,若有多个解,可输出一个或多个线路。
2.采用的数据结构
采用栈与队列
3.算法设计思想
采用栈,将相邻的代表可走的位置进栈(当该点四周有多个位置可走时,按照右下上左的优先级走),将走过的点标记为2。当走到一点四周都为墙或是走过的路时,将该位置标记为9,后退一格,查找下一个可走的位置,直至走到指定的位置为止。
4.源程序
#include <iostream>
#include <fstream>
using namespace std;
typedef struct point
{
int r,c;
}point;
point stack[256];
int num=0;
int find1(int row,int col,int path[][50],int a,int b,int x2,int y2)
{
if((a==x2) && (b==y2))
{
return 1;
}
else
{
if((b!=col-1)&&(path[a][b+1]==0)) //判断是否能向右走
{
path[a][b]=2;
stack[num].r=a;
stack[num].c=b;
num++;
find1(row,col,path,a,b+1,x2,y2);
}
else
{
if((a!=row-1)&&(path[a+1][b]==0)) //不能向右时向下
{
path[a][b]=2;
stack[num].r=a;
stack[num].c=b;
num++;
find1(row,col,path,a+1,b,x2,y2);
}
else
{
if((a!=0) && (path[a-1][b]==0)) //不能向右向下时向上
{
path[a][b]=2;
stack[num].r=a;
stack[num].c=b;
num++;
find1(row,col,path,a-1,b,x2,y2);
}
else
{
if((b!=0) && (path[a][b-1]==0)) //不能向右向上向下时向左
{
path[a][b]=2;
stack[num].r=a;
stack[num].c=b;
num++;
find1(row,col,path,a,b-1,x2,y2);
}
else //无法移动时,标记此格,后退一步
{
path[a][b]=9;
num--;
if(num==0)
{
return 0;
}
int x,y;
x=stack[num].r;
y=stack[num].c;
find1(row,col,path,x,y,x2,y2);
}
}
}
}
}
}
int main()
{
ifstream infile;
infile.open("迷宫路.txt");
if(infile)
{
int row,col;
infile>>row;
infile>>col;
int path[row][50];
for(int i=0;i<row;i++)
{
for(int j=0;j<col;j++)
{
infile>>path[i][j];
}
}
infile.close();
printf("迷宫路线如下图所示:\n");
for(int i=0;i<row;i++)
{
for(int j=0;j<col;j++)
{
cout<<path[i][j]<<" ";
}
printf("\n");
}
printf("\n请输入入口和出口位置:\n");
printf("例:1 1 7 7(入口为第1行第1列,出口为第7行第7列)\n");
int x1,x2,y1,y2;
scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
x1--;
x2--;
y1--;
y2--;
if((path[x1][y1]==1) || (path[x2][y2]==1))
{
printf("输入有误,请重新输入!");
}
else
{
int flag;
flag=find1(row,col,path,x1,y1,x2,y2);
if(flag==1)
{
printf("迷宫线路存在:\n");
path[x2][y2]=2;
for(int i=0;i<row;i++) //输出迷宫路线
{
for(int j=0;j<col;j++)
{
if((path[i][j]==1))
{
printf("# ");
}
else
{
if(path[i][j]==9||(path[i][j]==0))
{
printf(" ");
}
else
{
printf("o ");
}
}
}
printf("\n");
}
}
else
{
printf("无线路。\n");
}
}
}
else
{
printf("文件打开失败");
}
return 0;
}
5.源程序测试数据及结果
迷宫问题测试用例
迷宫问题测试结果
6.存在问题及改进方法
对于给定的起点和终点迷宫路径有可能输出的不是最优路径,即可能出现在死胡同里绕一圈再出来的情况,可以通过增加函数来对于这样的路径进行改善。同时,对于给定的输入,函数的输出有且仅有唯一的情况,但在现实问题中,路径的选择可能不止一种,可以对于存在路径都进行查找,实现多路径的输出。