【数据结构】求简单迷宫是否存在路径(递归和非递归版)
2018-02-01 17:58
387 查看
求简单迷宫是否存在路径
代码中用到的栈代码如下:
stack.h
stack.c
非递归版代码如下:
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
递归版代码如下:
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;
}
简单迷宫的递归和非递归代码就这样了,地图在头文件里
代码中用到的栈代码如下:
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;
}
简单迷宫的递归和非递归代码就这样了,地图在头文件里
相关文章推荐
- 【数据结构】求多出口迷宫的最短路径(递归版本)
- 【数据结构】求多出口带环迷宫的最短路径(递归版本)
- 采用邻接表存储结构,编写一个判别无向图中任意给定的两个顶点之间是否存在一条长度为k的简单路径的算法。
- 数据结构实验之图论十:判断给定图是否存在合法拓扑序列
- 迷宫求解路径:数据结构课设(c++)版
- 数据结构——用栈解决简单迷宫问题
- 两个二叉树结构是否相同(结构和数据都相同) -- 递归和非递归方法
- 数据结构之——迷宫递归求解
- 数据结构实验之图论十:判断给定图是否存在合法拓扑序列
- 数据结构示例之查看链表元素是否存在
- 数据结构实验之图论十:判断给定图是否存在合法拓扑序列
- iOS文件和文件夹的创建,删除,移动, 拷贝,是否存在及简单数据类型的读写
- 数据结构实验之图论十:判断给定图是否存在合法拓扑序列
- 二叉树(10)----比較两个二叉树是否同样(结构和数据),递归和非递归
- 2140-数据结构实验之图论十:判断给定图是否存在合法拓扑序列
- 判别一个无向图中某两点之间是否存在一条长度为k的简单路径
- mysql 判断是否已存在及插入表数据 的 简单存储过程
- 数据结构实验之图论十:判断给定图是否存在合法拓扑序列
- 判断常见的数据库数据结构对象是否存在
- SDUTOJ(2140)数据结构实验之图论十:判断给定图是否存在合法拓扑序列