C语言实现迷宫求解

最近做了一个用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、如果栈不空则接着往下找,如果栈空,则结束,没有可行的通路。

5、这样一直进行,找到出口坐标则结束,找到可行的通路


下面是我写的代码:有问题大家多交流。

#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 ;
}

相关推荐