c语言实现迷宫问题
用C语言解决迷宫问题
![用C语言解决迷宫问题](https://img.taocdn.com/s3/m/48e84144ce84b9d528ea81c758f5f61fb6362851.png)
⽤C语⾔解决迷宫问题#include <stdio.h>#include <stdlib.h>#define ROW 10#define COL 10/*迷宫中位置信息*/typedef struct position{int x;int y;}position;/*在迷宫中的当前位置的信息,也是⼊栈的基本元素*/typedef struct SElem{int di;position seat;}SElem;/*链式栈中节点的定义*/typedef struct position_stack{SElem p;struct position_stack *next;}*Stack_pNode,Stack_Node;void InitStack(Stack_pNode *Link){*Link = NULL;}void push(Stack_pNode *Link,SElem e){Stack_pNode new_SElem = (Stack_pNode)calloc(1,sizeof(Stack_Node));new_SElem->p = e;new_SElem->next = NULL;if (*Link == NULL)*Link = new_SElem;else{new_SElem->next = *Link;*Link = new_SElem;}}int pop(Stack_pNode *Link,SElem *e){if (*Link == NULL)return 0;*e = (*Link)->p;Stack_pNode q = *Link;*Link = (*Link)->next;free(q);return 1;}int top(Stack_pNode Link, SElem *e){if (Link == NULL)return 0;*e = Link->p;return 1;}int empty(Stack_pNode Link){if (Link == NULL)return 1;elsereturn 0;}int reverse(Stack_pNode *Link){Stack_pNode p, q, r;if (*Link == NULL || (*Link)->next == NULL)return 0;r = *Link;p = (*Link)->next;q = NULL;while (p){r->next = q;q = r;r = p;p = p->next;}r->next = q;*Link = r;}void print(Stack_pNode Link){Stack_pNode r = Link;while (r){printf("(%d,%d) -> ",r->p.seat.x,r->p.seat.y);r = r->next;}printf("exit\n");}int curstep = 1;/*纪录当前的⾜迹,填写在探索前进的每⼀步正确的路上*//*迷宫地图。
c语言~走迷宫
![c语言~走迷宫](https://img.taocdn.com/s3/m/3f50910576c66137ee0619a8.png)
本程序代码为C语言解决数据结构(严蔚敏)中关于迷宫的问题。
程序不仅实现迷宫路径查找,还实现文字描述路径功能可以直接粘贴到vc6.0中运行【代码如下】# include <stdio.h> # include <malloc.h> # define null 0typedef struct{int (*base)[2];int (*top)[2];int listlen;}sqlist;int topelem[2]; //栈顶元素void creatstack(sqlist *mazepath); //创建一个存储路径的栈void creatmap(int (*mazemap)[10]); //创建迷宫图纸void printmap(int (*mazemap)[10]);void footprint(int x,int y,int k,int (*mazemap)[10]);int position(int x,int y); //判断是否到终点int passroad(int x,int y,int (*mazemap)[10]);void findpath(int (*mazemap)[10],sqlist *mazepath); //在mazemap当中寻找mazepahtvoid printpath(sqlist *mazepath);void roadinwords(sqlist *mazepath); //文字叙述如何走迷宫void push(int x,int y,sqlist *mazepath); //栈操作void pop(sqlist *mazepath);void gettop(sqlist *mazepath);void main(){sqlist mazepath;creatstack(&mazepath); //创建一个存储路径的栈int mazemap[10][10]={1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,0,1,0,1,1,0,0,1,0,0,0,1,0,1,1,0,0,0,0,1,1,0,0,1,1,0,1,1,1,0,0,0,0,1,1,0,0,0,1,0,0,0,0,1,1,0,1,0,0,0,1,0,0,1,1,0,1,1,1,0,1,1,0,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1};// creatmap(mazemap); //创建迷宫图纸printf("迷宫原图为:\n");printmap(mazemap);findpath(mazemap,&mazepath); //在mazemap当中寻找mazepaht printf("走出迷宫图纸为:\n");printmap(mazemap);printf("走出迷宫文字叙述为:\n");roadinwords(&mazepath);// printpath(&mazepath);}void findpath(int (*mazemap)[10],sqlist *mazepath){int x,y,flag=0,k=0,next; //位置是否可通,flag=0通,1墙,2通但不可走x=1;y=1; //获取初始位置push(x,y,mazepath); //起点位置进栈footprint(x,y,6,mazemap);while(flag==0 && k!=162) //flag==1到达终点,0未到达终点{if(passroad(x,y+1,mazemap)==0)push(x,y+1,mazepath),y=y+1,footprint(x,y,6,mazemap);else if(passroad(x+1,y,mazemap)==0)push(x+1,y,mazepath),x=x+1,footprint(x,y,6,mazemap);else if(passroad(x,y-1,mazemap)==0)push(x,y-1,mazepath),y=y-1,footprint(x,y,6,mazemap);else if(passroad(x-1,y,mazemap)==0)push(x-1,y,mazepath),x=x-1,footprint(x,y,6,mazemap);elsefootprint(x,y,2,mazemap),pop(mazepath),gettop(mazepath),x=topelem[0],y= topelem[1];// printmap(mazemap);k++;flag=position(x,y); //判断是否到达终点// printf("flag==%d\n",flag);}}void creatstack(sqlist *mazepath){mazepath->base=(int (*)[2])malloc(120*sizeof(int (*)[2]));mazepath->top=mazepath->base;mazepath->listlen=120;}void push(int x,int y,sqlist *mazepath){**(mazepath->top)=x;*(*(mazepath->top)+1)=y;mazepath->top++;}void pop(sqlist *mazepath){if(mazepath->top!=mazepath->base)mazepath->top--;}void printmap(int (*mazemap)[10]){int (*p)[10];p=mazemap;int i,j;printf(" \n\n\n");for(i=0;i<10;i++){for(j=0;j<10;j++){if(j==0)printf(" ");if(*(*(p+i)+j)==0)printf("▇");else if(*(*(p+i)+j)==1)printf("□");else if(*(*(p+i)+j)==6)printf("★");elseprintf("▇");if(j==9)printf("\n");}}printf("\n\n");}void printpath(sqlist *mazepath){int (*p)[2];p=mazepath->base;while(p!=mazepath->top){printf("x=%d,y=%d\n",**p,*(*p+1));p++;}}void gettop(sqlist *mazepath){int (*p)[2];int (*q)[2];p=mazepath->base;while(p!=mazepath->top){q=p;p++;}topelem[0]=**q;topelem[1]=*(*q+1);}void footprint(int x,int y,int k,int (*mazemap)[10]){if(x<10 && y<10)*(*(mazemap+x)+y)=k;}int position(int x,int y){int flag;if(x==8 && y==8)flag=1;elseflag=0;return(flag);}int passroad(int x,int y,int (*mazemap)[10]) {int num=1;if(x<10 && y<10)num=*(*(mazemap+x)+y);return(num);}void roadinwords(sqlist *mazepath){int x=1,y=1,i=0;int (*p)[2];p=mazepath->base;p++;while(p!=mazepath->top){if(x==**p && y+1==*(*p+1))printf("向右走→→"),x=**p,y=*(*p+1);else if(x+1==**p && y==*(*p+1))printf("向下走→→"),x=**p,y=*(*p+1);else if(x==**p && y-1==*(*p+1))printf("向左走→→"),x=**p,y=*(*p+1);else if(x-1==**p && y==*(*p+1))printf("向上走→→"),x=**p,y=*(*p+1);i++;if(i%3==0)printf("\n");p++;}printf("\n");}。
C语言递归实现迷宫寻路问题
![C语言递归实现迷宫寻路问题](https://img.taocdn.com/s3/m/23ae0e9885868762caaedd3383c4bb4cf7ecb7b6.png)
C语⾔递归实现迷宫寻路问题迷宫问题采⽤递归和⾮递归两种⽅法,暂时完成递归⽅法,后续会补上⾮递归⽅法#include<stdio.h>#include<stdbool.h>bool findPath(int a[][8],int i,int j){//递归找出⼝if(i==6&&j==6)//如果找到了⽬标a[6][6]则返回truereturn true;if(a[i][j]==0)//若当前路径未被找到,则继续{a[i][j]=2;//当前⾛的路径置为2,表⽰⾛过if(findPath(a,i+1,j)||findPath(a,i,j+1)||findPath(a,i-1, j)||findPath(a,i-1,j))//每个⽅向都判断,依次展开递归,寻找最佳路径return true;//若选择的路径可以⾛,则返回trueelse{//若当前选择的路径不能⾛a[i][j]=0;//弹栈并恢复路径,回退到上⼀次的位置return false;}}else//未能找到最终点return false;}void print(int a[][8])//打印当前的⼆维数组表{for(int i=0;i<8;i++){for(int j=0;j<8;j++){printf("%d ",a[i][j]);}printf("\n");}}int main(){int a[8][8]={0};for(int i=0;i<8;i++)//设置围墙和障碍物{a[0][i]=1;a[i][0]=1;a[7][i]=1;a[i][7]=1;}a[3][1]=1;a[3][2]=1;print(a);printf("-----------after find path-----------\n");findPath(a, 1, 1);print(a);}。
C语言实验:迷宫问题(搜索,C语言实现栈、队列)
![C语言实验:迷宫问题(搜索,C语言实现栈、队列)](https://img.taocdn.com/s3/m/edb83d1302d8ce2f0066f5335a8102d276a26113.png)
C语⾔实验:迷宫问题(搜索,C语⾔实现栈、队列)Description给定迷宫起点和终点,寻找⼀条从起点到终点的路径。
(0,1)(2,0)起点(1,1)(1,2)(1,3)(1,4)(2,0)(2,1)(2,4)(3,0)(3,1)(3,2)终点(3,4)(4,1)上图中黄⾊代表墙,⽩⾊代表通路,起点为(1,1),终点为(3,4)。
要求搜寻策略是从起点开始按照“上、下、左、右”四个⽅向寻找终点,到下⼀个点继续按照“上、下、左、右”四个⽅⾯寻找,当该结点四个⽅向都搜寻完,但还没到终点时,退回到上⼀个点,直到找到终点或者没有路径。
⽐如上图从(1,1)开始,向上(0,1)不通,向下到(2,1);到了(2,1)后继续按“上、下、左、右”四个⽅⾯寻找,上已经⾛过,向下到(3,1);到(3,1)后上已经⾛过,下和左不通,向右到(3,2);到(3,2)四个⽅⾯都不通,回到(3,1)四个⽅向都不通,再回到(2,1),(1,1);到达(1,1)后下已经⾛过,左不通,继续向右⾛,重复这个过程最后到达(3,4)。
Input第⼀⾏两个数m和n表⽰迷宫的⾏数和列数。
迷宫⼤⼩不超过100×100第⼆⾏四个数x1,y1,x2,y2分别表⽰起点和终点的坐标。
接下来是m⾏n列的数,⽤来表⽰迷宫,1表⽰墙,0表⽰通路。
Output从起点到终点所经过的路径的坐标。
如果不存在这样的路径则输出“No Path!”。
Sample Input5 61 1 3 41 1 1 1 1 11 0 0 0 0 11 0 1 1 0 11 0 0 1 0 11 1 1 1 1 1Sample Output(1 1)(1 2)(1 3)(1 4)(2 4)(3 4)1.思路:(1)若当前点是终点,dfs函数返回1;(2)若不是终点,将此点标记为1,对该点4个⽅向进⾏搜索,实现⽅式为定义int dir[4][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} }; 通过⼀个⼩循环: for(int i = 0; i < 4; i++) { position nextp; nextp.x = dir[i][0] + now.x;nextp.y = dir[i][1] + now.y;...... } 进⾏搜索;若该点的下⼀个点nextp不是墙,未⾛,并且没有超界则将nextp压⼊栈中,递归调⽤dfs,若此过程经过(1)判断返回了1,说明最终找到了通往终点的路,便可以返回1,结束函数,此时栈中已储存了通往终点的路径,若没有通路,则弹出栈顶元素,根据递归原理该路径上的所有点都会弹出并标记未⾛,回溯到之前的点,继续向其他⽅向搜索,直到找到终点或遍历完整个图。
求解迷宫问题 (c语言
![求解迷宫问题 (c语言](https://img.taocdn.com/s3/m/2cd7e49faaea998fcc220ecd.png)
求迷宫问题就是求出从入口到出口的路径。
在求解时,通常用的是“穷举求解”的方法,即从入口出发,顺某一方向向前试探,若能走通,则继续往前走;否则沿原路退回,换一个方向再继续试探,直至所有可能的通路都试探完为止。
为了保证在任何位置上都能沿原路退回(称为回溯),需要用一个后进先出的栈来保存从入口到当前位置的路径。
首先用如图3.3所示的方块图表示迷宫。
对于图中的每个方块,用空白表示通道,用阴影表示墙。
所求路径必须是简单路径,即在求得的路径上不能重复出现同一通道块。
为了表示迷宫,设置一个数组mg,其中每个元素表示一个方块的状态,为0时表示对应方块是通道,为1时表示对应方块为墙,如图3.3所示的迷宫,对应的迷宫数组mg如下:int mg[M+1][N+1]={ /*M=10,N=10*/{1,1,1,1,1,1,1,1,1,1},{1,0,0,1,0,0,0,1,0,1},{1,0,0,1,0,0,0,1,0,1},/ 1{1,0,0,0,0,1,1,0,0,1}, {1,0,1,1,1,0,0,0,0,1}, {1,0,0,0,1,0,0,0,0,1}, {1,0,1,0,0,0,1,0,0,1}, {1,0,1,1,1,0,1,1,0,1}, {1,1,0,0,0,0,0,0,0,1}, {1,1,1,1,1,1,1,1,1,1} }; 伪代码:c语言描述如下:6/ 2void mgpath() /*路径为:(1,1)->(M-2,N-2)*/{int i,j,di,find,k;top++; /*初始方块进栈*/Stack[top].i=1;Stack[top].j=1;Stack[top].di=-1;mg[1][1]=-1;while (top>-1) /*栈不空时循环*/{i=Stack[top].i;j=Stack[top].j;di=Stack[top].di;if (i==M-2 && j==N-2) /*找到了出口,输出路径*/ {瀠楲瑮?迷宫路径如下:\n);for (k=0;k<=top;k++){printf(\ (%d,%d),Stack[k].i,Stack[k].j); if ((k+1)%5==0) printf(\);}6/ 3printf(\);return;}find=0;while (di<4 && find==0) /*找下一个可走方块*/ { di++;switch(di){case 0:i=Stack[top].i-1;j=Stack[top].j;break;case 1:i=Stack[top].i;j=Stack[top].j+1;break;case 2:i=Stack[top].i+1;j=Stack[top].j;break;case 3:i=Stack[top].i;j=Stack[top].j-1;break;}6/ 4if (mg[i][j]==0) find=1;}if (find==1) /*找到了下一个可走方块*/{Stack[top].di=di; /*修改原栈顶元素的di值*/ top++; /*下一个可走方块进栈*/Stack[top].i=i;Stack[top].j=j;Stack[top].di=-1;mg[i][j]=-1; /*避免重复走到该方块*/}else /*没有路径可走,则退栈*/{ mg[Stack[top].i][Stack[top].j]=0;/*让该位置变为其他路径可走方块*/top--;}}牰湩晴尨没有可走路径!\n);}6/ 5(范文素材和资料部分来自网络,供参考。
c语言实现迷宫问题
![c语言实现迷宫问题](https://img.taocdn.com/s3/m/685b70b37fd5360cbb1adbb8.png)
数据结构试验迷宫冋题(一)基本问题1•问题描述这是心理学中的一个经典问题。
心理学家把一只老鼠从一个无顶盖的大盒子的入口处放入,让老鼠自行找到出口出来。
迷宫中设置很多障碍阻止老鼠前行,迷宫唯一的出口处放有一块奶酪,吸引老鼠找到出口。
简而言之,迷宫问题是解决从布置了许多障碍的通道中寻找出路的问题。
本题设置的迷宫如图1所示。
入口迷宫四周设为墙;无填充处,为可通处。
设每个点有四个可通方向,分别为东、南、西、北(为了清晰,以下称"上下左右”)。
左上角为入口。
右下角为出口。
迷宫有一个入口,一个出口。
设计程序求解迷宫的一条通路。
2.数据结构设计以一个n的数组mg表示迷宫,每个元素表示一个方块状态,数组元素0和1分别表示迷宫中的通路和障碍。
迷宫四周为墙,对应的迷宫数组的边界元素均为1。
根据题目中的数据,设置一个数组mg如下int mg[M+2][N+2]={{1,1,1,1,1,1,1,1},{1,0,0,1,0,0,0,1}, {1,1,0,0,0,1,1,1},{1,0,0,1,0,0,0,1},{1,0,0,0,0,0,0,1}, {1,1,1,1,1,1,1,1}};在算法中用到的栈采用顺序存储结构,将栈定义为Struct{ int i; // 当前方块的行号int j; // 当前方块的列号int di; //di 是下一个相邻的可走的方位号}st[MaxSize];〃定义栈int top=-1 // 初始化栈3设计运算算法要寻找一条通过迷宫的路径,就必须进行试探性搜索,只要有路可走就前进一步,无路可进,换一个方向进行尝试;当所有方向均不可走时,则沿原路退回 一步(称为回溯),重新选择未走过可走的路,如此继续,直至到达出口或返回 入口(没有通路)。
在探索前进路径时,需要将搜索的踪迹记录下来,以便走不 通时,可沿原路返回到前一个点换一个方向再进行新的探索。
后退的尝试路径与 前进路径正好相反,因此可以借用一个栈来记录前进路径。
求解迷宫问题(c语言,很详细哦)
![求解迷宫问题(c语言,很详细哦)](https://img.taocdn.com/s3/m/e2b4f267a1c7aa00b42acb71.png)
求迷宫问题就是求出从入口到出口的路径。
在求解时,通常用的是“穷举求解”的方法,即从入口出发,顺某一方向向前试探,若能走通,则继续往前走;否则沿原路退回,换一个方向再继续试探,直至所有可能的通路都试探完为止。
为了保证在任何位置上都能沿原路退回(称为回溯),需要用一个后进先出的栈来保存从入口到当前位置的路径。
首先用如图所示的方块图表示迷宫。
对于图中的每个方块,用空白表示通道,用阴影表示墙。
所求路径必须是简单路径,即在求得的路径上不能重复出现同一通道块。
为了表示迷宫,设置一个数组mg,其中每个元素表示一个方块的状态,为0时表示对应方块是通道,为1时表示对应方块为墙,如图所示的迷宫,对应的迷宫数组mg如下:int mg[M+1][N+1]={ /*M=10,N=10*/{1,1,1,1,1,1,1,1,1,1},{1,0,0,1,0,0,0,1,0,1}, {1,0,0,1,0,0,0,1,0,1}, {1,0,0,0,0,1,1,0,0,1}, {1,0,1,1,1,0,0,0,0,1}, {1,0,0,0,1,0,0,0,0,1}, {1,0,1,0,0,0,1,0,0,1}, {1,0,1,1,1,0,1,1,0,1}, {1,1,0,0,0,0,0,0,0,1}, {1,1,1,1,1,1,1,1,1,1} }; 伪代码:c语言描述如下:void mgpath() /*路径为:(1,1)->(M-2,N-2)*/ {int i,j,di,find,k;top++; /*初始方块进栈*/Stack[top].i=1;Stack[top].j=1;Stack[top].di=-1;mg[1][1]=-1;while (top>-1) /*栈不空时循环*/{i=Stack[top].i;j=Stack[top].j;di=Stack[top].di;if (i==M-2 && j==N-2) /*找到了出口,输出路径*/{printf("迷宫路径如下:\n");for (k=0;k<=top;k++){printf("\t(%d,%d)",Stack[k].i,Stack[ k].j);if ((k+1)%5==0) printf("\n");}printf("\n");return;}find=0;while (di<4 && find==0) /*找下一个可走方块*/{ di++;switch(di){case 0:i=Stack[top].i-1;j=Stack[top].j ;break;case 1:i=Stack[top].i;j=Stack[top].j +1;break;case 2:i=Stack[top].i+1;j=Stack[top].j ;break;case 3:i=Stack[top].i;j=Stack[top] .j-1;break;}if (mg[i][j]==0) find=1;}if (find==1) /*找到了下一个可走方块*/{Stack[top].di=di; /*修改原栈顶元素的di值*/top++; /*下一个可走方块进栈*/Stack[top].i=i ;Stack[top].j=j ;Stack[top].di= -1;mg[i][j]=-1; /*避免重复走到该方块*/ }else /*没有路径可走,则退栈*/{ mg[Stack[top].i][Stack[top].j]=0;/*让该位置变为其他路径可走方块*/top--;}}printf("没有可走路径!\n");}。
c语言迷宫问题代码实现
![c语言迷宫问题代码实现](https://img.taocdn.com/s3/m/b8f2fb14c5da50e2524d7faa.png)
structStackList
{
SEAT stack[MAXSIZE];
inttop;
}*Stack;
intEmptyStack(StackList*Stack)//判断是否为空栈
{
if(Stack->top==0)
return 0;
else
return 1;
}
intMove[4][2]={{0,1},{1,0},{0,-1},{-1,0}};//分别表示向东、西、南、北需要加上的坐标
CurSeat=temp;
find =1;
}
}
}
}
}while(EmptyStack(Stack));
return false;
}
voidPrintStack(StackList*Stack)//输出路线
{
if(Stack->top==0)
printf("There is no route can be out of the maze\n");
Mark(CurSeat);
if(CurSeat.x==end.x+1&&CurSeat.y==end.y+1)//如果找到出口,返回
{
return true;
}
else
{
intfind=0;
while(CurSeat.di<3&&find==0)//找下一个结点的方向
{
CurSeat.di++;
SEAT temp;
scanf("%d",&n);
printf("Please enter the labyrinth of the coordinates of the wall unit(0<=row,column):\n");
c语言走迷宫代码
![c语言走迷宫代码](https://img.taocdn.com/s3/m/14ba5a5c571252d380eb6294dd88d0d233d43cdb.png)
c语言走迷宫代码以下是一个简单的 C 语言走迷宫代码示例,使用了递归算法: ```c#include <stdio.h>#include <stdlib.h>int main() {int size, row, col, choice, i, j;maze[0][0] = "*";maze[1][0] = "O";maze[0][1] = "O";maze[1][1] = "*";size = 2;row = 2;col = 2;while (1) {printf("Enter row: ");scanf("%d", &row);printf("Enter col: ");scanf("%d", &col);if (row < 0 || row > size || col < 0 || col > size) { printf("Invalid row or col. Try again.");}if (maze[row][col] != "*") {printf("Current cell is free. Try again. ");continue;}maze[row][col] = "X";printf("Enter a choice (1-6): ");scanf("%d", &choice);switch (choice) {case 1:row++;col = 0;break;case 2:row--;col = 0;break;case 3:col++;break;col--;break;case 5:row--;col = 1;break;case 6:row++;col = 1;break;default:printf("Invalid choice. Try again. ");continue;}}printf(" maze: ");for (i = 0; i < size * size; i++) { for (j = 0; j < size; j++) {if (maze[i][j] == "*")printf("*");elseprintf("%c", maze[i][j]);}printf("");}return 0;}```该程序首先初始化了一个 2x2 的迷宫,其中 `maze[0][0]` 和`maze[1][0]` 分别标记为 `"O"` 和 `"*"`,其他地方都为空。
基于栈的C语言迷宫问题与实现
![基于栈的C语言迷宫问题与实现](https://img.taocdn.com/s3/m/a440ffe2a32d7375a5178030.png)
数据结构与算法实验报告基于栈的C语言迷宫问题与实现一.问题描述多年以来,迷宫问题一直是令人感兴趣的题目。
实验心理学家训练老鼠在迷宫中寻找食物。
许多神秘主义小说家也曾经把英国乡村花园迷宫作为谋杀现场。
于是,老鼠过迷宫问题就此产生,这是一个很有趣的计算机问题,主要利用“栈”是老鼠通过尝试的办法从入口穿过迷宫走到出口。
迷宫只有两个门,一个叫做入口,另一个叫做出口。
把一只老鼠从一个无顶盖的大盒子的入口处赶进迷宫。
迷宫中设置很多隔壁,对前进方向形成了多处障碍,在迷宫的唯一出口处放置了一块奶酪,吸引老鼠在迷宫中寻找通路以到达出口。
求解迷宫问题,即找出从入口到出口的路径。
一个迷宫可用上图所示方阵[m,n]表示,0表示能通过,1 表示不能通过。
现假设耗子从左上角[1,1]进入迷宫,编写算法,寻求一条从右下角[m,n] 出去的路径。
下图是一个迷宫的示意图:迷宫示意图二.算法基本思想迷宫求解问题是栈的一个典型应用。
基本算法思想是:在某个点上,按照一定的顺序(在本程序中顺序为上、右、下、左)对周围的墙、路进行判断(在本程序中分别用1、0)代替,若周围某个位置为0,则移动到该点上,再进行下一次判断;若周围的位置都为1(即没有通路),则一步步原路返回并判断有无其他通路,然后再次进行相同的判断,直到走到终点为止,或者确认没有任何通路后终止程序。
要实现上述算法,需要用到栈的思想。
栈里面压的是走过的路径,若遇到死路,则将该位置(在栈的顶层)弹出,再进行下一次判断;若遇到通路,则将该位置压栈并进行下一次判断。
如此反复循环,直到程序结束。
此时,若迷宫有通路,则栈中存储的是迷宫通路坐标的倒序排列,再把所有坐标顺序打印后,即可得到正确的迷宫通路。
三.程序具体部分的说明1.迷宫的生成根据题目的要求,迷宫的大小是自定义输入的。
所以在程序中用malloc申请动态二维数组。
数组中的元素为随机生成的0、1。
数组周围一圈的元素全部定义为1,以表示边界。
C语言解决迷宫求解问题
![C语言解决迷宫求解问题](https://img.taocdn.com/s3/m/18655442b307e87101f69649.png)
迷宫求解
任务:
可以输入一个任意大小的迷宫数据,用非递归的方法求出一条走出迷宫的路
径,并将路径输出。
#include<iostream>
//获取栈顶元素
if(!(p.GetPop().x==q.GetPop().x&&p.GetPop().y==q.GetPop().y))
p.Push(Temp2);
//如果有新位置入栈,则把上一个探索的位置存入栈 p
for(loop=0;loop<4;loop++) //探索当前位置的 4 个相邻位置
//使栈顶元素出栈
T GetPop();
//取出栈顶元素
void Clear();
//把栈清空
bool empty();
//判断栈是否为空,如果为空则返回 1,否则返回 0
};
Stack::Stack()
//构造函数,置空栈
{
top=NULL;
}
Stack::~Stack()
//析构函数
{
}
void Stack::Push(T e)
//输出路径
{
cout<<"迷宫的路径为\n";
cout<<"括号内的内容分别表示为(行坐标,列坐标,数字化方向,方向)\n";
Stack t;
//定义一个栈,按从入口到出口存取路径
int a,b;
T data;
迷宫(direction)C语言代码
![迷宫(direction)C语言代码](https://img.taocdn.com/s3/m/fceee25bcf84b9d529ea7a03.png)
};
mazePath(maze,direction,1,1,6,9);
getchar();
return 0;
}
#include<stdio.h>
#include<conio.h>
intmigong[10][10]= //设置迷宫,最外围1为墙 里边0为可走路径 1为障碍
voidpush_seq(PSeqStackpastack,DataTypex ) {
if(pastack->t >= MAXNUM - 1 )
printf( "Overflow! \n" );
else {
pastack->t++;
pastack->s[pastack->t] = x;
}
}
/* 删除栈顶元素 */
element =top_seq(st);
pop_seq(st);
i=element.x; j =element.y;
for (k =element.d+ 1; k <= 3; k++) { /* 依次试探每个方向 */
g =i+ direction[k][0];h = j + direction[k][1];
lj[top].x=1;
lj[top].y=1;
migong[1][1]=-1;
find=0;d=-1;
while(top>-1){
if(lj[top].x==8&&lj[top].y==8)
{
printf("迷宫路径如下:\n");
c语言迷宫代码
![c语言迷宫代码](https://img.taocdn.com/s3/m/d8e0e38cfc0a79563c1ec5da50e2524de518d00b.png)
c语言迷宫代码C语言迷宫代码是指用C语言编写的程序,用于生成和解决迷宫问题的算法。
迷宫通常由一个矩形网格组成,其中包含墙壁和通道。
目标是找到从迷宫的起点到终点的路径,同时避开墙壁。
下面是一个简单的示例代码,用于生成迷宫:```c#include <stdio.h>#include <stdlib.h>#include <stdbool.h>#define ROWS 10#define COLS 10typedef struct {int x;int y;} Point;void generateMaze(int maze[ROWS][COLS]) {for (int i = 0; i < ROWS; i++) {for (int j = 0; j < COLS; j++) {if (i % 2 == 0 || j % 2 == 0) { maze[i][j] = 1; // 墙壁} else {maze[i][j] = 0; // 通道}}}}void printMaze(int maze[ROWS][COLS]) {for (int i = 0; i < ROWS; i++) {for (int j = 0; j < COLS; j++) {printf('%d ', maze[i][j]);}printf('');}}int main() {int maze[ROWS][COLS];generateMaze(maze);printMaze(maze);return 0;}```在上面的代码中,我们使用一个二维数组来表示迷宫。
数组中的值为1表示墙壁,值为0表示通道。
使用generateMaze函数,我们将迷宫的墙壁和通道初始化为适当的值。
然后使用printMaze函数打印迷宫。
通过运行上面的代码,我们可以得到一个简单的迷宫的表示:```1 1 1 1 1 1 1 1 1 11 0 1 0 1 0 1 0 1 11 1 1 1 1 1 1 1 1 11 0 1 0 1 0 1 0 1 11 1 1 1 1 1 1 1 1 11 0 1 0 1 0 1 0 1 11 1 1 1 1 1 1 1 1 11 0 1 0 1 0 1 0 1 11 1 1 1 1 1 1 1 1 11 0 1 0 1 0 1 0 1 1```当然,上述代码只是生成了一个简单的迷宫,还没有解决迷宫问题。
(完整word版)c语言迷宫最完整做法
![(完整word版)c语言迷宫最完整做法](https://img.taocdn.com/s3/m/fb428fd72f60ddccdb38a00d.png)
#include〈stdio。
h〉#include〈stdlib。
h>#include〈time.h>#define stack_init_size 200#define stack_increment 10#define ERROE 0#define TRUE 1#define FALSE 0#define OVERFLOW 0#define OK 1typedef int Status;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;int mg[20][20];/*随机生成迷宫的函数/*为了能够让尽量能通过,将能通过的块和不能通过的块数量比大致为2:1*/void Random(){int i,j,k;srand(time(NULL));mg[1][0]=mg[1][1]=mg[18][19]=0; //将入口、出口设置为“0"即可通过for(j=0;j〈20;j++)mg[0][j]=mg[19][j]=1;/*设置迷宫外围“不可走”,保证只有一个出口和入口*/ for(i=2;i〈19;i++)mg[i][0]=mg[i—1][19]=1; /*设置迷宫外围“不可走”,保证只有一个出口和入口*/ for(i=1;i〈19;i++)for(j=1;j<19;j++){k=rand()%3; //随机生成0、1、2三个数if(k)mg[i][j]=0;else{if((i==1&&j==1)||(i==18&&j==18)) /*因为距入口或出口一步的路是必经之路,故设该通道块为“0”加大迷宫能通行的概率*/mg[i][j]=0;elsemg[i][j]=1;}}}//构造一个空栈Status InitStack(SqStack &s){s。
用c语言实现迷宫求解完美源代码
![用c语言实现迷宫求解完美源代码](https://img.taocdn.com/s3/m/b87bba2b7dd184254b35eefdc8d376eeaeaa17c3.png)
用c语言实现迷宫求解完美源代码#include#include#include#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define OVERFLOW -2#define UNDERFLOW -2typedef int Status;//-----栈开始-----typedef struct{//迷宫中r行c列的位置int r;int c;}PostType;//坐标位置类型typedef struct{int ord;// 当前位置在路径上的序号PostType seat;// 当前坐标int di;// 从此通块走向下一通块的“方向”}SElemType;// 栈的元素类型//定义链式栈的存储结构struct LNode{SElemType data;//数据域struct LNode *next;//指针域};struct LStack{struct LNode *top;//栈顶指针};Status InitStack(LStack &s)//操作结果:构造一个空栈S {struct LNode *p;p=(LNode *)malloc(sizeof(LNode));if(!p){printf("分配失败,退出程序");exit(ERROR);}s.top=p;p->next=NULL;return OK;}Status StackEmpty(LStack s)//若栈s为空栈,则返回TRUE,否则FALSE{if(s.top->next==NULL) return TRUE;return FALSE;}Status Push(LStack &s,SElemType e)//插入元素e成为新的栈顶元素{struct LNode *p;p=(LNode *)malloc(sizeof(LNode));if(!p) exit(OVERFLOW);s.top->data=e;p->next=s.top;s.top=p;return OK;}Status Pop(LStack &s,SElemType &e)//删除s的栈顶元素,并且用e返回其值{struct LNode *p;if(!(s.top->next)) exit(UNDERFLOW);p=s.top;s.top=p->next;e=s.top->data;free(p);return OK;}Status DestroyStack(LStack &s)//操作结果:栈s被销毁{struct LNode *p;p=s.top;while(p){s.top=p->next;free(p);p=s.top;}return OK;}//-----栈结束------//-----迷宫开始-------#define MAXLEN 10// 迷宫包括外墙最大行列数typedef struct{int r;int c;char adr[MAXLEN][MAXLEN];// 可取' ''*' '@' '#'}MazeType;// 迷宫类型Status InitMaze(MazeType&maze){// 初始化迷宫,成功返回TRUE,否则返回FALSE int m,n,i,j;printf("输入迷宫行数和列数(包括了外墙): ");scanf("%d%d",&maze.r,&maze.c); // 输入迷宫行数和列数for(i=0;i<=maze.c+1;i++){// 迷宫行外墙maze.adr[0][i]='#';maze.adr[maze.r+1][i]='#';}//forfor(i=0;i<=maze.r+1;i++){// 迷宫列外墙maze.adr[i][0]='#';maze.adr[i][maze.c+1]='#';}for(i=1;i<=maze.r;i++)for(j=1;j<=maze.c;j++)maze.adr[i][j]=' ';// 初始化迷宫printf("输入障碍的坐标((-1 -1)结束): ");scanf("%d%d",&m,&n);// 接收障碍的坐标while(m!=-1){if(m>maze.r || n>maze.c)// 越界exit(ERROR);maze.adr[m][n]='#';// 迷宫障碍用#标记printf("输入障碍的坐标((-1,-1)结束): ");scanf("%d%d",&m,&n);}//whilereturn OK;}//InitMazeStatus Pass(MazeType maze,PostType curpos){// 当前位置可同则返回TURE,否则返回FALSEif(maze.adr[curpos.r][curpos.c]==' ')// 可通return TRUE;elsereturn FALSE;}//PassStatus FootPrint(MazeType &maze,PostType curpos) {// 若走过并且可通,则返回TRUE,否则返回FALSE maze.adr[curpos.r][curpos.c]='*';//"*"表示可通return OK;}//FootPrintPostType NextPos(PostType &curpos,int i){// 指示并返回下一位置的坐标PostType cpos;cpos=curpos;switch(i){//1.2.3.4 分别表示东南西北方向case 1 : cpos.c+=1; break;case 2 : cpos.r+=1; break;case 3 : cpos.c-=1; break;case 4 : cpos.r-=1; break;default: exit(ERROR);}return cpos;}//NextposStatus MarkPrint(MazeType &maze,PostType curpos) {// 曾走过,但不是通路标记,并返回OKmaze.adr[curpos.r][curpos.c]='@';//"@" 表示曾走过但不通return OK;}//MarkPrintStatus MazePath(MazeType &maze,PostType start,PostType end){// 若迷宫maze存在通路,则求出一条同路放在栈中,并返回TRUE,否则返回FALSE struct LStack S;PostType curpos;int curstep;// 当前序号,1,2,3,4分别表示东南西北方向SElemType e;InitStack(S);curpos=start; //设置"当前位置"为"入口位置"curstep=1;// 探索第一位printf("以三元组形式表示迷宫路径:\n");do{if(Pass(maze,curpos)){// 当前位置可以通过FootPrint(maze,curpos);// 留下足迹e.ord=curstep;e.seat=curpos;e.di=1;printf("%d %d %d-->",e.seat.r,e.seat.c,e.di);Push(S,e);// 加入路径if(curpos.r==end.r&&curpos.c==end.c)if(!DestroyStack(S))// 销毁失败exit(OVERFLOW);elsereturn TRUE; // 到达出口else{curpos=NextPos(curpos,1);// 下一位置是当前位置的东邻curstep++;// 探索下一步}//else}//ifelse{// 当前位置不通时if(!StackEmpty(S)){Pop(S,e);while(e.di==4&& !StackEmpty(S)){MarkPrint(maze,e.seat);Pop(S,e);// 留下不能通过的标记,并退一步}//whileif(e.di < 4){e.di++;// 换一个方向探索Push(S,e);curpos=NextPos(e.seat,e.di);// 设定当前位置是该方向上的相邻printf("%d %d %d-->",e.seat.r,e.seat.c,e.di);}//if}//if}//else}while(!StackEmpty(S));if(!DestroyStack(S))// 销毁栈exit(OVERFLOW);elsereturn FALSE;}//MazePathvoid PrintMaze(MazeType &maze){// 将标记路径信息的迷宫输出到终端int i,j;printf("\n输出迷宫(*表示通路):\n\n");printf("");for(i=0;i<=maze.r+1;i++)// 打印列数名printf("%4d",i);printf("\n\n");for(i=0;i<=maze.r+1;i++){printf("%2d",i);// 打印行名for(j=0;j<=maze.c+1;j++)printf("%4c",maze.adr[i][j]);// 输出迷宫当前位置的标记printf("\n\n");}}//PrintMazeint main(){// 主函数MazeType maze;PostType start,end;char cmd;do{printf("-------创建迷宫--------\n");if(!InitMaze(maze)){printf("Initialization errors\n");exit(OVERFLOW);// 初始化失败}do{// 输入迷宫入口坐标printf("\n输入迷宫入口坐标: ");scanf("%d%d",&start.r,&start.c);if(start.r>maze.r ||start.c>maze.c){printf("\nBeyond the maze\n"); continue;}}while(start.r>maze.r ||start.c>maze.c);do{// 输入迷宫出口坐标printf("\n输入迷宫出口坐标: ");scanf("%d%d",&end.r,&end.c);if(end.r>maze.r ||end.c>maze.c){printf("\nBeyond the maze\n"); continue;}}while(end.r>maze.r ||end.c>maze.c);if(!MazePath(maze,start,end))//迷宫求解printf("\nNo path from entranceto exit!\n"); elsePrintMaze(maze);// 打印路径printf("\n需要继续创建新的迷宫吗?(y/n): "); scanf("%s",&cmd);}while(cmd=='y' || cmd=='Y');}。
应用栈解决迷宫问题的C语言实现
![应用栈解决迷宫问题的C语言实现](https://img.taocdn.com/s3/m/cbaad00c0640be1e650e52ea551810a6f524c8eb.png)
应⽤栈解决迷宫问题的C语⾔实现题⽬来⾃于严蔚敏《数据结构》,参考伪代码实现的程序:1 #include <stdio.h>2 #include <malloc.h>3//记录通道块在迷宫矩阵当中的横、纵坐标4struct Position{5int x;6int y;7 };8//放⼊栈当中的通道块元素9struct SElement {10int ord;//记录此通道块在整个通道当中的次序11 Position p;//记录此通道块在矩阵当中的位置12int di;//记录下⼀次测试这⼀路径的临近路径的位置13 };14//创建栈数据结构15#define STACK_INIT_SIZE 10016#define STACKINCREMENT 1017struct MyStack{18 SElement* base;19 SElement* top;20int stacksize;21 };22//创建⼀个栈如果创建成功则返回1,否则就返回023int InitStack(MyStack* s)24 {25 s->base=(SElement*)malloc(STACK_INIT_SIZE*sizeof(SElement));//为栈分配初始空间26if(!s->base) return0;27 s->top=s->base;//设定为空栈28 s->stacksize=STACK_INIT_SIZE;29return1;30 }31//判断栈是否为空,如果是空的就返回0,否则就返回132int IsStackEmpty(MyStack* s)33 {34if(s->top==s->base) return true;35return false;36 }37//获取栈顶元素,如果栈为空就返回0 否则就返回138int GetTop(MyStack* s,SElement* e)39 {40if(IsStackEmpty(s)) return0;41 e=s->top-1;42return1;43 }44//获取栈的长度,并且通过程序返回45int StackLength(MyStack* s)46 {47return s->top-s->base;48 }49//插⼊元素e为新的栈顶元素,插⼊成功则返回1,否则返回050int Push(MyStack* s,SElement e)51 {52if(s->top-s->base>=STACK_INIT_SIZE)53 {54 s->base=(SElement*)realloc(s->base,(s->stacksize+STACKINCREMENT)*sizeof(SElement));55if(!s->base) return0;56 s->top=s->base+s->stacksize;57 s->stacksize+=STACKINCREMENT;58 }59 *(s->top)=e;60 s->top++;61return1;62 }63//弹出栈顶元素赋值给e弹出成功返回1,弹出失败返回064int Pop(MyStack* s,SElement* e)65 {66if(IsStackEmpty(s)) return0;67 *e=*(s->top-1);68 s->top--;69return1;70 }71//定义墙元素为2 可⾛路径为0 已知路径为curStep 不能够通过的路径为-172#define MazeScale 1073int Maze[MazeScale][MazeScale]={{2,2,2,2,2,2,2,2,2,2},{2,0,0,2,0,0,0,2,0,2},{2,0,0,2,0,0,0,2,0,2},{2,0,0,0,0,2,2,0,0,2},74 {2,0,2,2,2,0,0,0,0,2},{2,0,0,0,2,0,0,0,0,2},{2,0,2,0,0,0,2,0,0,2},{2,0,2,2,2,0,2,2,0,2},{2,2,0,0,0,0,0,0,0,2},{2,2,2,2,2,2,2,2,2,2}}; 75//辅助函数考察当前路径能否通过76bool Pass(Position posi)77 {78//只有路径所在位置的数字为0的是可以⾛的79if(Maze[posi.x][posi.y]==0)80 {81return true;82 }83return false;84 }85//按顺时针⽅向从东开始寻找矩阵当中某⼀个位置的临近位置86 Position NextPosition(Position now,int direction)87 {88 Position next;89int x=now.x;90int y=now.y;91switch(direction)92 {93//东94case1:{95 next.x=x;96 next.y=y+1;97break;98 }99//南100case2:{101 next.x=x+1;102 next.y=y;103break;104 }105//西106case3:{107 next.x=x;108 next.y=y-1;109break;110 }111//北112case4:113 {114 next.x=x-1;115 next.y=y;116break;117 }118default:break;119 }120return next;121 }122//留下⾜迹123void FootPrint(Position p,int step)124 {125 Maze[p.x][p.y]=step;126 }127//路径不可⾛的话就留下-1的标记128void MarkPrint(Position p)129 {130 Maze[p.x][p.y]=-1;131 }132int main()133 {134//打印出迷宫矩阵135for(int i=0;i<MazeScale;i++)136 {137for(int j=0;j<MazeScale;j++)138 {139 printf("%d ",Maze[i][j]);140 }141 printf("\n");142 }143//迷宫程序主体144 MyStack path;//记录路径的栈145 InitStack(&path);//初始化路径数组146 Position curp;//当前被试位置147//初始化当前位置为矩阵⼊⼝148 curp.x=1;149 curp.y=1;150int curStep=1;//被探索的步数151do152 {153if(Pass(curp))154 {155 FootPrint(curp,curStep);//可⾛就在迷宫⾥⾯留下⾜迹156//创建⼀个栈元素,存储可⾏路径的相关值,将这个元素存储到栈当中157 SElement e;158 e.di=1;//意味着下⼀个被试路块为这⼀个路块的正上⽅的路块159 e.ord=curStep;160 e.p.x=curp.x;161 e.p.y=curp.y;162 Push(&path,e);//将路径块⼊栈163if(curp.x==MazeScale-2 && curp.y==MazeScale-2) break; //如果被压⼊的路径块到了迷宫的终点就退出循环164//找到下⼀个被试块165 curp=NextPosition(curp,1);//找到前⼀个被试块东⾯的路径块作为被试块166 curStep++;//被探索的步数加⼀167 }else//如果当前被试路径不能够通过的话168 {169if(!IsStackEmpty(&path))170 {171 SElement e;172 Pop(&path,&e);173 curStep--;174//将这⼀段所有的周围路径都已经被测试过的路径从栈中清除175while(e.di==4 && !IsStackEmpty(&path)){176 MarkPrint(e.p);177 Pop(&path,&e);178 curStep--;179 }180//如果当前栈顶还有未被测试的路径就测试剩余的周围路径181if(e.di<4)182 {183 curp=NextPosition(e.p,e.di+1);184 e.di++;185 curStep++;186 Push(&path,e);187 }188 }189 }190 }while(!IsStackEmpty(&path));191 printf("\n");192//打印出结果迷宫矩阵193for(int i=0;i<MazeScale;i++)194 {195for(int j=0;j<MazeScale;j++)196 {197 printf("%d ",Maze[i][j]);198 }199 printf("\n");200 }201return0;202 }。
数据结构(C语言)迷宫问题
![数据结构(C语言)迷宫问题](https://img.taocdn.com/s3/m/19561bb2998fcc22bcd10dc9.png)
typedef int Status; //函数的返回值
typedef int DirectiveType; //下一个通道方向
#define RANGE 100 //迷宫大小
//~
2。
//stack.h
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
#define COL 8 //迷宫的列数
typedef struct...{
int m,n;
int arr[RANGE][RANGE];
}MazeType; //迷宫类型
Status InitMaze(MazeType &maze, int a[][COL], int row, int col)...{
#include<stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
//函数结果状态代码
#define TRUE 1
#define FALSE 0
#definBiblioteka OK 1#define ERROR 0
#define INFEASIBLE -1
if(s.top-s.base >= s.stacksize)...{ //栈满,追加存储空间
s.base = (SElemType *)realloc(s.base,(s.stacksize+STACKINCREMENT)*sizeof(SElemType));
if(!s.base) exit(OVERFLOW);
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
c语言实现迷宫问题集团文件版本号:(M928-T898-M248-WU2669-I2896-DQ586-M1988)数据结构试验——迷宫问题(一)基本问题1.问题描述这是心理学中的一个经典问题。
心理学家把一只老鼠从一个无顶盖的大盒子的入口处放入,让老鼠自行找到出口出来。
迷宫中设置很多障碍阻止老鼠前行,迷宫唯一的出口处放有一块奶酪,吸引老鼠找到出口。
简而言之,迷宫问题是解决从布置了许多障碍的通道中寻找出路的问题。
本题设置的迷宫如图1所示。
图1 迷宫示意图迷宫四周设为墙;无填充处,为可通处。
设每个点有四个可通方向,分别为东、南、西、北(为了清晰,以下称“上下左右”)。
左上角为入口。
右下角为出口。
迷宫有一个入口,一个出口。
设计程序求解迷宫的一条通路。
2.数据结构设计以一个m×n的数组mg表示迷宫,每个元素表示一个方块状态,数组元素0和1分别表示迷宫中的通路和障碍。
迷宫四周为墙,对应的迷宫数组的边界元素均为1。
根据题目中的数据,设置一个数组mg如下int mg[M+2][N+2]={{1,1,1,1,1,1,1,1},{1,0,0,1,0,0,0,1},{1,1,0,0,0,1,1,1},{1,0,0,1,0,0,0,1},{1,0,0,0,0,0,0,1},{1,1,1,1,1,1,1,1}};在算法中用到的栈采用顺序存储结构,将栈定义为Struct{ int i; //当前方块的行号int j; //当前方块的列号int di; //di是下一个相邻的可走的方位号}st[MaxSize];// 定义栈int top=-1 //初始化栈3设计运算算法要寻找一条通过迷宫的路径,就必须进行试探性搜索,只要有路可走就前进一步,无路可进,换一个方向进行尝试;当所有方向均不可走时,则沿原路退回一步(称为回溯),重新选择未走过可走的路,如此继续,直至到达出口或返回入口(没有通路)。
在探索前进路径时,需要将搜索的踪迹记录下来,以便走不通时,可沿原路返回到前一个点换一个方向再进行新的探索。
后退的尝试路径与前进路径正好相反,因此可以借用一个栈来记录前进路径。
方向:每一个可通点有4个可尝试的方向,向不同的方向前进时,目的地的坐标不同。
预先把4个方向上的位移存在一个数组中。
如把上、右、下、左(即顺时针方向)依次编号为0、1、2、3.其增量数组move[4]如图3所示。
x ymove[4]0-110121030-1图2数组move[4]方位示意图如下:通路:通路上的每一个点有3个属性:一个横坐标属性i、一个列坐标属性j和一个方向属性di,表示其下一点的位置。
如果约定尝试的顺序为上、右、下、左(即顺时针方向),则每尝试一个方向不通时,di 值增1,当d增至4时,表示此位置一定不是通路上的点,从栈中去除。
在找到出口时,栈中保存的就是一条迷宫通路。
(1)下面介绍求解迷宫(xi,yj)到终点(xe,ye)的路径的函数:先将入口进栈(其初始位置设置为—1),在栈不空时循环——取栈顶方块(不退栈)①若该方块为出口,输出所有的方块即为路径,其代码和相应解释如下:int mgpath(int xi,int yi,int xe,int ye) //求解路径为:(xi,yi)->(xe,ye){struct{int i; //当前方块的行号int j; //当前方块的列号int di; //di是下一可走方位的方位号} st[MaxSize]; //定义栈int top=-1; //初始化栈指针int i,j,k,di,find;top++; //初始方块进栈st[top].i=xi;st[top].j=yi;st[top].di=-1;mg[1][1]=-1;while (top>-1) //栈不空时循环{i=st[top].i;j=st[top].j;di=st[top].di; //取栈顶方块if (i==xe && j==ye) //找到了出口,输出路径{printf("迷宫路径如下:\n");for (k=0;k<=top;k++){printf("\t(%d,%d)",st[k].i,st[k].j);if ((k+1)%5==0) //每输出每5个方块后换一行printf("\n");}printf("\n");return(1); //找到一条路径后返回1}②否则,找下一个可走的相邻方块若不存在这样的路径,说明当前的路径不可能走通,也就是恢复当前方块为0后退栈。
若存在这样的方块,则其方位保存在栈顶元素中,并将这个可走的相邻方块进栈(其初始位置设置为-1)求迷宫回溯过程如图4所示从前一个方块找到相邻可走方块之后,再从当前方块找在、相邻可走方块,若没有这样的方快,说明当前方块不可能是从入口路径到出口路径的一个方块,则从当前方块回溯到前一个方块,继续从前一个方块找可走的方块。
为了保证试探的可走的相邻方块不是已走路径上的方块,如(i,j)已经进栈,在试探(i+1,j)的下一方块时,又试探道(i,j),这样会很悲剧的引起死循环,为此,在一个方块进栈后,将对应的mg数组元素的值改为-1(变为不可走的相邻方块),当退栈时(表示该方块没有相邻的可走方块),将其值恢复0,其算法代码和相应的解释如下:find=0;while (di<4 && find==0) //找下一个可走方块{di++;switch(di){case 0:i=st[top].i-1;j=st[top].j;break;case 1:i=st[top].i;j=st[top].j+1;break;case 2:i=st[top].i+1;j=st[top].j;break;case 3:i=st[top].i,j=st[top].j-1;break;}if (mg[i][j]==0) find=1;//找到下一个可走相邻方块}if (find==1) //找到了下一个可走方块{st[top].di=di; //修改原栈顶元素的di值top++; //下一个可走方块进栈st[top].i=i;st[top].j=j;st[top].di=-1;mg[i][j]=-1; //避免重复走到该方块}else //没有路径可走,则退栈{mg[st[top].i][st[top].j]=0;//让该位置变为其他路径可走方块top--; //将该方块退栈}}return(0); //表示没有可走路径,返回0(2)求解主程序建立主函数调用上面的算法,将mg和st栈指针定义为全局变量void main(){mgpath(1,1,M,N);}3界面设计设计很简单的界面,输出路径4运行结果图5。
基本运行结果(二)8个方向的问题1.设计思想(1)设置一个迷宫节点的数据结构。
(2)建立迷宫图形。
(3)对迷宫进行处理找出一条从入口点到出口点的路径。
(4)输出该路径。
(5)打印通路迷宫图。
图6功能结构图当迷宫采用二维数组表示时,老鼠在迷宫任一时刻的位置可由数组的行列序号i,j来表示。
而从 [i],[j]位置出发可能进行的方向见下图7.如果[i],[j]周围的位置均为0值,则老鼠可以选择这8个位置中的任一个作为它的下一位置。
将这8个方向分别记作:E(东)、SE(东南)、S(南)SW(西南)W(西)、NW(西北)、N(北)和NE(东北)。
但是并非每一个位置都有8个相邻位置。
如果[i],[j]位于边界上,即i=1,或i=m,或j=1,或j=n,则相邻位置可能是3个或5个为了避免检查边界条件,将数组四周围用值为1的边框包围起来,这样二维数组maze应该声明为maze[m+2],[n+2]在迷宫行进时,可能有多个行进方向可选,我们可以规定方向搜索的次序是从东(E)沿顺时针方向进行。
为了简化问题,规定[i],[j]的下一步位置的坐标是[x],[y],并将这8个方位伤的x和y坐标的增量预先放在一个结构数组move[8]中(见图8)。
该数组的每个分量有两个域dx和dy。
例如要向东走,只要在j值上加上dy,就可以得到下一步位置的[x],[y]值为[i],[j+dy]。
于是搜索方向的变化只要令方向值dir从0增至7,便可以从move数组中得到从[i],[j]点出发搜索到的每一个相邻点[x],[y]。
x=i+move[dir].dxy=j+move[dir].dydx dy图7 方向位移图图8向量差图为了防止重走原路,我们规定对已经走过的位置,将原值为0改为-1,这既可以区别该位置是否已经走到过,又可以与边界值1相区别。
当整个搜索过程结束后可以将所有的-1改回到0,从而恢复迷宫原样。
这样计算机走迷宫的方法是:采取一步一步试探的方法。
每一步都从(E)开始,按顺时针对8个方向进行探测,若某个方位上的maze[x],[y]=0,表示可以通行,则走一步;若maze[x],[y]=1,表示此方向不可通行须换方向再试。
直至8个方向都试过,maze[x],[y]均为1,说明此步已无路可走,需退回一步,在上一步的下一个方向重新开始探测。
为此需要设置一个栈,用来记录所走过的位置和方向(i,j,dir)。
当退回一步时,就从栈中退出一个元素,以便在上一个位置的下一个方向上探测,如又找到一个行进方向,则把当前位置和新的方向重新进栈,并走到新的位置。
如果探测到x=m,y=n,则已经到达迷宫的出口,可以停止检测,输出存在栈中的路径;若在某一位置的8个方向上都堵塞,则退回一步,继续探测,如果已经退到迷宫的入口(栈中无元素),则表示此迷宫无路径可通行。
2系统算法(伪代码描述):(1)建立迷宫节点的结构类型stack[]。
(2)入迷宫图形 0表示可以通 1表示不可以通。
用二维数组maze[m+2][n+2]进行存储。
数组四周用1表示墙壁,其中入口点(1,1)与出口点(m,n)固定。
(3)函数path()对迷宫进行处理,从入口开始:While(!((s->top==-1)&&(dir>=7)||(x==M)&&(y==N)&&(maze[x][y]==-1))){For(扫描八个可以走的方向){If(找到一个可以走的方向){进入栈标志在当前点可以找到一个可以走的方向避免重复选择maze[x][y]=-1不再对当前节点扫描}If(八个方向已经被全部扫描过,无可以通的路){标志当前节点没有往前的路后退一个节点搜索}}If(找到了目的地){输出路径退出循环}}未找到路径(4)输出从入口点到出口点的一条路径。