最近做了一个用C语言迷宫求解的题目,来分享一下。
题目要求://迷宫的布局放入到一个二维的数组中 1代表该地方走不通为墙,0代表该地方可以走通,打印出来走的顺序
//0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9
const int mizu[10][10] = { 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1, //0
1 , 0 , 0 , 1 , 0 , 0 , 0 , 1 , 0 , 1, //1
1 , 0 , 0 , 1 , 0 , 0 , 0 , 1 , 0 , 1, //2
1 , 0 , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 1, //3
1 , 0 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 1, //4
1 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 1, //5
1 , 0 , 1 , 0 , 0 , 0 , 1 , 0 , 0 , 1, //6
1 , 0 , 1 , 1 , 1 , 0 , 1 , 1 , 0 , 1, //7
1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1, //8
1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 //9
} ;
分析:
1、可以利用C语言的栈来实现,起点坐标为(1,1),如果该步能走通,把该步的坐标入栈,且对该坐标进行标记,代表已经走过。
2、然后以该坐标(x,y)为中心进行,对该坐标的上(x,y-1)、右(x+1,y)、下(x,y-1)、左(x-1,y)的坐标顺时针进行判断可否走通(可否走通的条件为:该坐标的值为0,同时该步没有走过),寻找下一步坐标,如果找到了下一步,就接着入栈。
3、如果判断出来该坐标的四周的四个坐标(上、右、下、左)都不能够走通,则把该坐标出栈。
4、如果栈不空则接着往下找,如果栈空,则结束,没有可行的通路。
4、这样一直进行,找到出口坐标则结束,找到可行的通路
下面是我写的代码:有问题大家多交流。
#include <stdio.h> #include <stdlib.h> //迷宫的布局放入到一个二维的数组中 //0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 const int mizu[10][10] = {1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1, //0 1 , 0 , 0 , 1 , 0 , 0 , 0 , 1 , 0 , 1, //1 1 , 0 , 0 , 1 , 0 , 0 , 0 , 1 , 0 , 1, //2 1 , 0 , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 1, //3 1 , 0 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 1, //4 1 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 1, //5 1 , 0 , 1 , 0 , 0 , 0 , 1 , 0 , 0 , 1, //6 1 , 0 , 1 , 1 , 1 , 0 , 1 , 1 , 0 , 1, //7 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1, //8 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 //9 } ; int flag[10][10] = {0} ; typedef int TypeData ; typedef struct node{ TypeData datax ; TypeData datay ; struct node* next ; }Node , *LinkList ; typedef struct stack{ LinkList top ; }STACK ; //************************函数声明****************************** int stackInit(STACK* s ) ; int pushStack(STACK* s ,TypeData x , TypeData y) ; void popStack(STACK* s , TypeData* x , TypeData* y) ; int isStackEmpty(STACK* s) ; int mizePath(STACK* s ,TypeData end_x , TypeData end_y ) ; int passMizu(TypeData x , TypeData y ) ; //********************************************************** //链栈的初始化 int stackInit(STACK* s ) { LinkList p = (LinkList)malloc(sizeof(Node)) ; if(!p) return -1 ; p->next = NULL ; p->datax = -1 ; p->datay = -1 ; s->top = p ; return 1 ; } //入栈操作 int pushStack(STACK* s ,TypeData x , TypeData y) { LinkList p = (LinkList)malloc(sizeof(Node)) ; if(!p) return -1 ; //分配内存失败 p->datax = x ; p->datay = y ; p->next = s->top ; s->top = p ; return 1 ; } //出栈的操作 void popStack(STACK* s , TypeData* x , TypeData* y) { LinkList p = s->top ; s->top = p->next ; (*x) = p->datax ; (*y) = p->datay ; free(p) ; } //判断栈是否为空 //1 空 0 不空 int isStackEmpty(STACK* s) { if(s->top->datax == -1) //栈空 return 1 ; return 0 ; } //找到最佳路径 //end_x , end_y为结束的坐标 //上 、右、下、左寻找方式 int mizePath(STACK* s ,TypeData end_x , TypeData end_y ) { pushStack(s , 1 ,1) ; //初始坐标压栈 TypeData nowx = 1 , nowy = 1 ; flag[nowx][nowy] = 1 ; //该坐标已经被占用不能再通过 while(!isStackEmpty(s)) //当栈不空的时候 { if((nowx == end_x)&&(nowy == end_y)) { return 1 ; } // printf("nowx = %d nowy = %d\n",nowx , nowy) ; // system("PAUSE") ; if(passMizu(nowx , nowy-1)) //先向上寻找 { nowy = nowy - 1 ; //坐标更改 pushStack(s , nowx , nowy) ; //把该坐标压栈 flag[nowy][nowx] = 1 ; //该坐标已经被占用不能再通过 } else if(passMizu(nowx+1 , nowy)) //向右寻找 { nowx = nowx + 1 ; pushStack(s , nowx , nowy) ; //把该坐标压栈 flag[nowy][nowx] = 1 ; //该坐标已经被占用不能再通过 } else if(passMizu(nowx , nowy+1)) //向下寻找 { nowy = nowy + 1 ; pushStack(s , nowx , nowy) ; //把该坐标压栈 flag[nowy][nowx] = 1 ; //该坐标已经被占用不能再通过 } else if(passMizu(nowx-1 , nowy)) //向左寻找 { nowx = nowx - 1 ; pushStack(s , nowx , nowy) ; //把该坐标压栈 flag[nowy][nowx] = 1 ; //该坐标已经被占用不能再通过 } else //都行不通 { popStack(s , &nowx , &nowy) ; } } //while(!isStackEmpty(s)) //当栈不空的时候 return 0 ; } //判断该位置是否可通 int passMizu(TypeData x , TypeData y ) { if((x > 9)||(y > 9)) return 0 ; //越界不可通 if(mizu[y][x]) return 0 ; //该位置是墙,不可通 if(flag[y][x]) return 0 ; //该坐标已经被占用,不能通过 return 1 ; } //打印栈中的数据 int printStackData(STACK s) { STACK temp ; //新建一个临时的栈 stackInit(&temp) ; if(s.top->datax == -1) return 0 ; //栈为空 while(s.top->datax != -1) { pushStack(&temp,s.top->datax,s.top->datay); s.top = s.top->next ; } while(temp.top->datax != -1) { printf("(%d,%d)\n",temp.top->datax , temp.top->datay) ; temp.top = temp.top->next ; } return 1 ; } int main() { STACK mi_stack ; int i = 0 , j = 0 ; stackInit(&mi_stack) ; if(mizePath(&mi_stack , 8 , 8)) { printStackData(mi_stack) ; //把坐标倒叙打印出来 } else printf("没有通路!\n") ; return 0 ; }