您的位置:首页 > 理论基础 > 数据结构算法

【数据结构】求多出口带环迷宫的最短路径(递归版本)

2018-02-03 22:17 351 查看
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<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 Mark(Pos* pos, int Map[7][7], int len) {
if (pos == NULL) {
return;
}
Map[pos->_Row][pos->_COL] = len;
}

/*检查是否可以形成通路*/
int CanWalk(Pos* pos, int Map[7][7], int len_num) {
if (pos == NULL) {
return;
}
/*lennum表示当前路径的长度,如果小的话就走不通*/
if (Map[pos->_Row][pos->_COL] == 1 || len_num < Map[pos->_Row][pos->_COL]) {
return 1;
}
return 0;
}

/*检查出口*/
int CheckExport(Pos* pos, int Map[7][7]) {
if (pos == NULL) {
return;
}
if (pos->_Row == 0 || pos->_COL == 0 ||
pos->_Row == 6 || pos->_COL == 6) {
/*该点在地图边上*/
if ( Map[pos->_Row][pos->_COL] != 0) {
/*该点是出口*/
return 1;
}
}
return 0;
}

/*len的row表示路径长度,col表示总共有几条路径*/
int _GetPath(Pos* entry, Pos* pos, SeqStack* stack, int Map[7][7], Pos* len) {

if (pos == NULL) {
return;
}
/*判断出口点是否在地图上*/
if (!CanStay(entry)) {
return 0;
}
++len->_Row;
Mark(pos, Map, len->_Row);

/*递归出口*/
if (len->_Row != 2) {
if (CheckExport(pos, Map)) {
++len->_COL;
/*是出口,比较长度大小然后把该出口点入栈*/
if (SeqStackEmpty(stack)) {
/*判断是否为空栈*/
/*把当前的点和len入栈*/
SeqStackPush(stack, *pos);
SeqStackPush(stack, *len);
}
else {
Pos pos2 = SeqStackTopValue(stack);
if ((*len)._Row < pos2._Row) {
/*表示当前路径更短*/
SeqStackPush(stack, *pos);
SeqStackPush(stack, *len);
}
}
--len->_Row;
return;
}
}

/*上*/
--pos->_Row;
if (CanStay(pos)) {
if (CanWalk(pos, Map, len->_Row)) {
/*当前点可以走*/
_GetPath(entry, pos, stack, Map, len);
}
}
++pos->_Row;
/*下*/
++pos->_Row;
if (CanStay(pos)) {
if (CanWalk(pos, Map, len->_Row)) {
_GetPath(entry, pos, stack, Map, len);
}
}
--pos->_Row;
/*左*/
--pos->_COL;
if (CanStay(pos)) {
if (CanWalk(pos, Map, len->_Row)) {
_GetPath(entry, pos, stack, Map, len);
}
}
++pos->_COL;
/*右*/
++pos->_COL;
if (CanStay(pos)) {
if (CanWalk(pos, Map, len->_Row)) {
_GetPath(entry, pos, stack, Map, len);
}
}
--pos->_COL;

/*当前点的四周现在都走不通了*/
/*判断当前点是不是出口点*/
if (pos->_Row == entry->_Row && pos->_COL == entry->_COL) {

if (SeqStackEmpty(stack)) {
return 0;
}
return 1;
}
/*如果不是出口,而这个点又走不通,就先返回一波*/
--len->_Row;
return;
}

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 },
{ 1, 1, 1, 1, 1, 1, 1 },
{ 0, 0, 0, 0, 0, 1, 0 },
{ 0, 0, 0, 0, 0, 1, 0 },
};
SeqStack stack;
SeqStackInit(&stack);
Pos entry;
Pos pos;
Pos len;
/*初始化*/
entry._Row = 0;
entry._COL = 1;
pos = entry;
len._Row = 1;
len._COL = 0;

int i = _GetPath(&entry, &pos, &stack, Map, &len);
if (i == 0) {
printf("未找到路径");
}
else {
Pos length = SeqStackTopValue(&stack);
/*因为地图标记的原因,所以一开始初始化为1,把入口点标记为2了,所以路径长度需要减个1才是真实长度*/
--length._Row;
printf("找到%d条路径,最短路径长度为%d\n", len._COL, length._Row);
SeqStackPop(&stack);
pos = SeqStackTopValue(&stack);
printf("最短路径的出口点为:[%d, %d]\n", pos._Row, pos._COL);
}
system("pause");
return 0;
}


//递归版本的代码比较简单
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: