第二三副是一副
说明一个问题:为什么m[1][5]变为了-1,那么多的3说明m[1][5]重复了访问两次,每一个被通过的单元都从他东边的一个单元开始检查他下一个单元是否通过。不管他前一个进入的单元是哪个方向,都要重新再来一次。
"a.h"
#include<stdio.h>
#include<malloc.h>
#include<string.h>
#include<stdlib.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
typedef int Status;
#define MAXSIZE 25
typedef int Maze[MAXSIZE][MAXSIZE];
Maze m; //定义全局变量迷宫
int curstep=1; //设置当前足迹为1
typedef struct {
int x;
int y;
}Position;
typedef struct{
int ord; //在路径中的序号
Position seat;
int di; //0-3分别代表东南西北
} ElemType;
#define INIT_SIZE 10
#define STACKINCREMENT 2
typedef struct SqStack{
ElemType *top;
ElemType *base;
int stacksize;
}SqStack;
//顺序栈,先分配一定的储存空间。
"b.h"
Status InitStack(SqStack *s)
{
(*s).base=(ElemType*)malloc(INIT_SIZE*sizeof(ElemType));
if(!(*s).base)
return ERROR;
(*s).top=(*s).base;
(*s).stacksize=INIT_SIZE;
return TRUE;
}
Status DestroyStack(SqStack *s)
{
free((*s).base);
(*s).base=(*s).top=NULL;
(*s).stacksize=0;
return TRUE;
}
Status ClearStack(SqStack *s)
{
(*s).top=(*s).base;
return TRUE;
}
Status StackEmpty(SqStack s)
{
if(s.base==s.top)
return TRUE;
else
return FALSE;
}
Status StackLength(SqStack s)
{
return s.top-s.base;
}
Status GetTop(SqStack s,ElemType *e)
{
if(s.top>s.base){
(*e)=*(s.top-1);
return TRUE;
}
else
return ERROR;
}
Status Push(SqStack *s ,ElemType e) //进栈
{
if((*s).top-(*s).base>=(*s).stacksize){
(*s).base=(ElemType*)realloc((*s).base,(INIT_SIZE+STACKINCREMENT)*sizeof(ElemType));
if(!(*s).base)
return ERROR;
(*s).top=(*s).base+(*s).stacksize;
(*s).stacksize+=STACKINCREMENT;
}
*((*s).top)=e;
(*s).top++;
return OK;
}
Status Pop(SqStack *s,ElemType *e) //出栈
{
if(!StackEmpty(*s)){
*e=*(--(*s).top);
return OK;
}
else
return ERROR;
}
Status StackTraverse(SqStack s,Status(*fun)(ElemType))
{
ElemType *p=s.top;
if(!StackEmpty(s)){
printf("栈定");
while(p!=s.base)
fun(*(--p));
printf("栈底\n");
return OK;
}
else
return ERROR;
}
"c.h"
#include"b.h"
Status fun(ElemType e)
{
printf("%d,%d<-- ",e.seat.x,e.seat.y);
return OK;
}
Status Pass(Position p) //是否为可通过路径
{
if (m[p.x][p.y]==1)
return TRUE;
else
return FALSE;
}
Status FootPrint(Position p) //使迷宫的p变为足迹
{
m[p.x][p.y]=curstep;
return OK;
}
Position NextPosition(Position p,int i)
{
Position q[4]={{0,1},{1,0},{0,-1},{-1,0}}; //难以想到这么简练的代码
// {行,列} 东 南 西 北
p.x+=q[i].x;
p.y+=q[i].y;
return p;
}
Status MarkPrint(Position p) //不能通过的路径用-1表示
{
m[p.x][p.y]=-1;
return OK;
}
Status MazePath(Position start,Position end)
{
SqStack sq;
Position p;
ElemType e ;
InitStack(&sq);
p=start;
do{
if(Pass(p)){ //当前位置可过
FootPrint(p);
e.ord=curstep; e.seat.x=p.x;e.seat.y=p.y; e.di=0;
Push(&sq,e);
curstep++;
if(p.x==end.x&&p.y==end.y){
StackTraverse(sq,fun);
return TRUE;
}
p=NextPosition(p,e.di);
}
else{ //当前位置不可过
if(!StackEmpty(sq)){
Pop(&sq,&e);
curstep--;
printf("***** %d\n",curstep);
while(e.di==3&&!StackEmpty(sq)){ //3什么意思,3指北方,最后一个方向,
printf("***** %d\n",curstep); //最后一个方向都封死了必须再退栈。
MarkPrint(e.seat);
Pop(&sq,&e);
curstep--;
printf("*****%d\n",curstep);
}
if(e.di<3){ //说明过不去的并不是最后一个方向
//所以可以向下一个方向继续下去,再进栈。
e.di++;
Push(&sq,e);
curstep++;
p=NextPosition(e.seat,e.di);
}//end if
}//end if
}//end else
} while(!StackEmpty(sq));
return OK;
}
Status Print(int x,int y)
{
int i,j;
for(i=0;i<x;i++){
for(j=0;j<y;j++)
printf(" %d ",m[i][j]);
printf("\n");
}
return OK;
}
"main.c"
#include"a.h"
#include"c.h"
void main()
{
Position start,end;
int i,j,x,y,n,a,b;
printf("请输入迷宫的行,列:");
scanf("%d, %d",&x,&y);
for(i=0;i<x;i++){
m[i][0]=0;
m[i][y-1]=0;
}
for(j=0;j<y;j++){
m[0][j]=0;
m[x-1][j]=0;
}
for(i=1;i<x-1;i++)
for(j=1;j<y-1;j++)
m[i][j]=1;
printf("输入迷宫内墙数 ");
scanf("%d", &n);
printf("依次输入每个内墙的单元的行列 :");
for(i=0;i<n;i++){
scanf("%d,%d",&a,&b);
m[a][b]=0;
}
printf("迷宫结构为\n");
Print(x,y);
// ****************************** 构造迷宫结构
printf("输入起点的行列数: ");
scanf("%d,%d",&start.x,&start.y);
printf("输入终点的行列数: ");
scanf("%d,%d",&end.x,&end.y);
if(MazePath(start,end)){
printf("路径如图 :\n");
Print(x,y);
}
else
printf("没有路径\n");
}