迷宫问题(完整版)

8083b066bfcd4a4c81f38b9e27408763.png

c++的代码与注释

#include<bits/stdc++.h>
using namespace std;

//方向的结构定义
typedef struct{
	int incX,incY;
}Direction;

Direction direct[4]; //创建四个方向的结构数组

//存储当前坐标和方向的结构体
typedef struct{
	int x, y;  //当前坐标
	int di;    //方向
}Box;



//打印迷宫
void show(int *maze[],int M, int N){
int i,j;
printf("\n");
	printf("迷宫如下:(-1代表走过的路径)\n");
	for(i = 0; i<M; i++){
		for(j = 0; j<N;j++){
	
	printf("%4d ",maze[i][j]);
	}
	printf("\n");
}
	printf("\n");

}

//处理迷宫
bool findPath(Direction direct[]){

int a,i,j;
int M,N;        //M是迷宫的行数,N是迷宫的列数
printf("   注意:  输入的M,N均要大于2\n\n");
printf("请输入M(迷宫的行数),N(迷宫的列数): ");
scanf("%d %d",&M, &N);
	int maze[M][N];
	int *s[M];
	for(i=0;i<M;i++)
	  s[i]=maze[i];
	printf("请输入迷宫(输入1表示墙,输入0表示通道:)\n");
	for(i = 0; i<M; i++){
		for(j = 0; j<N;j++){
	cin >> a;
	maze[i][j]=a;
	}
}

int m1,n1;//起点坐标
	printf("请输入起点坐标:");
	scanf("%d %d", &m1, &n1);

	int m2,n2;//终点坐标
	printf("请输入终点坐标:");
	scanf("%d %d", &m2, &n2);
	Box temp;
		stack<Box>S;  
	int x, y, di;   //当前位置的横纵坐标和方向
	int line, col;   //下一位置的横纵坐标
	maze[m1][n1]=-1;
	temp={m1,n1,-1};  //初始化当前位置并入栈
	S.push(temp);
	
	//开始走迷宫,走过的位置信息要入栈,当下一位置路不通时要退栈访问,尝试其他路径方向
	while(!S.empty()){
temp=S.top();
S.pop();		
		x=temp.x; y=temp.y; di=temp.di+1;
		
	//	试探四个方向
		while(di<4){
			line=x+direct[di].incX;         //line 为下一位置的横坐标
			col=y+direct[di].incY;          //col 为下一位置的纵坐标
			if(maze[line][col]==0){         //如果下一位置能走
				temp={x, y, di};
				S.push(temp);
				x=line; y=col; maze[line][col]=-1;
				if(x==m2&&y==n2) {           //如果到达终点
					show(s,M,N);
					return true;
				}
				else di=0;                  //重置di的值为0用于下次循环
			}
			else di++;                     //如果下一位置不可走,di++后试探其他方向
		}
		
	}
	
	show(s,M,N);
	return false;	
	}
	

	
int main(){
	direct[0]={0,1};//向右
	direct[1]={1,0};//向下
	direct[2]={0,-1};//向左
	direct[3]={-1,0};//向上
	int i, j;

	if(findPath(direct)) cout<<"该迷宫能到达终点"<<endl;
	else cout<<"该迷宫不能到达终点"<<endl;
	
}

f7621eaf7f42452ea2b9404cce6c2397.png

C语言代码与注释

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

//方向的结构定义
typedef struct{
	int incX,incY;
}Direction;
 
Direction direct[4]; //创建四个方向的结构数组
 
//存储当前坐标和方向的结构体
struct Stack{
	int x, y;  //当前坐标
	int di;    //方向
	struct Stack*next;
};
int maze[100][100];
 //栈的创建
struct Stack* CreateStack(struct Stack*head);
//栈的判空
bool isEmpty(struct Stack*head);
//入栈
void push(struct Stack*head, struct Stack*x);
//访问栈顶元素
struct Stack* top(struct Stack*head);
//出栈
void pop(struct Stack*head);
//递归求迷宫
bool findPath( int M,int N,int startX, int startY, int endX, int endY);

//栈的创建
struct Stack* CreateStack(struct Stack*head){
	head = (struct Stack*)malloc(sizeof(struct Stack));	
	head->next=NULL;
	return head;
}

//栈的判空
bool isEmpty(struct Stack*head){
if(head->next==NULL) return true;	
	else return false;
}

//入栈
void push(struct Stack*head, struct Stack*x){
	x->next=head->next;
	head->next=x;
}

//访问栈顶元素
struct Stack* top(struct Stack*head){
	return head->next;
}


//出栈
void pop(struct Stack*head){
	if(head->next->next!=NULL) head->next=head->next->next;
	else head->next=NULL;
}

 
//打印迷宫
void show(int M, int N){
int i,j;
printf("\n");
	printf("迷宫如下:(-1代表走过的路径)\n");
	for(i = 0; i<M; i++){
		for(j = 0; j<N;j++){
	
	printf("%4d ",maze[i][j]);
	}
	printf("\n");
}
	printf("\n");
 
}
 
//迭代处理迷宫
bool FindPath(Direction direct[]){
 
int a,i,j;
int M,N;        //M是迷宫的行数,N是迷宫的列数
printf("\n注意:  输入数字时迷宫四周的最外层必须全部是 1\n\n");
printf("请输入M(迷宫的行数),N(迷宫的列数): ");
scanf("%d %d",&M, &N);
	printf("请输入迷宫(输入1表示墙,输入0表示通道:)\n");
	for(i = 0; i<M; i++){
		for(j = 0; j<N;j++){
	scanf("%d",&a);
	maze[i][j]=a;
	}
}
 
int m1,n1;//起点坐标
	printf("请输入起点坐标:");
	scanf("%d %d", &m1, &n1);
 
	int m2,n2;//终点坐标
	printf("请输入终点坐标:");
	scanf("%d %d", &m2, &n2);
	struct Stack*H;
	struct Stack*head = CreateStack(H);
  if(maze[m1][n1]==1||maze[m2][n2]==1)
  {
  	printf("\n墙不能作为入口或出口,请重新输入!\n\n");
  	return false;
  }
	int x, y, di;   //当前位置的横纵坐标和方向
	int line, col;   //下一位置的横纵坐标
	maze[m1][n1]=-1;
	//初始化当前位置并入栈
	struct Stack*X=(struct Stack*)malloc(sizeof(struct Stack));
	X->x=m1;
	X->y=n1;
	X->di=-1;
	push(head,X);
	
	if(m1<M&&m1>=1&&n1>=1&&n1<N&&m2<M&&m2>=1&&n2>=1&&n2<N){
	
	//开始走迷宫,走过的位置信息要入栈,当下一位置路不通时要退栈访问,尝试其他路径方向
	while(!isEmpty(head)){
struct Stack*Temp=top(head);
pop(head);		
		x=Temp->x; y=Temp->y; di=Temp->di+1;
		
	//	试探四个方向
		while(di<4){
			line=x+direct[di].incX;         //line 为下一位置的横坐标
			col=y+direct[di].incY;          //col 为下一位置的纵坐标
			if(maze[line][col]==0){         //如果下一位置能走
				struct Stack*temp=(struct Stack*)malloc(sizeof(struct Stack));
				temp->x=x;
                temp->y=y;
	            temp->di=di;
				push(head,temp);
				x=line; y=col; maze[line][col]=-1;
				if(x==m2&&y==n2) {           //如果到达终点
					show(M,N);
					return true;
				}
				else di=0;                  //重置di的值为0用于下次循环
			}
			else di++;                     //如果下一位置不可走,di++后试探其他方向
		}
		
	}
	
	show(M,N);
	return false;	
}

else{
	printf("\n坐标输入有误,请重新输入!\n\n");
	return false;
}


	}
	
 
	
	
	//递归处理迷宫

 bool digui(){
int a,i,j;
int M,N;        //M是迷宫的行数,N是迷宫的列数
printf("注意:  输入的M,N均要大于2\n");
printf("请输入M(迷宫的行数),N(迷宫的列数): ");
scanf("%d %d",&M, &N);
printf("请输入迷宫(输入1表示墙,输入0表示通道:)\n");
for(i = 0; i<M; i++){
for(j = 0; j<N;j++){
scanf("%d",&a);
maze[i][j]=a;
}
}
 
int m1,n1;//起点坐标
printf("请输入起点坐标:");
scanf("%d %d", &m1, &n1);
 
int m2,n2;//终点坐标
printf("请输入终点坐标:");
scanf("%d %d", &m2, &n2);

bool c=findPath(M,N,m1,n1,m2,n2);

if(c){
	maze[m2][n2]=-1;
	show(M,N);
	return true;
} 

else return false;
}


//maze是一个二维矩阵,0表示可以走,1表示不能走
//startX和startY是起点的坐标,endX和endY是终点的坐标
bool findPath( int M,int N,int startX, int startY, int endX, int endY) {
    //如果已经到达终点,则返回true
    if (startX == endX && startY == endY) {
        return true;
    }
    //如果当前位置不可走,则返回false
    if (maze[startX][startY] == 1) {
        return false;
    }
    //将当前位置标记为已访问
    maze[startX][startY] = -1;
    //递归查找下一个可走位置
    if (startX + 1 <= M && maze[startX + 1][startY] != -1 && findPath( M,N,startX + 1, startY, endX, endY)) {
        return true;
    }
    if (startX - 1 >= 0 && maze[startX - 1][startY] != -1 && findPath( M,N,startX - 1, startY, endX, endY)) {
        return true;
    }
    if (startY + 1 <= N && maze[startX][startY + 1] != -1 && findPath( M,N,startX, startY + 1, endX, endY)) {
        return true;
    }
    if (startY - 1 >= 0 && maze[startX][startY - 1] != -1 && findPath( M,N,startX, startY - 1, endX, endY)){
	return true;
	}
    
    //如果没有找到可走位置,则返回false
    return false;
}
	
	
	
int main(){
		direct[0].incX=0;	direct[0].incY=1;//向右
	    direct[1].incX=1;	direct[1].incY=0;//向下
	    direct[2].incX=0;	direct[2].incY=-1;//向左
	    direct[3].incX=-1;	direct[3].incY=0;//向上
	int i,j;
	for(i=0;i<99;i++)
	  for(j=0;j<99;j++)
	     maze[i][j]=1;
	int option = 1 ;
	while(option >= 1 && option <= 3){
		
	printf("\n                           1.用迭代求迷宫问题\n");
   	printf("                           2.用递归求迷宫问题\n");
   	printf("                           3.退出\n");
		scanf("%d",&option); 
	switch(option){
			case 1:
				{
					
					if(FindPath(direct)) printf("该迷宫能到达终点\n");
	                else printf("该迷宫不能到达终点\n");
					break;
				}
			
			
			case 2:
				{
					if(digui()) printf("该迷宫能到达终点\n");
	                else printf("该迷宫不能到达终点\n");
					break;
				}
			
			case 3:
				{
					break;
				}
				
					
		}                 
	if(option == 3) break;
	}
	
	
}
	

递归核心算法:

//maze是一个二维矩阵,0表示可以走,1表示不能走
//startX和startY是起点的坐标,endX和endY是终点的坐标
bool findPath( int M,int N,int startX, int startY, int endX, int endY) {
    //如果已经到达终点,则返回true
    if (startX == endX && startY == endY) {
        return true;
    }
    //如果当前位置不可走,则返回false
    if (maze[startX][startY] == 1) {
        return false;
    }
    //将当前位置标记为已访问
    maze[startX][startY] = -1;
    //递归查找下一个可走位置
    if (startX + 1 <= M && maze[startX + 1][startY] != -1 && findPath( M,N,startX + 1, startY, endX, endY)) {
        return true;
    }
    if (startX - 1 >= 0 && maze[startX - 1][startY] != -1 && findPath( M,N,startX - 1, startY, endX, endY)) {
        return true;
    }
    if (startY + 1 <= N && maze[startX][startY + 1] != -1 && findPath( M,N,startX, startY + 1, endX, endY)) {
        return true;
    }
    if (startY - 1 >= 0 && maze[startX][startY - 1] != -1 && findPath( M,N,startX, startY - 1, endX, endY)){
	return true;
	}
    
    //如果没有找到可走位置,则返回false
    return false;
}
	

迭代算法:(注意:循环之前要有一次入栈操作)

//开始走迷宫,走过的位置信息要入栈,当下一位置路不通时要退栈访问,尝试其他路径方向
	while(!isEmpty(head)){
struct Stack*Temp=top(head);
pop(head);		
		x=Temp->x; y=Temp->y; di=Temp->di+1;
		
	//	试探四个方向
		while(di<4){
			line=x+direct[di].incX;         //line 为下一位置的横坐标
			col=y+direct[di].incY;          //col 为下一位置的纵坐标
			if(maze[line][col]==0){         //如果下一位置能走
				struct Stack*temp=(struct Stack*)malloc(sizeof(struct Stack));
				temp->x=x;
                temp->y=y;
	            temp->di=di;
				push(head,temp);
				x=line; y=col; maze[line][col]=-1;
				if(x==m2&&y==n2) {           //如果到达终点
					show(M,N);
					return true;
				}
				else di=0;                  //重置di的值为0用于下次循环
			}
			else di++;                     //如果下一位置不可走,di++后试探其他方向
		}
		
	}
	
	show(M,N);
	return false;	
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值