栈,迷宫,C,C++实现

//迷宫求解,用栈作为工具
//总体思路:先将首格入栈,设空格为0,非空格为1,
//若格子周围有空格则将该空格其入栈,若没则删除栈顶元素并对栈顶元素再找他四周有没有空格
// (只要入栈就将此格设为1,不走回头路。走进死胡同时原路返回,如果迷宫有解,就能回到周边有空格的地方)
//方法一与方法二的区别:
//方法一在结构体内可以只定义格子坐标(二维数组),每次不论是前进还是后退都找一遍四周有没有空格
//方法二要多定义一个方向值(direction)用于表示当前格子到下一格子的关系,这样就不用每次都判断四个方向了
//但方向值只能在确定下一个空格时才能赋值,默认为0,先入栈,再找空格,找到后再赋值
//我用1指北,顺时针方向标号
//若没空格返回上一个格子时,由于上一个格子有方向,可以按方向值查找,可避免走向已经走过的方向
#include<stdio.h>
#include<stdlib.h>
#define MAX 10
#define SPARE 3
//用二维数组初始化迷宫
int mg[10][10] = {
	{1,1,1,1,1,1,1,1,1,1},
	{1,0,0,1,0,0,0,1,0,1},
	{1,0,0,1,0,0,0,1,0,1},
	{1,0,0,0,0,1,1,0,0,1},
	{1,0,1,1,1,0,0,0,0,1},
	{1,0,0,0,1,0,0,0,0,1},
	{1,0,1,0,0,0,1,0,0,1},
	{1,0,1,1,1,0,1,1,0,1},
	{1,1,0,0,0,0,0,0,0,1},
	{1,1,1,1,1,1,1,1,1,1}
};
//结构体格子,图方便直接用方法二的了
typedef struct Box
{
	int i;
	int j;
	int di;
}Box;
typedef struct sqstack
{
	Box* top;
	Box* base;
	int size;
}Stack;
void Initstack(Stack* s)
{
	s->base = (Box*)malloc(MAX * sizeof(Box));
	if (s->base == NULL)
	{
		printf("开辟动态内存失败\n");
		return;
	}
	s->top = s->base;
	s->size = MAX;
}
void Push(Stack* s, Box b)
{
	if (s->top - s->base == s->size)
	{
		s->base = (Box*)realloc(s->base, (s->size + SPARE) * sizeof(Box));
		if (s->base == NULL)
		{
			printf("重新开辟动态内存失败\n");
			return;
		}
		s->top = s->base + s->size;
		s->size += SPARE;
	}
	*s->top++ = b;
}
char Pop(Stack* s)
{
	if (s->top == s->base)
	{
		printf("空栈\n");
		return;
	}
	s->top--;
}
Box Get(Stack* s)
{
	return *(s->top - 1);
}

//方法一:
//void Mazepath(int i, int j, int x, int y)
//{
//	Stack s;
//	Initstack(&s);
//	Box b = { i,j,0};
//	mg[i][j] = 1;
//	Push(&s, b);
// 由于前面已经入栈了起点,而只有格子四周都走不了才会出栈,则栈空只能说明无论怎么走路径都走不到终点
//	while (s.base != s.top)
//	{
		//if(i==x&&j==y)//到达终点
		//{
		//	Box* temp = s.base;
		//	while (temp != s.top)
		//	{
		//		printf("(%d,%d)\n", temp->i, temp->j);
		//		temp++;
		//	}		
		//	printf("结束");
		//	return;
		//}
//		if (mg[i - 1][j] == 0)
//		{
//			(s.top - 1)->di = 1;
//			Box tb = { --i,j,0 };
//			Push(&s, tb);
//			mg[i][j] = 1;
//		}
//		else if (mg[i][j+1] == 0)
//		{
//			(s.top - 1)->di = 2;
//			Box tb = { i,++j,0 };
//			Push(&s, tb);
//			mg[i][j] = 1;
//		}
//		else if (mg[i + 1][j] == 0)
//		{
//			(s.top - 1)->di = 3;
//			Box tb = { ++i,j,0 };
//			Push(&s, tb);
//			mg[i][j] = 1;
//		}
//		else if (mg[i][j-1] == 0)
//		{
//			(s.top - 1)->di = 4;
//			Box tb = { i,--j,0 };
//			Push(&s, tb);
//			mg[i][j] = 1;
//		}
//		else
//		{
//			Pop(&s);
//			i = (s.top - 1)->i;
//			j = (s.top - 1)->j;
//		}
//	}
//}

//方法二:
void Mazepath(int i, int j, int x, int y)
{
	Stack s;
	Initstack(&s);
	Box b = { i,j,0 };
	mg[i][j] = 1;
	Push(&s, b);
	while (s.base != s.top)
	{
		if (i == x && j == y)
		{
			Box* temp = s.base;
			while (temp != s.top)
			{
				printf("(%d,%d)\n", temp->i, temp->j);
				temp++;
			}
			printf("结束");
			return;
		}
		int find = 0;
		while (((s.top - 1)->di++) < 5 && find == 0)//通过di在刚入栈的格子四周找空格
		{
			int ti = i;
			int tj = j;
			switch ((s.top - 1)->di)
			{
			case 1: ti--; break;
			case 2: tj++; break;
			case 3: ti++; break;
			case 4: tj--; break;
			default: break;
			}
			if (mg[ti][tj] == 0)//如果找到就把坐标还给i,j
			{
				find = 1;
				mg[ti][tj] = 1;//不走回头路
				i = ti;
				j = tj;
			}
		}
		if (find)
		{
			Box tb = { i,j,0 };
			Push(&s, tb);
		}
		else//没找到,返回上格
		{
			Pop(&s);
			i = (s.top - 1)->i;
			j = (s.top - 1)->j;
		}
	}
}

int main()
{
	Mazepath(1,1,8,8);//四个参数为起点与终点的坐标
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值