資料結構---迷宮問題題解(C語言)
阿新 • • 發佈:2018-12-15
資料結構—迷宮問題題解(C語言)
#include<stdio.h> #include<stdlib.h> #define FALSE 0 #define TRUE 1 #define OK 1 #define M 20 #define N 20 typedef struct mark //定義迷宮內點的座標 { int x; int y; }Mark; struct Element //資料域 { int x,y; //x行,y列 int d; //下一步的方向 }; typedef struct LStack //鏈棧 { Element elem; struct LStack *next; }*PLStack; /*************棧函式****************/ int InitStack(PLStack &S)//構造空棧 { S=NULL; return OK; } int StackEmpty(PLStack S)//判斷棧是否為空 { if(S==NULL) return OK; else return FALSE; } int Push(PLStack &S, Element e)//元素入棧 { PLStack p; p=(PLStack)malloc(sizeof(LStack)); p->elem=e; p->next=S; S=p; return OK; } int Pop(PLStack &S,Element &e) //元素出棧 { PLStack p; if(!StackEmpty(S)) { e=S->elem; p=S; S=S->next; free(p); return OK; } else return FALSE; } /*************建立迷宮*******************/ void initmaze(int maze[M][N]) { int m,n; //迷宮行,列 printf("請輸入迷宮的行數 m="); scanf("%d",&m); printf("請輸入迷宮的列數 n="); scanf("%d",&n); printf("\n請輸入迷宮的各行各列:\n用空格隔開,0代表路,1代表牆\n",m,n); for(int i=1;i<=m;i++) for(int j=1;j<=n;j++) scanf("%d",&maze[i][j]); printf("建立的迷宮為(最外圈為牆)\n"); //列印迷宮 for(int i=0;i<=m+1;i++) //加一圈圍牆 { maze[i][0]=1; maze[i][n+1]=1; } for(int j=0;j<=n+1;j++) { maze[0][j]=1; maze[m+1][j]=1; } for(int i=0;i<=m+1;i++) //輸出迷宮 { for(int j=0;j<=n+1;j++) printf("%d ",maze[i][j]); printf("\n"); } } /*************求迷宮路徑函式*************/ void MazePath(struct mark start,struct mark end,int maze[M][N],int diradd[4][2]) { int i,j,d; int a,b; Element elem,e; PLStack S1,S2; InitStack(S1); InitStack(S2); maze[start.x][start.y]=2; //入口點作上標記 elem.x=start.x; elem.y=start.y; elem.d=0; //開始為0 ,東 1;南 2;西3 ;北 4 Push(S1,elem); while(!StackEmpty(S1)) //棧不為空 有路徑可走 { Pop(S1,elem); i=elem.x; j=elem.y; d=elem.d+1; //下一個方向 while(d<=4) //試探南西北各個方向 { a=i+diradd[d-1][0]; b=j+diradd[d-1][1]; if(a==end.x && b==end.y && maze[a][b]==0) //找到出口 { elem.x=i; elem.y=j; elem.d=d; Push(S1,elem); elem.x=a; elem.y=b; elem.d=6; //方向輸出為-1 判斷是否到了出口 Push(S1,elem); printf("\n1=東 2=南 3=西 4=北 6為則走出迷宮\n\n通路為:(行座標,列座標,方向)\n"); while(S1) //逆置路徑序列 { Pop(S1,e); Push(S2,e); } while(S2) //出棧列印 { Pop(S2,e); printf("->(%d,%d,%d)",e.x,e.y,e.d); } return; //跳出兩層迴圈,本來用break,但發現出錯,exit又會結束程式,選用return還是不錯滴 } if(maze[a][b]==0) //找到可以前進的非出口的點 { maze[a][b]=2; //標記走過此點 elem.x=i; elem.y=j; elem.d=d; Push(S1,elem); //當前位置入棧 i=a; //下一點轉化為當前點 j=b; d=0; } d++; } } printf("沒有找到可以走出此迷宮的路徑\n"); } int main(){ int mg[M][N]; Mark start,end; //start,end入口和出口的座標 int add[4][2]={{0,1},{1,0},{0,-1},{-1,0}};//行增量和列增量 方向依次為東南西北 initmaze(mg);//建立迷宮 printf("輸入入口的橫座標,縱座標[逗號隔開]\n"); scanf("%d,%d",&start.x,&start.y); printf("輸入出口的橫座標,縱座標[逗號隔開]\n"); scanf("%d,%d",&end.x,&end.y); MazePath(start,end,mg,add); //find path return 0; }