用矩阵(矩阵大小设为8*10,下标从0开始,点(1,1)为起点,点(6,8)为终点)代表地图,矩阵中1代表可以走通,0代表可以走通。假设目前位于(x,y)处,则下一可能位置为(x-1,y-1)(x-1,y)(x-1,y+1)(x,y-1)(x,y+1)(x+1,y-1)(x+1,y)(x+1,y+1)。
(1)将起点压栈并标记为已经历过(可以用-1表示,标记的原因是防止死循环)。
(2)在(x,y)的下一可能位置中选择一个是通路(这里为0)且没走过的点进行压栈,同时标记已经走过。
(3)如果(x,y)附近八个点都不满足条件,就将(x,y)退栈
如果栈不为空,就重复(2)。否则结束,无解。
输入:大小为8*10的矩阵,矩阵中1代表可以走通,0代表可以走通。
输出:由起点走到终点的路线。
代码实现如下:
#include"stdio.h" #include"stdlib.h" #include"conio.h" #define STACKSIZE 2000 #define INCREMENT 20 #define SIZE 10 int maze[SIZE-2][SIZE]; typedef struct{ //位置结构体 int x; int y; }PosType; typedef struct{ //栈的元素类型结构体 int ord; PosType seat; int di; }SElemType; typedef struct{ SElemType *base; SElemType *top; int stacksize; }SqStack; void InitStack(SqStack &S) //创建一个空栈 { S.base =(SElemType *)malloc(STACKSIZE*sizeof(SElemType)); if(!S.base) printf("储存分配失败!!\n"); else{ S.top=S.base ; S.stacksize =STACKSIZE; } } void Push(SqStack &S,SElemType e) //向栈顶插入元素 { if(S.top-S.base>=S.stacksize ) { S.base=(SElemType *)malloc((S.stacksize+INCREMENT)*sizeof(SElemType)); if(!S.base) printf("追加分配储存空间失败!!!\n"); else{ S.top =S.base +S.stacksize; S.stacksize +=INCREMENT; *S.top ++ = e; } } else {*S.top ++ = e; } } void Pop(SqStack S,SElemType &e) //删除栈顶元素,并且将栈顶元素的值用e返回 { if(S.top!=S.base) e=*--S.top; } int StackEmpty(SqStack S) // 空栈判断 { if(S.base ==S.top) return 1; else return 0; } int Pass(PosType pos) { if(maze[pos.x][pos.y+1]==0||maze[pos.x+1][pos.y+1]==0||maze[pos.x+1][pos.y]==0||maze[pos.x+1][pos.y-1]==0||maze[pos.x][pos.y-1]==0||maze[pos.x-1][pos.y-1]==0||maze[pos.x-1][pos.y]==0||maze[pos.x-1][pos.y+1]==0) return 1; else return 0; } PosType NextPos(PosType pos,int di) { int x=pos.x; int y=pos.y; switch(di){ case 1: if(maze[x][y+1]==0){ pos.y=y+1;break; } case 2: if(maze[x+1][y+1]==0){ pos.x=x+1;pos.y=y+1;break; } case 3:if(maze[x+1][y]==0) { pos.x=x+1;break; } case 4: if(y>0) if(maze[x+1][y-1]==0){ pos.x=x+1;pos.y=y+1;break; } case 5: if(y>0) if(maze[x][y-1]==0){ pos.y=y-1;break; } case 6:if(y>0&&x>0){ if(maze[x-1][y-1]==0){ pos.x=x-1;pos.y=y-1;break; } } case 7:if(x>0) if(maze[x-1][y]==0){ pos.x=x-1;break; } case 8: if(x>0) if(maze[x-1][y+1]==0){ pos.x=x-1;pos.y=y+1;break; } } return pos; } void MarkPrint(PosType t) { maze[t.x][t.y]=1; } void FootPrint(PosType t) { printf("%d %d\n",t.x,t.y); } void MazePath(int maze[SIZE-2][SIZE],PosType start,PosType end) { SqStack S; InitStack(S); SElemType e; PosType curpos=start; //当前位置 int curstep=1; //当前通道块序号 do{ if(Pass(curpos)){ //当前通道块可通 FootPrint(curpos); e.di=1; e.ord=curstep; e.seat=curpos; Push(S,e); if(curpos.x==end.x&&curpos.y==end.y) break; curpos=NextPos(curpos,1); curstep++; } else{ //不通 if(!StackEmpty(S)){ Pop(S,e); while(e.di==8&&!StackEmpty(S)){ MarkPrint(e.seat); Pop(S,e); } if(e.di<8) { e.di++; Push(S,e); curpos=NextPos(e.seat,e.di); } } } } while(!StackEmpty(S)); } int main() { int i,j; PosType start,end; start.x=1;start.y=1; end.x=6;end.y=8; printf("请输入迷宫(大小为8*10):\n"); for(i=0;i<SIZE-2;i++) for(j=0;j<SIZE;j++) scanf("%d",&maze[i][j]); MazePath(maze,start,end); return 0; }
我构建的迷宫(矩阵)为:
1 1 1 1 1 1 1 1 1 1
1 0 1 1 1 1 1 1 1 1
1 1 0 1 1 1 1 1 1 1
1 1 0 1 1 1 1 1 1 1
1 1 1 0 0 0 1 1 1 1
1 1 1 1 0 0 0 1 1 1
1 1 1 1 1 1 0 0 0 1
1 1 1 1 1 1 1 1 1 1
运行结果如下: