递归法求解迷宫问题

      求迷宫中从入口到出口的所有路径是一个经典的问题,这里所使用的方法是递归法,什么是递归呢?函数中有调用自己的函数,我们称为递归函数。一个问题可以分解为一个与自身求解过程相同的小问题,我们都可以用递归,比如,Hanoi塔问题,八皇后问题。我们知道用递归方法求解问题时最关键的就是递归函数的设计,在设计递归函数时应该注意以下几点:

     1.严格定义函数的功能和接口,对函数中所得的和原问题性质相同的子问题,只要接口一致,便可进行递归调用;

     2.对函数中每个递归调用都看成是一个简单的语句,切忌想得太深。

其实,在使用递归的时候我们可以想一下归纳法的思想,如果n成立,我们即可使用n的结论来计算n+1,在计算n+1时无需想着n+1之前的n是如何计算的,因为我们已经假设n已经成立了,无需在怀疑它的正确性。

     下面给出使用递归法求解迷宫问题的源代码,代码中求出了共有多少条道路可以通。

/*
 * 求迷宫中有多少条可通路径,1表示城墙,0表示道路
 */

#include <stdio.h>
#include <stdlib.h>

struct point{
 int p[10][10];
 int mark[10][10];
};
struct point pt;
int c = 0;

void build_maze(void)
{
 FILE *fd;
 char c;
 int i = 0,j;

 fd = fopen(“maze.txt”,”r”);        //maze.txt中画有迷宫地图
 while(!feof(fd)){
  c = fgetc(fd);
  if(isdigit(c)){ 
   pt.p[i/10][i%10] = c – 48;
   pt.mark[i/10][i%10] = 0;
   i++;
  } 
 }
 fclose(fd);
 return;
}

int maze(int x,int y)
{
 /*
  *当进入函数时,已经处在迷宫的(x,y)座标位置;
  *现在从(x,y)相邻的四个方向前进,前进条件是,该方向能通(值为0),并且还没有走过(0表示没走过);
  *当(x,y) == (8,8)终点时,表示求得一条可通路径
  */
 int i,j;
 if (x == 8 && y == 8) {                 //OUT
  c++;
  return 1;          
 }
 
 if (x – 1 >= 0 ) {                      //东方
  if (pt.p[x – 1][y] == 0) {
   if (pt.mark[x – 1][y] == 0) {
    pt.mark[x – 1][y] = 1;
    maze(x – 1,y);    
    pt.mark[x – 1][y] = 0;      //退回,将走过的标记清除
    
   }
  }
 }
 
 if (y + 1 <= 9){
  if (pt.p[x][y + 1] == 0 ){
   if (pt.mark[x][y + 1] == 0) {
    pt.mark[x][y + 1] = 1;
    maze(x,y + 1);
    pt.mark[x][y + 1] = 0;
   }
  }
    
 }
 
  
 if (x + 1 <= 9){    
  if (pt.p[x+1][y] == 0){
   if (pt.mark[x + 1][y] == 0) {
    pt.mark[x + 1][y] = 1;
    maze(x + 1,y);
    pt.mark[x + 1][y] = 0; 
   }
  }
 }
 
 if (y – 1 >= 0){     
  if (pt.p[x][y – 1] == 0){
   if(pt.mark[x][y – 1] == 0) {
    pt.mark[x][y – 1] = 1;
    maze(x,y – 1);
    pt.mark[x][y – 1] = 0;
   }
  }
 }
 return 0;
}
/* Find a way to go out of the maze */
int main()
{
 int i,j;
 build_maze();
 pt.mark[1][1] = 1;
 maze(1,1);
 if(c > 0) {
  printf(“There are %d ways for us to go out!/n”,c);
 }
 else
  printf(“Can’t go out!/n”);

 /* 打印迷宫地图 */
 for(i = 0;i<10;i++){
  for(j = 0;j < 10;j++){
   printf(“%d”,pt.p[i][j]);   
  }
  printf(“/n”);
 }
 return 0;
}

 

点赞