(栈的实现)迷宫求解

题目描述
用一个m×n的矩阵表示迷宫,0和1分别表示迷宫中的通路和障碍。设计一个程序,对给定的迷宫,求出找到的第一条从入口到出口的通路,或得到没有通路的结论。
我们指定:
(1) 迷宫的入口为矩阵的左上角(1,1),迷宫的出口为右下角(m,n);
(2) 路径的探索顺序依次为"东南西北"(即:右下左上)。
要求:
输入:
第一行输入两个整数,空格间隔,分别表示矩阵的行数m和列数n;
接下来的连续m行,输入迷宫矩阵的信息。
输出:
求得的通路以三元组(i,j,d)的形式输出。
其中:
i,j指示迷宫的一个坐标;
d表示走到下一坐标的方向(数字1表示东,数字2表示南,数字3表示西,数字4表示北);
终点d值为0。
解析:
1.当处于迷宫的边、角时,将不再具有四个方向,如此,会增加算法难度,为解决此问题,将行列各增加两行,并将其全部设成障碍。
如下图:设置了一个6行8列的迷宫,在其外围加了一圈障碍,(1,1)为入口,(6,8)为出口(下图出了些错误,出口标记错误)。
在这里插入图片描述
2.若所在位置周围没有通路,就要考虑回退,因此我们在解决这道题时应采用栈。

3.我们还应该避免兜圈子,为解决这问题,必须将曾到过的位置进行标记。

下面是代码实现:

#include <stdio.h>
#include <stdlib.h>
 
typedef struct n
{
	int i;
	int j;
	int f;
	struct n* next;
}link;
//创建 
link* init(){
	link* l = (link*)malloc(sizeof(link));
	l->i=0;
	l->j=0;
	l->f=0;
	l->next=NULL;
	return l;
}
link* l;
//判空操作 
int isEmpty(link *l){
	if(l->next==NULL)
		return 1;
	return 0;
}
//入栈操作 :头插法 
void ru(link *l,int i,int j,int f){
	link *p = (link*)malloc(sizeof(link));
	p->i=i;
	p->j=j;
	p->f=f;
	p->next=l->next;
	l->next=p;
}
//出栈操作 
int chu(link* l){
	if(isEmpty(l))
		return 0;
	link* p=l->next;
	l->next=l->next->next;
	free(p);
	return 1;
}
//算法 
int VistMaze(int maze[][100],int endi,int endj,int starti,int startj, int i, int j)
{
	int end = 0;//end==flag,1为已出迷宫,0为未出 
	maze[i][j] = 2;
	if (i == endi && j == endj){
		end = 1;
	}
	if (end != 1 && j + 1 <= endj && maze[i][j + 1] == 0){		//右
		ru(l,i,j,1);
		if (VistMaze(maze,endi,endj,starti,startj, i, j + 1) == 1)
			return 1;
	}
	if (end != 1 && i + 1 <= endi && maze[i + 1][j] == 0){		//下
		ru(l,i,j,2);
		if (VistMaze(maze,endi,endj,starti,startj, i + 1, j) == 1)
			return 1;
	}
	if (end != 1 && j - 1 >= startj && maze[i][j - 1] == 0){	//左
		ru(l,i,j,3);
		if (VistMaze(maze,endi,endj,starti,startj, i, j - 1) == 1)
			return 1;
	}
	if (end != 1 && i - 1 >= starti && maze[i - 1][j] == 0){	//上
		ru(l,i,j,4);
		if (VistMaze(maze,endi,endj,starti,startj, i - 1, j) == 1)
			return 1;
	}
	//当下一步的各个方向均为墙时,将本部设为0通路,由上一步的2去探索下一个通路 
	if (end != 1){
		maze[i][j] = 0;
		chu(l);
	}
	return end;
}
//输出函数 
void show(link* l){
	if(l->next)
		show(l->next); 
	if(l->i)
		printf("(%d,%d,%d)",l->i,l->j,l->f);
}
int main(void)
{
	int i,j;
	int q,w; 
//	link* l;
	l = init();
	scanf("%d %d",&i,&j);
	int a[100][100];
	for(q=1;q<=i;q++){
		for(w=1;w<=j;w++){
			scanf("%1d",&a[q][w]);//因为输入不能带空格,所以每次在输入时截取一个字符 
		}
	}
	printf("输出路径:\n");
	if(VistMaze(a,i,j,1,1,1,1) == 1){
		ru(l,i,j,0);//上面的if已将除最后一步以外的所有通路全部入栈,这一步将通路最后一步单独入栈
		
		show(l);
	}
}

运行截图:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值