栈的应用-迷宫问题-数据结构

栈的基本应用之一,解决迷宫问题,主要是利用栈的递归作用。

就是个搜索加回溯,写了两遍,第一遍小问题调到两点没调试出来,第二天干脆重新写了,一次就出来了。

后面几个例子运行了下没什么问题,可能有些问题暂时没发现,主要不像OJ,人家已经把数据构造好了,自己就懒的去构造数据了

例子代码:

#include<stdio.h>
#include<string.h>
#include<malloc.h>

#define Initstacksize 100
#define Increase 100


typedef struct PosType     //坐标 
{
	int x;
	int y;
}PosType; 

typedef struct MazeType
{
	char **maze;    //迷宫图 
	int **mark;    //标记位 
	int row;    //迷宫行数   
	int col;   //迷宫列数 
}MazeType;

typedef struct SElemType
{
	int ord;   //走的步数 
	PosType seat;   //坐标信息 
	int dir; //方向 
}SElemType;

typedef struct SqStack   //栈 
{
	SElemType *base;
	SElemType *top;
	int stacksize;
}SqStack;

void CreatMaze(MazeType &ma)  //构造迷宫 
{
	int i,j;
	char ch;
	printf("Input the row and the col of the maze:\n");
	scanf("%d%d",&ma.row,&ma.col);
	ma.maze=(char**)malloc(Initstacksize*sizeof(char*));
	ma.mark=(int**)malloc(Initstacksize*sizeof(int*));
	ch=getchar();
	for(i=0;i<ma.row;i++)
	{
		ma.maze[i]=(char*)malloc(Initstacksize*sizeof(char));
		ma.mark[i]=(int*)malloc(Initstacksize*sizeof(int));
		gets(ma.maze[i]);
		for(j=0;j<ma.col;j++)
			ma.mark[i][j]=0;
	}
}

void DisplayMaze(MazeType ma)  //迷宫验证 
{
	int i,j;
	for(i=0;i<ma.row;i++)
	{
		for(j=0;j<ma.col;j++)
			printf("%c",ma.maze[i][j]);
		printf("\n");	
	}
}

void InitStack(SqStack &s)  //初始化栈 
{
	s.top=s.base=(SElemType*)malloc(Initstacksize*sizeof(SElemType));
	s.stacksize=Initstacksize;
}

int PassOk(PosType std,MazeType maa)   //该点是否能通过 
{
	if(std.x<0 || std.y<0 || std.x>=maa.row || std.y>=maa.col || maa.maze[std.x][std.y]=='#' || maa.mark[std.x][std.y]>0)
			return 0;
	else return 1;
}

SElemType UpdatE(PosType p,int step,int di)  //更新坐标信息:坐标,步数,寻找方向 
{
	SElemType ee;
	ee.ord=step;
	ee.dir=di;
	ee.seat=p;
	return ee;
}

void PushStack(SqStack &S,SElemType ee)  //入栈 
{
	if(S.top-S.top>=S.stacksize)
	{
		S.base=(SElemType*)realloc(S.base,(Increase+Initstacksize)*sizeof(SElemType));
		S.top=S.base+S.stacksize;
		S.stacksize+=Increase;
	}
	*S.top++=ee;
}

bool EmptyStack(SqStack S)   //判断栈是否为空 
{
	if(S.base==S.top) return true;
	else return false;
}

void MakePrint(MazeType &maa,PosType p)  //可行路径的记录 
{
	maa.mark[p.x][p.y]=1;
}

PosType NextPos(PosType p,int di)  //下一步行走 
{
	PosType np;
	np=p;
	switch(di)
	{
		case 1:np.x++;break; //下 
		case 2:np.y++;break; //右 
		case 3:np.x--;break; //上 
		case 4:np.y--;break; //左 
		default:break; 
	}
	return np;
}

void PopStack(SqStack &ss,SElemType &ee)  //上一个点出栈 回退上一个点 
{
	ss.top--;
	ee=*ss.top;
}

void NoPrint(MazeType &maa,PosType p)  //寻找过程中的无效路径标记 
{
	maa.mark[p.x][p.y]=2;
}

int MazePath(MazeType ma,SqStack &s,PosType st,PosType ed)   //迷宫行走 
{
	PosType curpos;
	SElemType e;
	int curstep;
	curstep=1;
	curpos=st;
	if(!PassOk(st,ma)) return 0;//起点坐标OK 
	MakePrint(ma,curpos);    //做路径标记 
	e=UpdatE(curpos,curstep,1); //更新坐标信息 
	PushStack(s,e);  //起点入栈,作为回溯点 
	curpos=NextPos(curpos,1); //走下一步 
	curstep++;
	while(!EmptyStack(s)) 
	{
		if(PassOk(curpos,ma))
		{
			MakePrint(ma,curpos);
			e=UpdatE(curpos,curstep,1);
			PushStack(s,e);
			if(curpos.x==ed.x&& curpos.y==ed.y) return 1; //到达终点 
			curpos=NextPos(curpos,1);
			curstep++;
		}
		else
		{
			if(!EmptyStack(s))
			{
				PopStack(s,e);  //回退
				while(e.dir==4 && !EmptyStack(s))  //四个方向搜索过,都是无效点 
				{
					NoPrint(ma,e.seat);   //探索过的无效路径 
					PopStack(s,e);
				}
				if(e.dir<4)  //走完四个方向 
				{
					e.dir++;
					PushStack(s,e);  //因为有其他方向还没走过,所以回退的节点需要重新进栈,然后去探索下个节点 
					curpos=NextPos(e.seat,e.dir); //下一个位置 
				} 
			}//if
		}//else
	}//while 
	return 0;
}

void DisplayMarkPath(MazeType maa)  //打印路径, 
{
	int i,j;
	for(i=0;i<maa.row;i++)
	{
		for(j=0;j<maa.col;j++)
			printf("%d",maa.mark[i][j]);
		printf("\n");
	}
}

int main()
{
	MazeType Maze;
	SqStack stack;
	PosType start,end;
	int Ok;
	CreatMaze(Maze);  //构造迷宫 
	printf("///////////\n");
	DisplayMaze(Maze);   //验证构造迷宫 
	printf("///////////\n");
	InitStack(stack);  //初始化栈 
	printf("Input the start point and end point:\n");
	scanf("%d%d",&start.x,&start.y);
	scanf("%d%d",&end.x,&end.y);       //输入起点和终点 
	Ok=MazePath(Maze,stack,start,end);    //迷宫路径寻找 
	if(Ok) 
	{
		printf("Find the way out!\n");
		printf("Show the way:\n");
		DisplayMarkPath(Maze);
	}
	else
	{
		printf("No way out!\n");
		DisplayMarkPath(Maze);
	}
	 
	
	return 0;
}

/*
6 5
# ###
# ###
# #  
# # #
    #
#####
0 1
2 4

4 5
### #
    #
 ####
 ####
0 3
3 0 

10 10
# ########
# #    # #
# #    # #
#    ##  #
# ###    #
#   # # ##
# #   #  #
# ### ## #
##        
##########
0 1
8 9

10 10
# ########
# #    # #
# #    # #
#    ##  #
# ###    #
#   # # ##
# #   #  #
# ### ## #
##       # 
##########
0 1
8 8

10 10
# ########
# #    # #
# #    # #
#    ## ##
# ###    #
#   # # ##
# #   #  #
# ### ## #
##       #
##########
0 1
1 9
*/
    原文作者:迷宫问题
    原文地址: https://blog.csdn.net/B08370108/article/details/48546085
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞