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

【数据结构】求简单迷宫是否存在路径(递归和非递归版)

2018-02-01 17:58 387 查看
求简单迷宫是否存在路径

代码中用到的栈代码如下:

stack.h

#pragma once

#include<stdio.h>
#include<stddef.h>
#include"Maze.h"

typedef Pos SeqType;

#define SEQDATAMAX 1000

/*创建一个栈的结构体*/
typedef struct SeqStack{
SeqType data[SEQDATAMAX];
int top;
int bottom;
}SeqStack;

/*初始化栈*/
void SeqStackInit(SeqStack* seq);
/*从栈里面压入一个元素*/
void SeqStackPush(SeqStack* seq, SeqType value);
/*出栈一个元素*/
void SeqStackPop(SeqStack* seq);
/*取栈顶元素*/
SeqType SeqStackTopValue(SeqStack* seq);
/*销毁栈*/
void SeqStackDestory(SeqStack* seq);
/*判断当前栈是不是空栈*/
int SeqStackEmpty(SeqStack* seq);


stack.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"Stack.h"

/*初始化栈*/
void SeqStackInit(SeqStack* seq) {

seq->top = 0;
seq->bottom = seq->top;
}
/*从栈里面压入一个元素*/
void SeqStackPush(SeqStack* seq, SeqType value) {

if (seq == NULL) {
return;
}
/*判断栈是不是已经满了*/
if (seq->top == SEQDATAMAX - 1) {
return;
}
seq->top++;
seq->data[seq->top] = value;
}
/*删除栈顶元素,出栈一个元素*/
void SeqStackPop(SeqStack* seq) {

if (seq == NULL) {
return;
}
/*判断栈是否为空栈*/
if (seq->top == seq->bottom) {
printf("栈为空");
return;
}
seq->top--;
}
/*取栈顶元素*/
SeqType SeqStackTopValue(SeqStack* seq) {

if (seq == NULL) {
return;
}
return seq->data[seq->top];
}

/*销毁栈*/
void SeqStackDestory(SeqStack* seq) {

if (seq == NULL) {
return;
}
seq->top = 0;
}

/*判断当前栈是不是空栈*/
int SeqStackEmpty(SeqStack* seq) {
if (seq == NULL) {
return;
}
if (seq->top == seq->bottom) {
return 1;
}
return 0;
}


非递归版代码如下:

maze.h

#pragma once

#include<stdio.h>

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

int maze[5][5] = { { 0, 1, 0, 0, 0 },
{ 0, 1, 1, 1, 0 },
{ 0, 1, 0, 1, 1 },
{ 1, 1, 0, 1, 0 },
{ 0, 0, 0, 1, 0 },
};
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;
}
/*行和列 小于0, 或者行也列大于5*/
if (pos->_Row < 0 || pos->_COL < 0
|| pos->_Row > 4 || pos->_COL > 4) {
/*表示该点的行和列在迷宫外面*/
return 0;
}
return 1;
}

/*标记当前点*/
void Mark(Pos* Pos, int Maze[5][5]) {
if (Pos == NULL) {
return;
}
Maze[Pos->_Row][Pos->_COL] = 2;
}
/*判断该点是不是出口*/
int Check_Export(Pos* Pos, int Maze[5][5]) {

if (Pos == NULL) {
return;
}

/*该点在迷宫地图内*/
/*该点在地图边界*/
if (Pos->_Row == 0 || Pos->_COL == 0 || Pos->_Row == 4 || Pos->_COL == 4) {

if (Maze[Pos->_Row][Pos->_COL] == 1) {
/*该点等于1,是出口*/
return 1;
}
}
return 0;
}

/*判断是否能形成通路*/
int Can_go(Pos* pos, int Maze[5][5]) {

if (pos == NULL) {
return;
}
/*如果当前点为1,则可以走*/
if (Maze[pos->_Row][pos->_COL] == 1) {
return 1;
}
return 0;
}

/*得到出口路径*/
/*传入入口点和一个地图*/
int Get_Path(Maze* entry, int Maze[][5]) {
if (entry == NULL) {
return;
}
/*判断入口点能否落脚*/
if (!CanStay(entry)) {
return;
}
SeqStack seq;
SeqStackInit(&seq);

//标记入口点,然后入栈入口点
Mark(entry, Maze);
SeqStackPush(&seq, entry->pos);
Pos pos;
pos = entry->pos;
/*进入循环,循环停止条件是走到出口*/
while (!Check_Export(&pos, Maze)) {

/*进入循环了已经把入口点标记了,然后开始判断当前的点周围的四个点是否可以走*/

/*上*/
/*当前点的行加个1*/
pos._Row -= 1;
/*如果能落脚,在地图上*/
if (CanStay(&pos, Maze)) {
/*判断该点是否能走*/
if (Can_go(&pos, Maze)) {
/*能走,判断是否为出口点*/
if (Check_Export(&pos, Maze)) {
break;
}
/*,标记该点把该点入栈*/
Mark(&pos, Maze);
SeqStackPush(&seq, pos);
continue;
}
}
pos._Row += 1;

/*下*/
pos._Row += 1;
if (CanStay(&pos, Maze)) {
if (Can_go(&pos, Maze)) {
/*可以走*/
if (Check_Export(&pos, Maze)) {
break;
}
Mark(&pos, Maze);
SeqStackPush(&seq, pos);
continue;
}
}
pos._Row -= 1;

/*左*/
pos._COL -= 1;
if (CanStay(&pos, Maze)) {
if (Can_go(&pos, Maze)) {
/*可以走*/
/*判断是不是出口点,如果是,就直接退出,找到该点了*/
if (Check_Export(&pos, Maze)) {
break;
}
Mark(&pos, Maze);
SeqStackPush(&seq, pos);
continue;
}
}
pos._COL += 1;

/*右*/
pos._COL += 1;
if (CanStay(&pos, Maze)) {
if (Can_go(&pos, Maze)) {
/*可以走*/
if (Check_Export(&pos, Maze)) {
break;
}
Mark(&pos, Maze);
SeqStackPush(&seq, pos);
continue;
}
}
pos._COL -= 1;

/*每个点都走不了了,如果这个点是入口点,表示没有出口?*/
if (pos._COL == entry->pos._COL && pos._Row == entry->pos._Row) {
return 0;
}
/*
**每个点都走不了了
**这个时候出栈一个元素
**然后让pos等于当前栈的栈顶元素(回溯)
*/
SeqStackPop(&seq);
pos = SeqStackTopValue(&seq);
}
/*如果退出while循环,表示找到了出口点*/
return 1;
}

int main() {

/*只是判断有无出口*/
Maze entry_pos;
entry_pos.pos._Row = 0;
entry_pos.pos._COL = 1;
int path = Get_Path(&entry_pos,	maze);
printf("expect 1, actual: %d", path);
system("pause");
return 0;
}


递归版代码如下:

maze.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"Maze.h"
#include"Stack.h"

int Canstay(Pos* pos) {
/*判断当前点是否在地图上*/
if (pos == NULL) {
return;
}
if (pos->_Row < 0 || pos->_COL < 0 ||
pos->_Row > 4 || pos->_COL > 4) {
/*该坐标不在地图内*/
return 0;
}
return 1;
}

/*判断该点是否为出口*/
int Check_Export(Pos* pos, int Maze[5][5]) {
if (pos == NULL) {
return;
}
/*先判断该坐标是否在地图上*/
if (pos->_Row == 0 || pos->_COL == 0 ||
pos->_Row == 4 || pos->_COL == 4) {

if (Maze[pos->_Row][pos->_COL] == 1) {
printf("出口点坐标为:(%d, %d)", pos->_Row, pos->_COL);
return 1;
}
}
return 0;
}

/*标记该点*/
void Mark(Pos* pos, int Maze[5][5]) {

if (pos == NULL) {
return;
}
Maze[pos->_Row][pos->_COL] = 2;
}
/*判断当前点是否是通路*/
int Can_Walk(Pos* pos, int Maze[5][5]) {
if (pos == NULL) {
return;
}
if (Maze[pos->_Row][pos->_COL] == 1) {
return 1;
}
return 0;
}

int _GetPath(Pos* entry, Pos* pos, int Maze[5][5]) {
/*pos就是当前点*/
if (entry == NULL) {
return;
}
/*判断当前点是否在地图上*/
if (!Canstay(entry)) {
return 0;
}
/*标记入口点,然后把入口点压栈*/
Mark(entry, maze);
//SeqStack seq;
//SeqStackPush(&seq, *entry);

/*开始递归*/
/*递归出口*/
if (Check_Export(pos, Maze)) {
return 1;
}
else {
/*如果pos不是出口,就标记它*/
Mark(pos, Maze);
}

/*上*/
--pos->_Row;
/*判断坐标是不是在地图上*/
if (Canstay(pos)) {
/*如果在地图内,判断该点是否可以走*/
if (Can_Walk(pos, Maze)) {
/*把该点标记下*/
/*判断子问题是否成功找到通路*/
if (_GetPath(entry, pos, Maze)) {
return 1;
}
}
}
++pos->_Row;

/*下*/
++pos->_Row;
if (Canstay(pos)) {
if (Can_Walk(pos, Maze)) {
if (_GetPath(entry, pos, Maze)) {
return 1;
}
}
}
--pos->_Row;

/*左*/
--pos->_COL;
if (Canstay(pos)) {
if (Can_Walk(po
4000
s, Maze)) {
if (_GetPath(entry, pos, Maze)) {
return 1;
}
}
}
++pos->_COL;
/*右*/
++pos->_COL;
if (Canstay(pos)) {
if (Can_Walk(pos, Maze)) {
if (_GetPath(entry, pos, Maze)) {
return 1;
}
}
}
--pos->_COL;

/*到了这里,表示该点走不通*/
return 0;
}

int main() {
/*不是最优解最短路径的递归求法*/
Pos entry;
Pos pos;
entry._Row = 0;
entry._COL = 1;

pos = entry;
int i = _GetPath(&entry, &pos, maze);
printf("expect 1, actual: %d", i);
system("pause");
return 0;
}

简单迷宫的递归和非递归代码就这样了,地图在头文件里
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐