c语言迷宫问题求解——递归、栈回溯

第一次写,见谅

以下是求迷宫的实现

为什么下面会出现<span>标签啊,有什么简便的方法去掉吗?求告知

最后是关于求所有通路,个人愚笨只想到改变搜索方向顺序这种笨方法,总共有16种《c语言迷宫问题求解——递归、栈回溯》不同顺序,有兴趣的小伙伴可以试一下

/*
第一部分使用递归求解
为了数据的简单化,不对路口进行数据结构化,将用一个简单的int类型数组来表示迷宫
因为每一个路口的四个方向相对于当前路口的位移都是一样的,这样可以用一个int类型二位数据表示四个方向的相对于当前位置的位移,以顺时针东、南,、西、北储存
    
 */


//路口数据结构化
//当前路口状态;1表示通顺路口,2表示搜索过的,0表示障碍路口



#include<stdio.h>
#include<stdlib.h>
#define MaxStackSize 72   //堆栈的最大元素个数
#define m 9   //表示迷宫的行
#define n 8	   //表示迷宫的列


	//初始化迷宫,用于递归求通路
int maze[m][n]={
	{1,1,0,1,1,1,0,1},
	{1,1,0,1,1,1,0,1},
	{1,1,1,1,0,0,1,0},
	{1,0,0,0,1,1,0,1},
	{1,1,1,0,1,1,1,1},
	{1,0,1,1,1,0,1,0},
	{1,0,0,0,0,1,1,0},
	{0,0,1,1,1,0,1,0},
	{0,0,1,1,1,1,1,1}
};
//用于堆栈求通路
int mazee[m][n]={
	{1,1,0,1,1,1,0,1},
	{1,1,0,1,1,1,0,1},
	{1,1,1,1,0,0,1,0},
	{1,0,0,0,1,1,0,1},
	{1,1,1,0,1,1,1,1},
	{1,0,1,1,1,0,1,0},
	{1,0,0,0,0,1,1,0},
	{0,0,1,1,1,0,1,0},
	{0,0,1,1,1,1,1,1}
};


//初始化每个路口相邻路口的相对偏移量数组,表示当前路口的四个方向,按顺时针依次是东,南、西、北
int move[4][2]= {{0,1},{1,0},{0,-1},{-1,0}};


//求迷宫通路算法,两个参数为入口坐标
int MAZE(int x, int y)
{




	//将越界路口跳出
	if(x<0||x>m||y<0||y>n){
		return 0;
	}
    int a,b;
    int tag = 0;
	//迷宫出口
    if(x==8 && y==7)
        return 1;
	
	//试探相邻的4个路口
    for(int i= 0; i<4; i++)
    {
        a= x+ move[i][0];
        b= y+ move[i][1];


		//如果路口通顺且没搜索过则进入该路口,否则什么都不做
        if(maze[a][b]==1)
        {
		      	
            maze[a][b]= 2;//(a,b)上的值改成2表示走过的路
			//进入路口
			tag= MAZE(a, b);
            //判断是否找到出口用于输出路径
			if(tag){
				
                printf("(%d,%d)←",a,b);
                return 1;
            }
        }
    }//end for
    return 0;
}


/*


第二部分使用堆栈求迷宫通路


*/

//路口数据化
typedef struct{
	int x;
	int y;      //x,y表示路口位置
	int condition;       //表示路口状态,1表示通顺路口,2表示搜索过的,0表示障碍路口
} Stack;

//栈用来储存从入口到当前路口的路径
typedef struct
{
	Stack stack[MaxStackSize];
	int top;
}SeqStack;


//堆栈初始化
void StackInitiate(SeqStack *s){
	s->top=0;
}


//判断堆栈是否为空
int StackNotEmpty(SeqStack s){
	if(s.top<=0)return 0;
	else return 1;
}


//入栈,成功返回1,否则返回0
int StackPush(SeqStack *s,Stack x){
	if(s->top>=MaxStackSize)
	{
		printf("堆栈已满无法插入!\n");
		return 0;
	}
	else
	{
		s->stack[s->top]=x;
		s->top++;
		return 1;
	}
}


//取得栈顶元素,成功返回1,否则返回0
	int StackTop(SeqStack s,Stack *x)
	{
		if(s.top<=0)
		{
			printf("堆栈已空!\n");
			return 0;
		}
		else{
			*x=s.stack[s.top-1];
			return 1;
		}
	}


//出栈,成功返回1,否则返回0
int StackPop(SeqStack *s,Stack *x){


	if(s->top<=0)
	{
		printf("堆栈已空无数据元素出栈!\n");
		return 0;
	}
	else
	{
		s->top--;
		*x=s->stack[s->top];
		return 1;
	}
}


void getPass(){

SeqStack s;     //堆栈
StackInitiate(&s);         //堆栈初始化
Stack ss;
int a=0,b=0;       //a,b表示当前搜索的迷宫位置,当前是入口

ss.x=a;
ss.y=b;
ss.condition=mazee[a][b]=2;
StackPush(&s,ss);

while(StackNotEmpty(s)){       //将堆栈为空设置成停止循环的条件,也意味着没有通路;

StackTop(s,&ss);  //获取当前位置
  
//下个路口的探索
for(int i= 0; i<4; i++)
  {

       a= ss.x+ move[i][0];
       b= ss.y+ move[i][1];
//如果不越界,进入下一个方向
if(a>=0&&a<m&&b>=0&&b<n){

//如果通顺,进入路口,入栈,否则什么都不做,搜索另一个方向
if(mazee[a][b]==1){
mazee[a][b]=2;
ss.condition=mazee[a][b];
ss.x=a;
ss.y=b;
StackPush(&s,ss);
break;

 }//end if
}//end if
if(i==3){
StackPop(&s,&ss);      //但搜索到第四个方向且该方向的路口不通,出栈
}
}//end for

//迷宫出口
if(a==8&&b==7)break;     //但搜索到出口跳出
 }//end while


if(!StackNotEmpty(s))printf("该迷宫没有通路\n");
else{
while(StackNotEmpty(s)){
    StackPop(&s,&ss);
printf("(%d,%d)←",ss.x,ss.y);
}//end while
}//end else
}




void main()
{


//堆栈求迷宫通路
printf("堆栈求迷宫的通路:\n");
getPass();
printf("\n\n\n\n");
//递归求所有通路,按一定方向顺序进行搜索能得到一条路径,反过来想的话,用不同方向顺序进行搜索能得到不同路径,除非只有一条通路
//调用MAZE,每调用依次必须对迷宫进行初始化
printf("递归求迷宫的通路:\n");
MAZE(0,0);
//迷宫入口
printf("(0,0)←入口\n");

system("pause");
       
    原文作者:迷宫问题
    原文地址: https://blog.csdn.net/to_study/article/details/80464900
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞