回溯算法c语言代码解释,走迷宫算法(C回溯递归)

引言

迷宫算法在很多场景都非常实用,比如游戏中的机器人等。而且高级的迷宫算法与回溯、递归也是息息相关的。而且回溯的用途更为广阔,如下棋游戏等。

请用代码走出下面的迷宫,并且将所有可能都列出。(R为当前开始位置)

0 1 2 3 4 5 6 7 8 9

0 # # # # # # # # # #

1 # # # # # #

2 # # # # # # #

3 # # # #

4 # # # # # # #

5 # # # # # #

6 # # # # #

7 # # # # # # # #

8 # #

9 # R # # # # # # #

原理

方法1:走迷宫算法本质是使用的一个栈,初始化栈为开始顶点(9,1,0)【x:9,y:1,d:0】,在从栈顶取出(x,y,d)【x:表示第几行,y:表示第几列,d:表示从哪个方向走】开始向d方向走之前先进行的判断,如果行的通(不为#,不为R,不越界)进行标记,已表明走过,并且将(x,y,d)放入到栈中;如果行不通则进行方向的加1然后在进行判断,一直到d=4则(就是上下左右都行不通)进行弹栈,依次类推。

方法2:我们从方法1中可以看出迷宫算法一直都是对栈顶进行操作,所以咱们可以不可以用递归来实现一下。思想非常的简单,就是每走一步就向四个方向进行验证,行的通就走,行不通就不走。具体看代码(备注很明白);

代码

# include "stdio.h"

# include "windows.h"

# define UP 0 //定义上

# define DOWN 1 //定义下

# define LEFT 2 //定义左

# define RIGHT 3 //定义右

# define MAP_MAX 10 //定义最大地图

int map[MAP_MAX][MAP_MAX] =

{

{1,1,1,1,1,1,1,1,1,1},

{1,0,0,0,1,0,1,1,1,1},

{1,0,1,0,1,0,1,1,1,1},

{1,0,1,0,0,0,0,0,1,1},

{1,0,1,0,1,1,0,1,1,1},

{1,0,1,0,0,1,0,1,1,1},

{1,0,1,1,0,1,0,0,0,1},

{1,0,1,1,1,1,1,1,0,1},

{1,0,0,0,0,0,0,0,0,1},

{1,2,1,1,1,1,1,1,0,1}//手动在出发点标了个2

};

/*

打印地图

*/

void print_map()

{

int i,j;

char emt[]=" #R";

//定义显示的数组

putchar(' ');

for(j=0; j

{

printf(" %d", j);

}

putchar('\n');

for(i=0; i

{

printf("%d ", i);

for(j=0; j

{

printf("%c ", emt[map[i][j]]);

}

putchar('\n');

}

}

/*

单纯的移动,并且进行值的改变

*/

void move(int &x, int &y, int d)

{

switch(d)

{

case UP:

x--;

break;

case DOWN:

x++;

break;

case LEFT:

y--;

break;

case RIGHT:

y++;

break;

}

}

/*

检查下一步是否可行

x,y点开始

d方向

*/

int inspect(int x,int y,int d)

{

// printf("%d %d %d\n", x,y,d);

move(x,y,d);

if(x<0 || y<0|| x>=MAP_MAX || y>=MAP_MAX || map[x][y]!=0)

{

return 0;

}

return 1;

}

void print_pro(int s[2], int e[2], int n){

/*打印过程*/

Sleep(0);

//system("cls");

printf("当前:(%d, %d) 终点:(%d, %d) 步数:%d\n", s[0],s[1],e[0],e[1],n);

print_map();

/*--------*/

}

/*

走迷宫(递归回溯所有可能都走)

s是开始坐标

e是结束坐标

n当前第几步

*/

int mazes(int s[2],int e[2],int n)

{

if(s[0]==e[0] && s[1]==e[1]){

print_pro(s,e,n);

}

int i;

for(i=0; i<4; i++)//向四个方向同时走

{

if(inspect(s[0],s[1],i))//检查i方向是否可以行得通

{

int tx = s[0], ty = s[1];//设置临时变量,防止数据混乱

move(tx,ty,i);//向i方向移动一步

map[tx][ty] = 2;//标记已走

int ta[2] = {tx,ty};//传值变量

mazes(ta,e,n+1);

map[tx][ty] = 0;//取消标记

}

}

}

int main()

{

int n = 0;//初始步数

int s[2] = {9,1};//s初始位置

int e[2] = {9,8};//e终止位置

mazes(s,e,n);//调用走迷宫

putchar('\n');

return 0;

}

结果

当前:(9, 8) 终点:(9, 8) 步数:23

0 1 2 3 4 5 6 7 8 9

0 # # # # # # # # # #

1 # R R R # # # # #

2 # R # R # # # # #

3 # R # R R R R # #

4 # R # # # R # # #

5 # R # # R # # #

6 # R # # # R R R #

7 # R # # # # # # R #

8 # R R #

9 # R # # # # # # R #

当前:(9, 8) 终点:(9, 8) 步数:9

0 1 2 3 4 5 6 7 8 9

0 # # # # # # # # # #

1 # # # # # #

2 # # # # # # #

3 # # # #

4 # # # # # # #

5 # # # # # #

6 # # # # #

7 # # # # # # # #

8 # R R R R R R R R #

9 # R # # # # # # R #

结语

迷宫算法还是很有研究的必要,因为他涉及 栈、递归、回溯、生成树这些知识点。通过迷宫算法可以更深一步理解。如果有什么问题可以评论,如果想要栈的走迷宫代码,可以私信我。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值