用栈实现迷宫

18 篇文章 0 订阅

C语言没有自己的栈操作的一系列库函数,如果是C++,可以使用STL,所以自己用了自己以前写的栈函数。


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

typedef int NextDirectionType;
typedef struct{
	int row;
	int col;
}PosType;

typedef struct{
	PosType seat;//当前的位置信息
	NextDirectionType dir;//选择下一个位置的方向,分别为东南西北
}element;

//建立顺序栈
#define STACK_INIT_SIZE 100
#define STACKINCRESEMENT 10
typedef element DataType ;
typedef struct SqStack
{
	DataType *base;
	DataType *top;
	int stacksize;
}SqStack,* pSqStack;

//函数声明
pSqStack InitStack();
DataType GetTop(pSqStack s);
int IsStackEmpty(pSqStack  s);
void Push( pSqStack s,DataType x);
void Pop(pSqStack s,DataType *x);
int GetStackSize(pSqStack s);
void ClearStack(pSqStack s);
void DestroyStack(pSqStack s);
void Visit(int  data);
void StackTraverseFromBase(pSqStack s);

pSqStack InitStack()
{
	pSqStack s=(pSqStack) malloc(sizeof(SqStack));
	if(! s)
		return NULL;
	s->base=(DataType *) malloc(sizeof(DataType) *STACK_INIT_SIZE);
	if(! s->base)
		exit(-1);
	s->top=s->base;
	s->stacksize=STACK_INIT_SIZE;
	return s;
}

DataType GetTop(pSqStack s)
{
	if( !s)
	{
		printf("the stack initialization failed \n");
		exit(-1);
	}
	if(s->base==s->top)
	{
		printf("the stack is null\n");
		return ;
	}
	return *(s->top-1);
	//   return  *(--s->top); 
	//  return s->base[--s->top];

}

int IsStackEmpty(pSqStack  s)
{
	if( !s)
	{
		printf("the stack initialization failed \n");
		exit(-1);
	}
	if(s->base==s->top)
	{

		return 1;
	}
	return  0;

}

void Push( pSqStack s,DataType x)
{
	if( (s->top-s->base) >=s->stacksize)
	{
		s->base=(DataType *) realloc( s->base,(STACK_INIT_SIZE+STACKINCRESEMENT)*sizeof(DataType) ) ;
		if( !s->base)
			exit(-1);
		s->top=s->base + s->stacksize;
		s->stacksize+=STACKINCRESEMENT;

	}
	* s->top=x;
	s->top++;
}

void Pop(pSqStack s,DataType *x)
{
	if(s->base==s->top)
		printf("the stack is null,can't pop anything\n");
	// *x=s->base[--s->top];
	if(x!=NULL) // 为了和栈清空结合起来
		*x= *(--s->top);
	else
		--s->top;
}

int GetStackSize(pSqStack s)
{
	if(!s)
		exit(-1);
	return s->stacksize;
}

void ClearStack(pSqStack s)
{
	if(!s)
		exit(-1);
	while(s->base !=s->top) //或者 while( !IsSatckEmpty(s))
	{
		Pop(s, NULL);
	}
}

void DestroyStack(pSqStack s)
{
	if( !s)
		exit(-1);
	free(s->base);
	free(s);
}

void Visit(int  data)
{
	printf("%d ",data);
}



void StackTraverseFromBase(pSqStack s)
{
	DataType *p=s->base;  
	DataType data;
	while(p!=s->top)
	{
		char ch[4][4]={"->","↓","<-","↑"};	
		printf("(%d %d) 下一个位置的方向 :%s\n",(*p).seat.row, (*p).seat.col,ch[ (*p).dir ]);
		p++;
	}
}

//Maze.c

//Maze.c
//-------------------- 迷宫程序 ----------------------------------
/**//**************************************************************
	  迷宫问题算法: 从入口出发,顺着某一个方向进行探索,若能走通,则继续
	  前进;否则沿着原路退回,换一个方向继续探索,直至出口位置,求得一条通路,
	  假如所有可能的通路都探索到而未能达到出口,则所设定的迷宫没有通路.
	  说明:可通: 未增走到过的通道快.
	 *********************************************************/
#include<stdio.h>
#include"SqStack.c"

#define M 5
#define N 5
#define EXIT_ROW M
#define EXIT_COL N
#define true 1
#define false 0
typedef int bool;
//其中element结构体在SqStack中,因为对栈操作中用到了它
typedef struct{
	int horiz; //水平方向
	int vert;  //垂直方向
}offsets;
offsets move[4]=
{
        //这里注意它的方向东南西北和你用坐标表示(x,y),那种记法不一样,得从数组上来看a[i][j]中的i,j变化
	{0, 1},//东
	{1, 0},//南 
	{0,-1},//西
	{-1, 0} //北
};

int maze[M+2][N+2]; //迷宫的大小,为了防止边界检查,把四周都设置为1,即有墙
int mark[M+2][N+2]={0}; //标记走过的路径中的0,以免重复走该路径


//函数声明
void InitMaze();
void PrintMaze();
void MazePath();

//随机生成迷宫
void InitMaze()
{
	int i,j;
	srand((unsigned int) time(NULL));
	for(i=1;i<=M ;i++)
		for(j=1;j<=N;j++)
		{
			maze[i][j]=rand()%2;
		}
	maze[1][1]=0;//起始结点要为0,否则随机产生的迷宫没有意义
	maze[M][N]=0;

	//加上围墙

	//对行加围墙
	for(j=0; j<N+2 ;j++)
		maze[0][j]=1;

	for(j=0; j<N+2 ;j++)
		maze[M+2-1][j]=1;
	//对列加围墙
	for(i=0; i<M+2;i++)
		maze[i][0]=1;

	for(i=0; i<M+2 ;i++)
		maze[i][N+2-1]=1;
}

//打印迷宫
void PrintMaze()
{
        int x,y;
        x=1;
        y=1;
        printf("起点位置 :(%d %d).\n",x,y);
        x=M;
        y=N;
        printf("终点位置 :(%d %d).\n",x,y);
        printf("The maze :\n");
	int i,j;
	srand((unsigned int) time(NULL));
	for(i=0;i<M+2 ;i++)
	{
		for(j=0;j<N+2;j++)
		{
			printf("%d ",maze[i][j]);
		}
		printf("\n");
	}
	printf("\n");
}

void MazePath()
{
	mark[1][1]=1;
	bool find=false;

	pSqStack s=InitStack();
	element info ;
	info.seat.row=1;
	info.seat.col=1;
	info.dir=0;
	Push(s,info);

	while(! IsStackEmpty(s))
	{
		Pop(s,&info);
		int row=info.seat.row;
		int col=info.seat.col;
		int dir=info.dir;
		while( dir <4 && !find)
		{
			int next_row=row+move[dir].horiz; //下一个位置的row
			int next_col=col+move[dir].vert;  //下一个位置的col
			
			if(next_row==EXIT_ROW && next_col==EXIT_COL) //下一个位置为出口,则找到
				{
                                    find=true;
                                    info.seat.row=row; //把当前位置入栈,其实这4句不加入也可以,只是为了输出结果好看
				    info.seat.col=col; //否则离出口的前一步的位置没有输出。
				    info.dir=dir;
				    Push(s,info);
                                }
			else if(maze[next_row][next_col]==0 && mark[next_row][next_col]==0) //下一个位置为不是出口,且该路径没有走过
			{
				maze[next_row][next_col]=1;
				info.seat.row=row; //把当前位置入栈
				info.seat.col=col;
				info.dir=dir;
				Push(s,info);
                                row=next_row;//把下一个位置置为当前位置
			        col=next_col;
                                dir=0;   //且此时下一个位置方向重新选择
			}
                        else
                            dir++;
		}

		if(find)
		{
			printf("The path is :\n");
			StackTraverseFromBase(s);//把栈里面所存的路径输出,自栈底向栈顶输出
                        printf("(%d %d )终点\nGet the exit.Success!\n",EXIT_ROW,EXIT_COL);
			DestroyStack(s);//此时找到了,栈空间要释放。
			return;
		}
	}

	printf("The maze doesn't have a path\n");
	DestroyStack(s);

}
//test
int main()
{
	InitMaze();	
	PrintMaze();
	MazePath();
	return 1;
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值