用栈和递归求解迷宫问题

一、问题概述

小时候,我们都玩过走迷宫的游戏吧。看一下这个图例:

《用栈和递归求解迷宫问题》

遇到这种问题时,我们第一反应都会先找到迷宫的入口点,然后对上下左右四个方向进行寻迹,

 检测当前位置是否是通路,是否可以通过,直至找到出口位置,才是迷宫的正确轨迹。如若走到死胡

 同里,则须返回重新选择路径走。

 我们来模拟一下迷宫问题,我们的迷宫是这样的:

《用栈和递归求解迷宫问题》

哈哈~虽然有点low!但是可以帮助我们解决实际问题,就将就着看吧,这个更能清晰的说明问题哦。

那么这个迷宫从何而来呢?我将它放在文件中,以读取文件的方式,将其坐标保存在二维数组中喽。


二、解决方案

(1)找到入口点(entry),这个由我们自己给定坐标即可。

(2)使用试探法对迷宫寻迹,有上下左右四个方向,将走过的路径标记一下,将值赋值为其他

                 值。(这里我将它赋为2)

(3)如果走进死胡同里,则采用回溯的思想,将其pop即可。

(4)判断何时为迷宫出口,当它的横坐标为(行数-1)时,说明已找到出口。(当然,在这里你

也可以不用规定出口就在最下方,视迷宫的图例而定)

(5)若迷宫没有出口,则栈为空。


三、实现代码


//Maze.h

#include<iostream>
using namespace std;
#include<assert.h>
#include<stack>

struct Pos
{
	int _row;
	int _col;
};

void GetMaze(int *Maze,size_t N)
{
	FILE* fout = fopen("Maze.txt","r");
	assert(fout);
	for(size_t i = 0; i < N; ++i)
	{
		for(size_t j = 0; j < N; )
		{
			int value = fgetc(fout);
			if(value == '1' || value == '0')
			{
				Maze[i*N+j] = value - '0';
				++j;
			}
			else if(value == EOF)
			{
				cout<<"Maze error!"<<endl;
				return;
			}
		}
	}
}

bool IsCheckPath(int *maze,size_t n,Pos path)
{
	if((path._row >= 0 && path._row < 10) 
		&& (path._col >= 0 && path._col < 10) 
		&& (maze[path._row*n+path._col] == 0))
	{
		return true;
	}
	return false;
}

//栈求解迷宫路径
void GetMazePath(int *maze,size_t n,Pos entry,stack<Pos>& s)
{
	Pos cur = entry;
	Pos next = cur;
	maze[cur._row*n+cur._col] = 2;
	s.push(entry);
	while(!s.empty())
	{
		if(s.top()._row  == n-1)
		{
			return;
		}
		//探测上下左右
		//上
		next = s.top();
		next._row-=1;
		if(IsCheckPath(maze,n,next))
		{
			s.push(next);
			maze[next._row*n+next._col] = 2;
			continue;
		}

		//右
		next = s.top();
		next._col+=1;
		if(IsCheckPath(maze,n,next))
		{
			s.push(next);
			maze[next._row*n+next._col] = 2;
			continue;
		}

		//下
		next = s.top();
		next._row+=1;
		if(IsCheckPath(maze,n,next))
		{
			s.push(next);
			maze[next._row*n+next._col] = 2;
			continue;
		}

		//左
		next = s.top();
		next._col-=1;
		if(IsCheckPath(maze,n,next))
		{
			s.push(next);
			maze[next._row*n+next._col] = 2;
			continue;
		}

		//没有通路
		Pos tmp = s.top();
		maze[tmp._row*n+tmp._col] = 3;
		s.pop();
	}
}

//递归求解迷宫路径
void GetMazePath(int *maze,size_t n,Pos entry,stack<Pos>& s)
{
		Pos next = entry;
		maze[next._row*n+next._col] = 2;
		s.push(entry);
	
		if(next._row == n-1)
		{
			return;
		}

		//探测上下左右
		//上
		next = entry;
		next._row-=1;
		if(IsCheckPath(maze,n,next))
		{
			GetMazePath(maze,n,next,s);
			
		}
		//右
		next = entry;
		next._col+=1;
		if(IsCheckPath(maze,n,next))
		{
			GetMazePath(maze,n,next,s);
			
		}

		//下
		next = entry;
		next._row+=1;
		if(IsCheckPath(maze,n,next))
		{
			GetMazePath(maze,n,next,s);
			
		}

		//左
		next = entry;
		next._col-=1;
		if(IsCheckPath(maze,n,next))
		{
			GetMazePath(maze,n,next,s);
		}
}

void PrintMaze(int *maze,size_t n)
{
	cout<<"迷宫显示:>"<<endl;
	for(size_t i = 0; i < n; ++i)
	{
		for(size_t j = 0; j < n; ++j)
		{
			cout<<maze[i*n+j]<<" ";
		}
		cout<<endl;
	}
}

//Maze.cpp

#define _CRT_SECURE_NO_WARNINGS 1
#include"Maze.h"

//用栈和递归实现迷宫问题
const size_t N = 10;

void FunTest()
{
	int Maze[N][N];
	Pos entry = {2,0};
	stack<Pos> ss;
	GetMaze((int*)Maze,N);
	GetMazePath((int*)Maze,N,entry,ss);
	cout<<"迷宫是否有出口?"<<!ss.empty()<<endl;
	PrintMaze((int*)Maze,N);
}

int main()
{
	FunTest();
	return 0;
}

用栈和递归实现普通的迷宫问题还是可以的,但是还有一种这样的迷宫:

《用栈和递归求解迷宫问题》

当有多条路径的时候,就会涉及到路径长短的问题,到底走哪条路径会是最优。下篇博客给大家介绍哦。《用栈和递归求解迷宫问题》《用栈和递归求解迷宫问题》

希望看过此篇博客的编程爱好者提出见解哈。


    原文作者:迷宫问题
    原文地址: https://blog.csdn.net/xxpresent/article/details/53413730
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞