代码如下:
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;
}