数据结构实战(八)——迷宫问题

任务简述

设计非递归算法,根据入口和出口位置将给定迷宫中的全部可行路线输出,并标记出其中的最短路径;
int mg[10][10]={
{1,1,1,1,1,1,1,1,1,1},
{1,0,0,1,0,0,0,1,0,1},
{1,0,0,1,0,0,0,1,0,1},
{1,0,0,0,0,1,1,0,0,1},
{1,0,1,1,1,0,0,0,0,1},
{1,0,0,0,1,0,0,0,0,1},
{1,0,1,0,0,0,1,0,0,1},
{1,0,1,1,1,0,1,1,0,1},
{1,1,0,0,0,0,0,0,0,1},
{1,1,1,1,1,1,1,1,1,1},
}; //该二维数组表示迷宫,0表示可行,1表示不可行。

算法描述

用temp将矩阵复制一份,先对temp操作,利用队列dd求出最短路径的长度,若存在路径,则再对mg操作,利用栈T求出所有与最短路径长度一样的路径并输出。

源代码

#include "stdio.h"
#include "stdlib.h"
#define N 8 
typedef struct ddd{
	int x,y,pre;
}dd;//队列 
typedef struct mystack{
	int xx[100],yy[100];
	int fangxiang[100];
	int top;
}ST;//栈 
int dx[4]={0,0,-1,1};//四个方向的改变 
int dy[4]={-1,1,0,0};
int mg[10][10]={
	{1,1,1,1,1,1,1,1,1,1},
	{1,0,0,1,0,0,0,1,0,1},
	{1,0,0,1,0,0,0,1,0,1},
	{1,0,0,0,0,1,1,0,0,1},
	{1,0,1,1,1,0,0,0,0,1},
	{1,0,0,0,1,0,0,0,0,1},
	{1,0,1,0,0,0,1,0,0,1},
	{1,0,1,1,1,0,1,1,0,1},
	{1,1,0,0,0,0,0,0,0,1},
	{1,1,1,1,1,1,1,1,1,1},	
};	 //迷宫 
void showway(ST T,int n);

int main(){
	int start_x,start_y,end_x,end_y;
	printf("请输入起点、终点的坐标:");
	scanf("%d%d%d%d",&start_x,&start_y,&end_x,&end_y);
	int head=1,tail=1,flag=0,i,j,tx,ty,minlen=0,temp[10][10];//head,tail分别表示队头和队尾,flag用来判断是否存在路径,i用来循环四个方向,tx,ty用来记录位置,minlen表示最短路径的长度,用temp将矩阵复制,找最短路径的操作对temp进行 
	dd d[100]; //队列 
	for(i=0;i<10;i++)	for(j=0;j<10;j++)	temp[i][j]=mg[i][j]; 
	d[1].x=start_x,d[1].y=start_y,d[1].pre=0,temp[start_x][start_y]=1;//设置起点的数据 
	while(head<=tail&&tail<100){//先找出最短路径的长度 
		if(d[head].x==end_x&&d[head].y==end_y){//head达到终点,由于tail可能一次大不止一个,所以用head 
			while(head){
				minlen++;
				head=d[head].pre;
			}
			flag=1;
			printf("最短要%d步\n",minlen);
			break;
		}
		for(i=0;i<4;i++){//四个方向循环,判断是否能走 
			tx=d[head].x+dx[i];
			ty=d[head].y+dy[i];
			if(temp[tx][ty]==0){//判断是否能走 
				tail++;
				d[tail].x=tx;
				d[tail].y=ty;
				d[tail].pre=head;
				temp[tx][ty]=1;//将这个点变为1 
			}
		}
		head++;
	}
	if(flag==0)//如果不存在路径 
		printf("no way\n");
	else{//若存在路径,则输出所有最短路径 
		ST T;//栈 
		int nextpose=0,tiaoshu=0;//用nextpose判断下一步的方向,条数记录路径条数 
		T.top=0;//初始化栈的数据 
		T.xx[0]=1;
		T.yy[0]=1;
		mg[1][1]=1;
		while(T.top>=0){
			for(i=nextpose;i<4;i++){//四个方向 		
				if(i>=4)	break;//如果进来时便i>=4则break 
				tx=T.xx[T.top]+dx[i];
				ty=T.yy[T.top]+dy[i];
				if(mg[tx][ty]==0){//当前方向可行			
					T.fangxiang[T.top]=i;//记下当前方向 
					if(tx==end_x&&ty==end_y){//已经到了终点 
						tiaoshu++;
						if(T.top==minlen-2){//top还未++且从0开始,所以top=minlen-2时路径长度为最短路径的长度,输出该路径并tiaoshu++ 
							printf("下面为一条最短路径:\n");	
						}
						T.top++;
						T.xx[T.top]=tx;
						T.yy[T.top]=ty;
						T.top--;
						showway(T,T.top+2);
						printf("路径长度:%d\n",T.top+2);
						mg[T.xx[T.top]][T.yy[T.top]]=0;//将当前点更改为可行并top--,对前一个点进行下一个方向的操作 
						T.top--;
						nextpose=T.fangxiang[T.top]+1;
						break; 
					}
					else{
						mg[tx][ty]=1;//将当前点更改为不可行并计入栈中,之后对这个点的四个方向进行操作 
						T.top++;
						T.xx[T.top]=tx;
						T.yy[T.top]=ty;
						nextpose=0;
						break;
					}
				}
			}
			if(i>=4){//若当前点四个方向都不可行,则弹栈并开始对前一个点进行操作 
				mg[T.xx[T.top]][T.yy[T.top]]=0;
				T.top--;
				nextpose=T.fangxiang[T.top]+1;
			}
		}
		printf("共%d条\n",tiaoshu);
	}
	return 0;
}

void showway(ST T,int n){//显示路径的函数,n为路径长度 
	int i,j;
	for(i=0,j=0;i<n;i++){
		printf("(%d,%d) ",T.xx[i],T.yy[i]);
		j++;
		if(j%10==0)
			printf("\n");
	}
	printf("\n\n");
}//共121行

运行结果

在这里插入图片描述

总结

队列可以用来找出最短路径,栈则可类似递归地找出所有路径,两种数据结构一起使用可以找出所有的最短路径。老师上课的时候提示了这种做法,下来自己尝试了一下便成功了。在使用指针前要记得给指针赋初值。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值