堆栈穷举法走迷宫

迷宫问题实验

#define _CRT_SECURE_NO_WARNINGS

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

typedef struct MNode ElementType;
struct MNode {
	int X;
	int Y;
};
typedef struct SNode* PtrToSNode;
struct SNode {
	ElementType Data;
	PtrToSNode Next;
};
typedef PtrToSNode Stack;


Stack CreateStack(void);//创建一个栈
int IsEmpty_Stack(Stack);//判断栈是否为空
void Push(Stack, ElementType);//将元素放入栈中
ElementType Pop(Stack);//将元素从栈顶拿出
ElementType GetStackTop(Stack);//查看栈顶元素
void FindPath(ElementType, ElementType, int[][10]);
int Judge(ElementType, ElementType);

int main(void)
{
	int Map[10][10];//默认地图为10*10
	int i;
	int j;
	ElementType Entrance;
	ElementType Exit;

	printf("输入迷宫地图\n");
	for (i = 0; i < 10; i++) {
		for (j = 0; j < 10; j++) {
			scanf("%d", &Map[i][j]);
		}
	}
	do {
		printf("输入入口坐标\nX = ");
		scanf("%d", &Entrance.X);
		printf("Y = ");
		scanf("%d", &Entrance.Y);

		printf("输入出口坐标\nX = ");
		scanf("%d", &Exit.X);
		printf("Y = ");
		scanf("%d", &Exit.Y);
	} while (!Judge(Entrance, Exit));
	FindPath(Entrance, Exit, Map);
	return 0;
}

int CanPass(ElementType, int[][10]);//周围存在新的路径
ElementType FindNext(ElementType, int[][10]);//寻找下一个新的路径

void FindPath(ElementType Entrance, ElementType Exit, int Map[][10])
{
	Stack S;
	ElementType Now;

	Now = Entrance;//从起点开始
	S = CreateStack();
	do {
		if (CanPass(Now, Map)) {//若周围存在新的路径
			Push(S, Now);
			Map[Now.X][Now.Y] = -1;
			printf("(%d,%d) ", Now.X, Now.Y);
			if (Now.X == Exit.X && Now.Y == Exit.Y) {
			//如果找到出口,退出程序
				printf("\n");
				return;
			}
			else {//否则指向下一个新的路径
				Now = FindNext(Now, Map);
				Map[Now.X][Now.Y] = -1;
			}
		}
		else {//如果周围不存在新的路径
			//回到上一个位置
			Now = Pop(S);
			printf("(%d,%d) ", Now.X, Now.Y);
		}
	} while (!IsEmpty_Stack(S));
	printf("找不到出路");

}

int CanPass(ElementType Now, int Map[][10])
{
	if ((Map[Now.X + 1][Now.Y] == 1) || (Map[Now.X - 1][Now.Y] == 1) || (Map[Now.X][Now.Y + 1] == 1) || (Map[Now.X][Now.Y - 1] == 1))
	//如果四周有存在尚未探索过的路
		return 1;
	else
		return 0;
}
ElementType FindNext(ElementType Now, int Map[][10])
{
	ElementType TheNext;
	//逆时针寻找四周的尚未探索的路
	if (Map[Now.X + 1][Now.Y] == 1) {//从右方开始,逆时针
		TheNext.X = Now.X + 1;
		TheNext.Y = Now.Y;
	}
	else if (Map[Now.X][Now.Y - 1] == 1) {
		TheNext.X = Now.X;
		TheNext.Y = Now.Y - 1;
	}
	else if (Map[Now.X - 1][Now.Y] == 1) {
		TheNext.X = Now.X - 1;
		TheNext.Y = Now.Y;
	}
	else if (Map[Now.X][Now.Y + 1] == 1) {
		TheNext.X = Now.X;
		TheNext.Y = Now.Y + 1;
	}

	return TheNext;
}

int Judge(ElementType Entrance, ElementType Exit)
{
	//判断出入口坐标是否在地图范围外
	if (Entrance.X > 10 || Entrance.X < 0 || Exit.X > 10 || Exit.Y < 0)
		return 0;
	else
		return 1;
}
//下方为所用到的Stack函数原型
Stack CreateStack(void)
{
	Stack S = (Stack)malloc(sizeof(struct SNode));

	S->Next = NULL;

	return S;
}

int IsEmpty_Stack(Stack S)
{
	return (S->Next == NULL);
}

void Push(Stack S, ElementType Sdata)
{
	PtrToSNode P;

	P = (PtrToSNode)malloc(sizeof(struct SNode));//创建新的栈结点
	P->Data = Sdata;
	P->Next = S->Next;//将栈顶链接在新栈顶后
	S->Next = P;//将新栈顶链接在栈头后
}

ElementType Pop(Stack S)
{
	if (IsEmpty_Stack(S)) {
		printf("The Stack is Empty.");
		ElementType NoElement;

		NoElement.X = -1;
		NoElement.Y = -1;

		return NoElement;
	}
	else {
		PtrToSNode P;
		ElementType Sdata;

		P = S->Next;//找到栈顶结点
		Sdata = P->Data;//取出数据
		S->Next = P->Next;//栈头链接新的栈顶
		free(P);//释放原栈顶

		return Sdata;
	}
}

ElementType GetStackTop(Stack S)
{
	if (IsEmpty_Stack(S)) {
		printf("The Stack is empty.");
		ElementType NoElement;

		NoElement.X = -1;
		NoElement.Y = -1;

		return NoElement;
	}
	else
		return S->Next->Data;
}

测试用例:
0 0 0 0 0 0 0 0 0 0
0 1 1 0 1 1 1 0 1 0
0 1 1 0 1 1 1 0 1 0
0 1 1 1 1 0 0 1 1 0
0 1 0 0 0 1 1 1 1 0
0 1 1 1 0 1 1 1 1 0
0 1 0 1 1 1 0 1 1 0
0 1 0 0 0 1 0 0 1 0
0 0 1 1 1 1 1 1 1 0
0 0 0 0 0 0 0 0 0 0
1
1
8
8运行截图

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值