经典算法~~迷宫---用栈模拟递归实现

这个算法,用邻接矩阵表示迷宫,主要的思路是:从起点出发,寻找可以走的位置,将横纵坐标压入栈中,当走入死胡同时,读取栈中的横纵坐标,标记该位置,避免再次进入死胡同中,然后再寻找其他的路线,直到找到出口。

这种一步步回退的技巧叫做回溯,回溯的基本原理是从某一个点开始,找不到解时(在迷宫中,就是进入了死胡同),就回到前一个结点,再次重新从这个点出发尝试下一个未尝试的可能路径。

下面是代码实现:

# include <stdio.h>
# include <stdlib.h>
# define LIST struct list

typedef struct                //四个方向的结点
{
	int vert;
	int horiz;
}offsets;

typedef LIST                   //入栈的结点
{
	int line;
	int colu;
	LIST *next;
}link;


LIST *put(int x, int y, LIST *p)                  //入栈函数
{
	LIST *p1, *p2;
	p1 = (LIST *)malloc(sizeof(LIST));
	p1->line = x;
	p1->colu = y;
	p2 = p;
	p1->next = p2;
	p = p1;
	return p;
}

LIST *dele(LIST *p)                      //出栈函数
{
	LIST *p1;
	p1 = p;
	p = p->next;
	free(p1);
	return p;
}
int main()
{
	void work_maze(int maze[][10], int line, int colu, offsets move[4]);
	offsets move[4];                                 //定义结构体数组,分别是上下左右四个方向的。  
	move[0].vert = -1; move[0].horiz = 0;         
	move[1].vert = 1; move[1].horiz = 0;
	move[2].vert = 0; move[2].horiz = -1;
	move[3].vert = 0; move[3].horiz = 1;
	int maze[10][10] = {{1,1,1,1,1,1,1,1,1,1},{2,0,1,1,1,0,1,0,1,1},{1,0,0,1,0,0,0,1,0,1},
	{1,0,1,1,0,1,0,1,0,2},{1,0,0,0,0,1,0,1,0,1},{1,1,1,0,1,1,0,1,0,1},{1,1,0,1,1,1,0,0,0,1},
	{1,0,1,1,0,0,1,1,0,1},{1,0,0,1,1,0,0,1,0,1},{1,1,1,1,1,1,1,1,1,1}};               //迷宫用邻接矩阵表示
	int line = 3, colu = 8;
	int i, j;
	work_maze(maze, line, colu, move);	
	for(i = 0; i < 10; i++)                      //打印迷宫以及路线
	{
		for(j = 0; j < 10; j++)
		{
			if(maze[i][j] == 1)
				printf("■");          
			else if(maze[i][j] == 2)
				printf("%2c", 16);
			else if(maze[i][j] == 3)
				printf("%2c", 17);
			else if(maze[i][j] == 4)
				printf("%2c", 31);
			else if(maze[i][j] == 5)
				printf("%2c", 30);
			else 
				printf("  ");
		}
		printf("\n");
	}
	printf("\n");
	return 0;
}
void work_maze(int maze[][10], int line, int colu, offsets move[4])
{
	int line1, colu1, d = 0, found = 0, m, n, flag = 0;
	LIST *top, *p;
	top = NULL;
	line1 = 1; colu1 = 1; maze[line1][colu1] = 2;
	p = (LIST *)malloc(sizeof(LIST));
	p->line = line1;
	p->colu = colu1;
	p->next = top;
	top = p;
	while(found == 0)
	{
		if(flag != 0 && top == p)                      //表示没有出口
		{
			printf("无路可走!!\n");
			break;
		}
		else if(flag != 0)
		{                                            //读栈
			maze[line1][colu1] = -1;                //标记为-1,表示为已经走过的,且是走不通的路!
			line1 = top->next->line;                 
			colu1 = top->next->colu;
			top = dele(top);                       //栈顶的出栈
		}
		while(d < 4)
		{
			m = line1 + move[d].vert;                     
			n = colu1 + move[d].horiz;
			if(maze[m][n] == 0)
			{
				line1 = m; colu1 = n;
				top = put(line1, colu1, top);              //将走到的位置压入栈
				if(d == 0)                                 //标记路线
					maze[line1][colu1] = 5;                
				else if(d == 1)
					maze[line1][colu1] = 4;
				else if(d == 2)
					maze[line1][colu1] = 3;
				else if(d == 3)
					maze[line1][colu1] = 2;
				flag = 1;
				if(line1 == line && colu1 == colu)         //表示找到了出口
				{
					found = 1;
					break;
				}
				else
				{
					d = 0;          //找到有路,d重新赋值0
				}
			}
			else
			{
				d++;                    //尝试其他方向
			}
		}
		d = 0;
	}
}

下面是样例结果:


用栈模拟深度优先,在这个算法中,需要注意的是路径的标记。!~~~

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值