【数据结构】求多出口带环迷宫的最短路径

这篇博客介绍了如何解决带有多个出口和循环的迷宫问题,探讨了寻找最短路径的算法实现。通过提供的代码(Maze.h 和 Maze.c),作者展示了具体的解决方案,帮助读者理解在复杂迷宫环境下找到最优路径的方法。
摘要由CSDN通过智能技术生成

代码如下:

Maze.h

#pragma once

#include<stdio.h>

typedef struct Pos{
	int _Row;
	int _COL;
}Pos;



typedef struct Maze{

	struct Pos pos;

}Maze;


Maze.c

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include"Maze.h"
#include"Stack.h"


int CanStay(Pos* pos) {
	if (pos == NULL) {
		return;
	}
	if (pos->_Row < 0 || pos->_COL < 0 ||
		pos->_Row > 6 || pos->_COL > 6) {
		/*表示该点不在地图上*/
		return 0;
	}
	return 1;
}

void MarkPos(Pos* pos, int Map[7][7], int* num) {
	if (pos == NULL) {
		return;
	}

	Map[pos->_Row][pos->_COL] = *num;
	(*num)++;
}

int CanWalk(Pos* pos, int Map[7][7], int num) {
	if (pos == NULL) {
		return;
	}
	/*判断是否可以形成通路*/
	if (Map[pos->_Row][pos->_COL] == 1 || num < Map[pos->_Row][pos->_COL]) {
		/*
		**如果当前点为1
		**num是当前点的路径长度,如果小于那个点的值,代表当前路径的长度是更短的
		*/
		return 1;
	}
	return 0;
}

int Check_Export(Pos* pos, int Map[7][7]) {
	if (pos == NULL) {
		return;
	}
	/*如果当前点在边界上,且为1*/
	if (pos->_Row == 0 || pos->_COL == 0 ||
		pos->_Row == 6 || pos->_COL == 6) {

		if (Map[pos->_Row][pos->_COL] != 0) {
			/*有可能该点已经走过但是不是最佳路径,在这里只需要判断是不是出口*/
			return 1;
		}
	}
	return 0;
}

int _GetPath(Pos* entry, Pos* pos, int Map[7][7], int num) {

	if (pos == NULL) {
		return;
	}
	/*判断入口点是否合法*/
	if (!CanStay(entry)) {
		return 0;
	}
	SeqStack stack1, stack2;
	SeqStackInit(&stack1);
	SeqStackInit(&stack2);

	Pos pos2;
	pos2._Row = 0;
	pos2._COL = 0;

	/*把入口点入栈并标记*/
	SeqStackPush(&stack1, *entry);
	MarkPos(entry, Map, &num);
	++pos2._Row;
	++pos2._COL;

	/*开始循环*/
	while (CanStay(pos)) {

		/*pos一开始是和entry相等的*/
		/*上*/
		--pos->_Row;
		if (CanStay(pos)) {
			/*如果当前点在地图上*/
			if (CanWalk(pos, Map, num)) {
				/*
				**代表pos上面的点可以走
				**判断该点是不是出口
				**如果是出口,就标记该点然后入栈pos,然后继续往下走
				**如果不是出口,也标记该点,然后入栈pos
				*/
				//标记该点
				MarkPos(pos, Map, &num);
				++pos2._Row;
				/*入栈pos*/
				SeqStackPush(&stack1, *pos);

				if (Check_Export(pos, Map)) {
					/*是出口*/
					if (SeqStackEmpty(&stack2)) {
						/*把pos位置也入栈*/
						SeqStackPush(&stack2, *pos);
						SeqStackPush(&stack2, pos2);
					}
					else {
						/*不是空栈就比大小*/
						Pos tmp = SeqStackTopValue(&stack2);
						if (pos2._Row < tmp._Row) {
							/*如果当前路径小,就入栈*/
							SeqStackPush(&stack2, *pos);
							SeqStackPush(&stack2, pos2);
						}
						/*反之就不入栈,继续走*/
					}
				}
				else {
					/*是通路,但是不是出口点*/
					continue;
				}
			}
		}
		++pos->_Row;		
		/*下*/
		++pos->_Row;
		if (CanStay(pos)) {

			if (CanWalk(pos, Map, num)) {
				/*可以走,就标记*/
				MarkPos(pos, Map, &num);
				++pos2._Row;

				/*入栈pos位置*/
				SeqStackPush(&stack1, *pos);
				if (Check_Export(pos, Map)) {
					/*是出口*/
					if (SeqStackEmpty(&stack2)) {
						/*因为stack2是空的,直接入栈pos2*/
						SeqStackPush(&stack2, *pos);
						SeqStackPush(&stack2, pos2);
					}
					else {
						/*不是空栈就比大小*/
						Pos tmp = SeqStackTopValue(&stack2);
						if (pos2._Row < tmp._Row) {
							/*如果当前路径小,就入栈*/
							SeqStackPush(&stack2, *pos);
							SeqStackPush(&stack2, pos2);
						}
						/*反之就不入栈,继续走*/
					}
				}
				else {
					continue;
				}
			}

		}
		--pos->_Row;
		/*左*/

		--pos->_COL;
		if (CanStay(pos)) {
			if (CanWalk(pos, Map, num)) {

				/*可以走,就标记,然后入栈,然后让路径长度pos2的row加1*/
				MarkPos(pos, Map, &num);
				SeqStackPush(&stack1, *pos);
				pos2._Row++;
				if (Check_Export(pos, Map)) {
					/*是出口*/
					if (SeqStackEmpty(&stack2)) {
						/*因为stack2是空的,直接入栈pos2*/
						SeqStackPush(&stack2, *pos);
						SeqStackPush(&stack2, pos2);
					}
					else {
						/*不是空栈就比大小*/
						Pos tmp = SeqStackTopValue(&stack2);
						if (pos2._Row < tmp._Row) {
							/*如果当前路径小,就入栈*/
							SeqStackPush(&stack2, *pos);
							SeqStackPush(&stack2, pos2);
						}
						/*反之就不入栈,继续走*/
					}
				}
				else {
					continue;
				}
			}
		}
		++pos->_COL;
		/*右*/
		++pos->_COL;
		if (CanStay(pos)) {

			if (CanWalk(pos, Map, num)) {
				MarkPos(pos, Map, &num);
				SeqStackPush(&stack1, *pos);
				pos2._Row++;
				if (Check_Export(pos, Map)) {
					if (SeqStackEmpty(&stack2)) {
						SeqStackPush(&stack2, *pos);
						SeqStackPush(&stack2, pos2);
					}
					else {
						Pos tmp = SeqStackTopValue(&stack2);
						if (pos2._Row < tmp._Row) {

							SeqStackPush(&stack2, *pos);
							SeqStackPush(&stack2, pos2);
						}
					}
				}
				else {
					continue;
				}
			}
		}
		--pos->_COL;

		/*
		**走到这一步,代表当前点的四周都走不了了
		**这时候判断当前点是不是入口点,如果是,就代表该地图已经全部找完了
		**直接返回,如果不是,就出栈stack1一个元素
		*/
		if (pos->_Row == entry->_Row && pos->_COL == entry->_COL) {
			break;
		}
		SeqStackPop(&stack1);
		pos2._Row--;
		--num;

		Pos top = SeqStackTopValue(&stack1);
		*pos = top;
	}

	/*出了循环,表示已经找完了*/
	if (SeqStackEmpty(&stack2)) {
		/*表示没有找到任何一条路径*/
		return 0;
	}
	pos2 = SeqStackTopValue(&stack2);
	return pos2._Row;
}

int main() {
	int Map[7][7] = {
		{ 0, 1, 0, 0, 0, 0, 0 },
		{ 0, 1, 1, 1, 1, 1, 0 },
		{ 0, 1, 0, 0, 0, 1, 0 },
		{ 0, 1, 0, 0, 0, 1, 0 },
		{ 0, 1, 1, 1, 1, 1, 1 },
		{ 0, 0, 0, 0, 0, 1, 0 },
		{ 0, 0, 0, 0, 0, 1, 0 },
	};
	Pos entry1;
	Pos pos1;
	entry1._Row = 0;
	entry1._COL = 1;

	pos1 = entry1;

	int num = 2;
	 int i = _GetPath(&entry1, &pos1, Map, num);
	 if (i == 0) {
		 printf("未找到路径");
	 }
	 else {
		 printf("最短路径长度为:%d", i);
	 }
	system("pause");
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值