顺序栈的应用:迷宫

1.迷宫问题:

思路:

int mg[M+2][N+2]={
{1,1,1,1,1,1},//   0行0列开始   
{1,0,0,0,1,1},//1行 
{1,0,1,0,0,1},//2 行 
{1,0,0,0,1,1},
{1,1,0,0,0,1},//起点(1,1)    终点是(4,4) 
{1,1,1,1,1,1}


};

可以看到一条路径(1,1)(1,2)(1,3)(2,3)(2,4)(3,3)(4,3)(4,4)
要记录位置:移动的位置:

for(k=0;k<=top;k++) 
	
printf("(%d,%d)",St[k].i,St[k].j);//St[k].i,存储移动位置的


St[top].i=xi; //1,1 xi=1,yi=1. 存储移动的位置 
St[top].j=yi;刚开始记录:St[0].i=1,S[0].j=1       (1,1)



把位置移动:原来的位置是i,j.(i=St[top].i; j=St[top].j;)
移动后的位置:i1 j1(i1是i变化的).找到了mg[i1]mg[j1]=0;
就top++; 存储这个信息。St[top].i=i1; St[top].j=j1;
把移动后的位置值 mg[top][top]变为-1.
第二次移动:

	St[top].di=di;//这里di=2, 下一个就不可能 原来的位置
top++;  //这里top变化了:2,3,4 现在的位置
St[top].i=i1;  St[top].j=j1;// St[2].i=i1;
	
mg[i][j]=0;
top=top-1; 如果走不通,就返回原来的位置 top--;
				

第一个路径打印出来时,把mg[top][top]=-1,变成0.重新可以走路。

代码:

#include<stdio.h>
#define M 4
#define N 4
#define MaxSize 100

int mg[M+2][N+2]={
{1,1,1,1,1,1},//   0行0列开始   
{1,0,0,0,1,1},//1行 
{1,0,1,0,0,1},//2 行 
{1,0,0,0,1,1},
{1,1,0,0,0,1},//起点(1,1)    终点是(4,4) 
{1,1,1,1,1,1}


};

struct{
	
	int i,j;
	int di;
}St[MaxSize],path[MaxSize];


int top=-1;
int count=1;
int minlen=MaxSize;




void  dispapath(){
	int k;
	printf("这个数是%5d\n",count++);
	for(k=0;k<=top;k++) 
	
		printf("(%d,%d)",St[k].i,St[k].j);
		printf("\n");
		
		
		if(top+1<minlen){
			
			
			
			for(int k=0;k<top;k++)
				
		path[k]=St[k];
		minlen=top+1; //这里minlen改变了值 第一个1. 
		
			
		}
		
		
		
		
	}
	

	
	
void dispminpath()
{

	printf("最短路径如下:\n"); 
printf("长度:%d",minlen);
for(int k=0;k<minlen;k++){
	
	
printf("(%d,%d)",path[k].i,path[k].j);




	
}	
printf("\n");
	
	}
	
	
	void mgpath(int xi,int yi,int xe,int ye){//1,1,4,4 
		int i,j,i1,j1,di;
		
		bool find;
		top++;
		St[top].i=xi; //1,1 xi=1,yi=1. 存储移动的位置 
		St[top].j=yi;
		
		St[top].di=-1;
		mg[xi][yi]=-1; // mg[1][1]=-1;把走过的位置改为-1. 防止 
		
		
		while(top>-1){
			
			i=St[top].i;
			j=St[top].j;
			di=St[top].di;
			
			
			if(i==xe&&j==ye){//终点 
				
				dispapath();
				mg[i][j]=0;
				top--; //这里top会减减 
				
				i=St[top].i;//
				j=St[top].j;
				
				
				
				di=St[top].di;
				
			}  // 
			
			find=false;
			
			
			while(di<4&&!find){ //这里开始移动 
				
				di++; //这个开始加 从0,1,2,3,四个方向 
				switch(di){
					
					
					case 0: i1=i-1;j1=j;  break; //用i1,和j1代表移动的位置 :向左移动一步 
					case 1: i1=i;j1=j+1;  break;//向下面移动一步 
					case 2: i1=i+1;j1=j;  break;
					case 3: i1=i1;j1=j-1;  break;//向上面移动一步 
					
					
					
				}
				if(mg[i1][j1]==0) find=true;//只要存在一个位置 mg[i1][j1]==0,结束循环 
				
				
				
				
				
			}
			
			
			
			if(find){
				
				
				St[top].di=di;
				top++;  //这里top变化了:2,3,4 
				St[top].i=i1;  St[top].j=j1;// St[2].i=i1;
				
				St[top].di=-1;
				mg[i1][j1]=-1;//把这个值变成-1; 
				
				
			}
			
			else{
				
				mg[i][j]=0;
				top--;
			}
		}
		
		
		
		
		
		
		dispminpath(); 	
		
		
	} 
	
	
	
	
	//
	
	

	

int main(){
printf("迷宫的所有路径:\n");
mgpath(1,1,M,N);
return 0;	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
}





效果图:
在这里插入图片描述

补充:
当找到第一条路径时,栈的元素是:
(1,1)(1,2)(1,3)(2,3)(2,4)(3,3)(4,3)(4,4)
top- -,此时:栈的元素是:
(1,1)(1,2)(1,3)(2,3)(2,4)(3,3)(4,3)
再继续寻找路径:栈顶(4,3)的移动位置:移动到(4,2)把(4,2)元素变成-1,移动到(3,3),在(3,3)位置移动:上下左右循环元素值为0的,上为1,右为-1,只能往左边进栈(3,2)继续移动到(2,2),时,(2,2)元素上下左右都走不了,只能退栈,退栈时:把(2,2)元素由值-1变成0,现在栈顶是(3,2).位置之前标志了:只能左右下,还是没有路,再
退栈就变成栈顶是(3,3),还是找不到路,退栈,一直退到(3,3).此时:
St[top]保存的是栈:
(1,1)(1,2)(1,3)(2,3)(2,4)(3,3),就栈顶就是(3,3).就找路,向左边走路。
进栈(3,2)(4,2) (4,3) (4,4).就完成第二条路径。

第三条/第四条也是这样:进栈,退栈(保存进栈的位置)

{1,1,1,1,1,1},// 0行0列开始
{1,0,0,0,1,1},//1行
{1,0,1,0,0,1},//2 行
{1,0,0,0,1,1},
{1,1,0,0,0,1},//起点(1,1) 终点是(4,4)
{1,1,1,1,1,1}

2.更新:输入迷宫,打印出路径:

输入迷宫(有外墙)

7 7
1 1 1 1 1 1 1
1 0 0 0 0 0 1
1 0 0 0 0 0 1
1 0 0 0 0 0 1
1 0 0 0 0 0 1
1 0 0 0 0 0 1
1 1 1 1 1 1 1 //定义的二维数组是int mg[30][30];如果不弄外墙,就会
把输入的行列的外面

1 1 1 1 1 1 1 0 0 0 0 0 0
1 0 0 0 0 0 1 0 0 0 0 0 0
1 0 0 0 0 0 1 0 0 0 0 0 0
1 0 0 0 0 0 1 0 0 0 0 0 0
1 0 0 0 0 0 1 0 0 0 0 0 0
1 0 0 0 0 0 1 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0实际上的数组,我只选择了外墙里面的。

#include<stdio.h>
//#define M 4
#define N 6
#define MaxSize 100



//int N=10;

int mg[30][30];

struct{
	
	int i,j;
	int di;
}St[MaxSize],path[MaxSize];


int top=-1;
int count=1;
int minlen=MaxSize;


int n=6;

void  dispapath(){
	int k;
	printf("这个数是%5d\n",count++);
	for(k=0;k<=top;k++) 
	
		printf("(%d,%d)",St[k].i,St[k].j);
		printf("\n");
		
		
		if(top+1<minlen){
			
			
			
			for(int k=0;k<=top;k++)  //这里注意修改为  k<=top; 
				
		path[k]=St[k];
		minlen=top+1; //这里minlen改变了值 第一个1. 
		
			
		}
		
		
		
		
	}
	

	
	
void dispminpath()
{

	printf("最短路径如下:\n"); 
printf("长度:%d",minlen);
for(int k=0;k<minlen;k++){
	
	
printf("(%d,%d)",path[k].i,path[k].j);




	
}	
printf("\n");
	
	}
	
	
	void mgpath(int xi,int yi,int xe,int ye){//1,1,4,4 
	printf("执行这个\n");
	
	
	/*for(int i=0;i<20;i++){
		for(int j=0;j<20;j++){
			
			
			printf("%d",mg[i][j]);
		} 
	}
	
	
	*/ 
	
	
		int i,j,i1,j1,di;
		
		bool find;
		top++;
		St[top].i=xi; //1,1 xi=1,yi=1. 存储移动的位置 
		St[top].j=yi;
		
		St[top].di=-1;
		mg[xi][yi]=-1; // mg[1][1]=-1;把走过的位置改为-1. 防止 
		
		
		while(top>-1){
			
			i=St[top].i;
			j=St[top].j;
			di=St[top].di;
			
			
			if(i==xe&&j==ye){//终点 
				
				dispapath();
				mg[i][j]=0;
				top--; //这里top会减减 
				
				i=St[top].i;//
				j=St[top].j;
				
				
				
				di=St[top].di;
				
			}  // 
			
			find=false;
			
			
			while(di<4&&!find){ //这里开始移动 
				
				di++; //这个开始加 从0,1,2,3,四个方向 
				switch(di){
					
					
					case 0: i1=i-1;j1=j;  break; //用i1,和j1代表移动的位置 :向左移动一步 
					case 1: i1=i;j1=j+1;  break;//向下面移动一步 
					case 2: i1=i+1;j1=j;  break;
					case 3: i1=i1;j1=j-1;  break;//向上面移动一步 
					
					
					
				}
				if(mg[i1][j1]==0) find=true;//只要存在一个位置 mg[i1][j1]==0,结束循环 
				
				
				
				
				
			}
			
			
			
			if(find){
				
				
				St[top].di=di;
				top++;  //这里top变化了:2,3,4 
				St[top].i=i1;  St[top].j=j1;// St[2].i=i1;
				
				St[top].di=-1;
				mg[i1][j1]=-1;//把这个值变成-1; 
				
				
			}
			
			else{
				
				mg[i][j]=0;
				top--;
			}
		}
		
		
		
		
		
		
		dispminpath(); 	
		
		
	} 
	
	
	
	
	//
	
	

	

int main(){
	
//int mg[10][10];
//	printf("请输入迷宫有多少行多少列/n");
///	scanf("%d",&N); 
	
	
/*	int mg[6][6]={
{1,1,1,1,1,1},//   0行0列开始   
{1,0,0,1,1,1},//1行 
{1,1,0,1,1,1},//2 行 
{1,1,0,1,1,1},
{1,1,0,0,0,1},//起点(1,1)    终点是(4,4) 
{1,1,1,1,1,1}


};
*/

int m,n;
scanf("%d%d",&m,&n);
//int mg[m][6];

for(int i=0;i<m;i++){
	
	for(int j=0;j<n;j++){
		
		
		scanf("%d",&mg[i][j]);
	}
} 

	
//*/	
	
	
printf("迷宫的所有路径:\n");

mgpath(1,1,m-2,n-2); //外面是围墙 
return 0;	
	
	
}

在这里插入图片描述

3.更新迷宫3:

给定一个M行N列的迷宫图,其中 “0"表示可通路,“1"表示障碍物,无法通行。在迷宫中只允许在水平或上下四个方向的通路上行走,走过的位置不能重复走。
5行8列的迷宫如下:
0 1 1 1 0 0 0 0
0 0 0 1 0 0 0 0
0 1 0 0 0 1 0 0
0 1 1 1 0 1 1 0
1 0 0 0 0 0 0 0
则从左上角(1,1)至右下角(5,8)的最短路径为:
1,1–》2,1–》2,2–》2,3–》3,3–》3,4–》3,5–》4,5–》5,5–》5,6–》5,7–》5,8
题目保证每个迷宫最多只有一条最短路径。
请输出该条最短路径,如果不存在任何通路,则输出"NO FOUND”.
输入格式:
第一行,输入M和N值,表示迷宫行数和列数。
接着输入M行数值,其中,0表示通路,1表示障碍物。每列数值用空格符间隔。
接下来可能输入多组迷宫数据。
当输入M的值为-1时结束输入。
输出格式:
按行顺序输出路径的每个位置的行数和列数,如 x,y
如果不存在任何路径,则输出"NO FOUND”.
每组迷宫寻路结果用换行符间隔。
输入样例:
在这里给出一组迷宫。例如:
8 8
0 0 1 0 0 0 1 0
0 0 1 0 0 0 1 0
0 0 0 0 1 1 0 0
0 1 1 1 0 0 0 0
0 0 0 1 0 0 0 0
0 1 0 0 0 1 0 0
0 1 1 1 0 1 1 0
1 0 0 0 0 0 0 0
4 4
0 0 1 0
0 0 0 0
0 0 1 1
0 1 0 0
-1 -1
输出样例:
在这里给出相应的输出。例如:
1,1
2,1
3,1
4,1
5,1
5,2
5,3
6,3
6,4
6,5
7,5
8,5
8,6
8,7
8,8

NO FOUND
结尾无空行

#include<stdio.h>
//#define M 4
#define N 6
#define MaxSize 100



//int N=10;

//int mg[30][30];

struct{
	
	int i,j;
	int di;
}St[MaxSize],path[MaxSize];


int top=-1;
int count=0;
int minlen=MaxSize;


int n=6;

void  dispapath(){  // 全部路径
	int k;
	count=count+1;
	
	
	 
/*	printf("这个数是%5d\n",count);
	for(k=0;k<=top;k++) 
	
		printf("(%d,%d)",St[k].i+1,St[k].j+1);
		printf("\n");
		
		
		
		
	
	*/		
			
			
		
		
		if(top+1<minlen){
			
			
			if(count!=0){
			
			
			for(int k=0;k<=top;k++)  //这里注意修改为  k<=top; 
				
		//path[k]=St[k];
		{
			path[k].i=St[k].i+1;
		path[k].j=St[k].j+1;
		}
		minlen=top+1; //这里minlen改变了值 第一个1. 
		
		
		
		
			
		}
		
		
}
		
	}
	

	
	
void dispminpath()
{
if(count!=0){
//	printf("最短路径如下:\n"); 
//printf("长度:%d",minlen);
for(int k=0;k<minlen;k++){
	
	
printf("%d,%d",path[k].i,path[k].j);
printf("\n");




	
}	

	
	}}
	
	
	void mgpath(int xi,int yi,int xe,int ye,int mg[][6]){//1,1,4,4 
	printf("执行这个\n");
	
	
	for(int i=0;i<6;i++){
		for(int j=0;j<6;j++){
			
			
			printf("%d",mg[i][j]);
		} 
		printf("\n");
	}
	
	
	
	
	
		int i,j,i1,j1,di;
		
		bool find;
		top++;
		St[top].i=xi; //1,1 xi=1,yi=1. 存储移动的位置 
		St[top].j=yi;
		
		St[top].di=-1;
		mg[xi][yi]=-1; // mg[1][1]=-1;把走过的位置改为-1. 防止 
		
		
		while(top>-1){
			
			i=St[top].i;
			j=St[top].j;
			di=St[top].di;
			
			
			if(i==xe&&j==ye){//终点 
				
				dispapath();
				mg[i][j]=0;
				top--; //这里top会减减 
				
				i=St[top].i;//
				j=St[top].j;
				
				
				
				di=St[top].di;
				
			}  // 
			
			
		
			
			find=false;
			
			
			while(di<4&&!find){ //这里开始移动 
				
				di++; //这个开始加 从0,1,2,3,四个方向 
				switch(di){
					
					
					case 0: i1=i-1;j1=j;  break; //用i1,和j1代表移动的位置 :向左移动一步 
					case 1: i1=i;j1=j+1;  break;//向下面移动一步 
					case 2: i1=i+1;j1=j;  break;
					case 3: i1=i1;j1=j-1;  break;//向上面移动一步 
					
					
					
				}
				if(mg[i1][j1]==0) find=true;//只要存在一个位置 mg[i1][j1]==0,结束循环 
				
				
				
				
				
			}
			
			
			
			if(find){
				
				
				St[top].di=di;
				top++;  //这里top变化了:2,3,4 
				St[top].i=i1;  St[top].j=j1;// St[2].i=i1;
				
				St[top].di=-1;
				mg[i1][j1]=-1;//把这个值变成-1; 
				
				
			}
			
			else{
				
				mg[i][j]=0;
				top--;
			}
		}
		
		
		if(count==0){
			
			
			printf("NO FOUND\n");
		}
		
		
		
		
		
		
		dispminpath(); 	
		
		
	} 
	
	
	
	
	//
	
	

	

int main(){
	
//int mg[10][10];
//	printf("请输入迷宫有多少行多少列/n");
///	scanf("%d",&N); 
	
	
int mg[6][6]={
{0,0,0,0,0,1},//   0行0列开始   
{1,0,0,0,0,1},//1行 
{1,0,0,0,0,1},//2 行 
{1,0,0,0,0,1},
{1,0,0,0,0,1},//起点(1,1)    终点是(4,4) 
{0,0,0,0,0,0}


};




int m,n;


//scanf("%d%d",&m,&n);




//scanf("%d%d",&m,&n);
//int mg[m][6];

/*for(int i=0;i<m;i++){
	
	for(int j=0;j<n;j++){
		
		
		scanf("%d",&mg[i][j]);
	}
} 

	
*/	
	
	
	
	
	
	
printf("迷宫的所有路径:\n");

mgpath(0,0,5,5,mg); //外面是围墙 
return 0;	
	
	
}

在这里插入图片描述

4.更新迷宫4:(完整补充)

#include<stdio.h>
//#define M 4
#define N 6
#define MaxSize 100


//int m=9;
//int N=10;
//int  *p;

int mg[30][30];

int e,t;

struct{
	
	int i,j;
	int di;
}St[MaxSize],path[MaxSize];


int top=-1;
int count=0;
int minlen=MaxSize;


int n=6;

void  dispapath(){  // 全部路径
	int k;
	count=count+1;
	
	
	 
/*	printf("这个数是%5d\n",count);
	for(k=0;k<=top;k++) 
	
		printf("(%d,%d)",St[k].i+1,St[k].j+1);
		printf("\n");
		
*/		
		
		
	
		
			
			
		
		
		if(top+1<minlen){
			
			
			if(count!=0){
			
			
			for(int k=0;k<=top;k++)  //这里注意修改为  k<=top; 
				
		//path[k]=St[k];
		{
			path[k].i=St[k].i+1;
		path[k].j=St[k].j+1;
		}
		minlen=top+1; //这里minlen改变了值 第一个1. 
		
		
		
		
			
		}
		
		
}
		
	}
	

	
	
void dispminpath()
{
if(count!=0){
//	printf("最短路径如下:\n"); 
//printf("长度:%d",minlen);
for(int k=0;k<minlen;k++){
	
	
printf("%d,%d",path[k].i,path[k].j);
printf("\n");




	
}	

	
	}}
	
	
	void mgpath(int xi,int yi,int xe,int ye){//1,1,4,4 
	
	
	int mgt[xe+1][ye+1];
	
	
	
//	printf("执行这个\n");
	
	
for(int i=0;i<xe+1;i++){
		for(int j=0;j<ye+1;j++){
			
			
		//	printf("%d",mg[i][j]);
			
			
			
			mgt[i][j]=mg[i][j];
			//	printf("%d",mgt[i][j]);
		} 
	//	printf("\n");
	}
	

	
	
	
		int i,j,i1,j1,di;
		
		bool find;
		top++;
		St[top].i=xi; //1,1 xi=1,yi=1. 存储移动的位置 
		St[top].j=yi;
		
		St[top].di=-1;
		mgt[xi][yi]=-1; // mg[1][1]=-1;把走过的位置改为-1. 防止 
		
		
		while(top>-1){
			
			i=St[top].i;
			j=St[top].j;
			di=St[top].di;
			
			
			if(i==xe&&j==ye){//终点 
				
				dispapath();
				mgt[i][j]=0;
				top--; //这里top会减减 
				
				i=St[top].i;//
				j=St[top].j;
				
				
				
				di=St[top].di;
				
			}  // 
			
			
		
			
			find=false;
			
			
			while(di<4&&!find){ //这里开始移动 
				
				di++; //这个开始加 从0,1,2,3,四个方向 
				switch(di){
					
					
					case 0: i1=i-1;j1=j;  break; //用i1,和j1代表移动的位置 :向左移动一步 
					case 1: i1=i;j1=j+1;  break;//向下面移动一步 
					case 2: i1=i+1;j1=j;  break;
					case 3: i1=i1;j1=j-1;  break;//向上面移动一步 
					
					
					
				}
				if(mgt[i1][j1]==0) find=true;//只要存在一个位置 mg[i1][j1]==0,结束循环 
				
				
				
				
				
			}
			
			
			
			if(find){
				
				
				St[top].di=di;
				top++;  //这里top变化了:2,3,4 
				St[top].i=i1;  St[top].j=j1;// St[2].i=i1;
				
				St[top].di=-1;
				mgt[i1][j1]=-1;//把这个值变成-1; 
				
				
			}
			
			else{
				
				mgt[i][j]=0;
				top--;
			}
		}
		
		
		if(count==0){
			
			
			printf("NO FOUND\n");
		}
		
		
		
		
		
		
		dispminpath(); 	
		
		
	} 
	
	
	
	
	//
	
	

	

int main(){
	
//int mg[10][10];
//	printf("请输入迷宫有多少行多少列/n");
///	scanf("%d",&N); 
	
	
/*int mg[6][6]={
{0,0,0,0,0,1},//   0行0列开始   
{1,0,0,0,0,1},//1行 
{1,0,0,0,0,1},//2 行 
{1,0,0,0,0,1},
{1,0,0,0,0,1},//起点(1,1)    终点是(4,4) 
{0,0,0,0,0,0}


};
*/





int m=1,n=1;

//int mg[m][n];



	scanf("%d%d",&m,&n);

while(m!=-1){
	
//	printf("迷宫的所有路径:\n");


if(m!=-1){
	for(int i=0;i<m;i++){
	
	for(int j=0;j<n;j++){
		
		
		scanf("%d",&mg[i][j]);
	}
}
};

mgpath(0,0,m-1,n-1);



//	printf("迷宫的所有路径:\n");


	scanf("%d%d",&m,&n);
	
}












//scanf("%d%d",&m,&n);




//scanf("%d%d",&m,&n);
//int mg[m][6];

	
	
	
	
	
	
	
//printf("迷宫的所有路径:\n");


/*if(m!=-1){
	printf("迷宫的所有路径:\n");

scanf("%d%d",&m,&n);



for(int i=0;i<m;i++){
	
	for(int j=0;j<n;j++){
		
		
		scanf("%d",&mg[i][j]);
	}
} 





*/ 


//mgpath(0,0,5,5); //外面是围墙 



return 0;	
	
	
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

半浮名

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值