基于栈的C语言迷宫问题与实现Word文件下载.docx
《基于栈的C语言迷宫问题与实现Word文件下载.docx》由会员分享,可在线阅读,更多相关《基于栈的C语言迷宫问题与实现Word文件下载.docx(15页珍藏版)》请在冰豆网上搜索。
1.迷宫的生成
根据题目的要求,迷宫的大小是自定义输入的。
所以在程序中用malloc申请动态二维数组。
数组中的元素为随机生成的0、1。
数组周围一圈的元素全部定义为1,以表示边界。
2.栈的C语言实现
为了实现栈的功能,即清空、压栈、弹出、返回栈顶元素,在程序中编写了相应的函数。
MakeNULL清空栈
Push将横、纵坐标压栈
Topx返回栈顶存储的横坐标
Topy返回栈顶存储的纵坐标
Pop弹出栈顶元素
3.具体的判断算法
当位置坐标(程序中为XY)移到某一位置时,将这个位置的值赋值为1并压栈,以说明该点已经走过。
接着依次判断该点的上、右、下、左是否为0,若有一方为0,则移动到该位置上,进行下次判断;
若为周围位置全部是1,则将该点压栈后不断弹出,每次弹出时判断栈顶元素(即走过的路)周围有无其他通路。
如果有的话,则选择该方向继续走下去;
如果栈已经为空仍然没有找到出路,则迷宫没有出口程序结束。
当XY走到出口坐标时,程序判断部分结束。
栈里面存储的是每个走过的点的坐标,将这些横纵坐标分别存储在两个数组中,最后将数组中的坐标元素倒序输出,即得到了完整的路径。
四.程序源代码及注释
//Maze.cpp:
定义控制台应用程序的入口点。
//
#include"
stdafx.h"
#include<
stdio.h>
string.h>
malloc.h>
#include<
stdlib.h>
time.h>
typedefintElementtype;
structnode
{
Elementtypeval1;
Elementtypeval2;
node*next;
};
//定义结构体
typedefnode*MAZE;
voidMakeNull(MAZE&
S);
voidPush(Elementtypex,Elementtypey,MAZES);
voidPop(MAZES);
ElementtypeTopx(MAZES);
ElementtypeTopy(MAZES);
//申明函数
int_tmain(intargc,_TCHAR*argv[])
int**p,*q,*x1,*y1,i,j,k,n1,n2,m1,m2,l,w,max;
intx,y;
inta,b,c,d;
printf("
输入迷宫长度及宽度l和w\n"
);
scanf("
%d%d"
&
l,&
w);
getchar();
n1=w+2;
n2=l+2;
//为迷宫加上边界
max=n1*n2;
p=(int**)malloc(n1*sizeof(int));
for(i=0;
i<
n1;
i++)
p[i]=(int*)malloc(n2*sizeof(int));
//生成二维动态数组
srand(time(NULL));
x1=(int*)malloc(max*sizeof(int));
//生成动态数组用于存储路径
y1=(int*)malloc(max*sizeof(int));
max;
{
x1[i]=0;
}
y1[i]=0;
}//先将存储路径的数组元素全赋值为0
for(j=0;
j<
n2;
j++)
if(i==0||j==0)
{
p[i][j]=1;
}
elseif(i==n1-1||j==n2-1)
else
p[i][j]=rand()%2+0;
}//生成二维10随机数组
p[1][1]=0;
p[n1-2][n2-2]=0;
//定义迷宫的入口及出口
生成的迷宫如下(代表墙0代表路):
\n"
%2d"
p[i][j]);
}//打印迷宫
MAZES;
MakeNull(S);
//清空栈
i=1;
j=1;
if(p[1][2]==1&
&
p[2][1]==1)
Thereisnowayout"
a
return0;
}//判断入口是否就是死路
else
do
if(p[i-1][j]==0)
x=i;
y=j;
Push(x,y,S);
p[i][j]=1;
i=i-1;
}//判断能否向上走
elseif(p[i-1][j]==1&
p[i][j+1]==0)
j=j+1;
}//判断能否向右走
p[i][j+1]==1&
p[i+1][j]==0)
k=Topx(S);
i=i+1;
}//判断能否向下走
p[i+1][j]==1&
p[i][j-1]==0)
j=j-1;
}//判断能否向左走
p[i][j-1]==1)//判断如果为死路
for(;
;
)
Pop(S);
//弹出栈顶元素
x=Topx(S);
y=Topy(S);
//返回栈顶元素横纵坐标
if(p[x-1][y]==0)
i=x-1;
j=y;
break;
elseif(p[x-1][y]==1&
p[x][y+1]==0)
i=x;
j=y+1;
p[x][y+1]==1&
p[x+1][y]==0)
i=x+1;
p[x+1][y]==1&
p[x][y-1]==0)
j=y-1;
}//判断弹出后栈顶元素周围有无通路
elseif(x==1&
y==1)
printf("
getchar();
return0;
}//如果栈顶元素为入口则迷宫无出路
}while(i!
=n1-2||j!
=n2-2);
//循环截止条件
Success!
\nTherouteis:
a=Topx(S);
b=Topy(S);
x1[i]=a;
y1[i]=b;
//将栈顶元素坐标存储在数组中
if(a==1&
b==1)
for(i=max-1;
i>
=0;
if(x1[i]!
=0&
(x1[i]!
=x1[i-1]||y1[i]!
=y1[i-1]))
<
%d,%d>
"
x1[i],y1[i]);
i--;
elseif(x1[i]!
(x1[i]==x1[i-1]&
y1[i]==y1[i-1]))
i=i-2;
else
}//倒序打印数组得到顺序出路坐标
"
n1-2,n2-2);
//打印出口坐标
}
S)//清空栈的函数
S=newnode;
S->
next=NULL;
voidPush(Elementtypex,Elementtypey,MAZES)//压栈函数
MAZEstk;
stk=newnode;
stk->
val1=x;
val2=y;
next=S->
next;
next=stk;
voidPop(MAZES)//弹出函数
if(S->
next)
stk=S->
S->
next=stk->
deletestk;
ElementtypeTopx(MAZES)//返回横坐标函数
return(S->
next->
val1);
returnNULL;
ElementtypeTopy(MAZES)//返回纵坐标函数
val2);
五.程序运行结果
运行程序后,首先输入迷宫的长度和宽度
假设迷宫是8*8的(也可以为其他大小)。
输入后若没有出路,则显示“Thereisnowayout”,程序结束。
输入后若迷宫有出路,则显示Success
再次按下回车键,则打印出迷宫路径
程序结束
六.程序运行结果自评
该程序运用栈的思想,成功解决了迷宫问题。
下面对上述运行结果进行简要分析:
当迷宫没有出路时,系统首先走到2,2点弹出,发现2,1点下方为出路,然后继续向下走。
但是走到5,1点时发现周围再次为死路,只能不停弹出,同时检测周围有无出路。
当弹出到1,1,点时,发现迷宫没有出路,程序结束。
当迷宫有出路时,系统按照既定规则移动,在3,5点时并未直接向下走向4,5点,而是按照判断顺序向右移动。
当走到1,8点时发现为死路,则不停弹出并且检测周围有无出路。
弹出到3,5时发现4,5可以走,则继续走下去,直到走到终点,程序结束。
在调试程序时,对栈顶元素进行观测,当程序分步执行时,可以清楚地看到栈里面元素的变化,从而分析出程序完成了的压栈、弹出的步骤。
在编写与调试程序的过程中,我遇到了很多问题。
其中最主要的有动态数组的生成、对栈的概念的理解与栈的实现、具体算法的判断标准与循环结束条件等等。
通过加设断点、分步执行程序、观测变量值等方法,不断对程序进行改进,直到最终成型。
在这过程中,我对C语言的使用有了进一步的熟悉,对栈的思想有了更深入的了解。