迷宫算法-数据结构、算法与应用C++语言描述

一、栈的算法查找迷宫解法

1.代码

按照《数据结构、算法与应用C++语言描述》第九章栈的思路来实现解法。

迷宫内部主要有四个函数。welcome函数是欢迎界面,inputMaze函数是输入迷宫,findPath函数是寻找迷宫解法,outputPath函数是输出迷宫解法。

#include <iostream>
#include "Maze.h"

using namespace std;

int main()
{
    Maze m;
    m.welcome();
    m.inputMaze();
    m.findPath();
    m.outputPath();

    return 0;
}

记录当前位置的类position.h

#ifndef POSITION_H
#define POSITION_H

#include <iostream>

using namespace std;

class position
{
public:
	position()
	{
		this->row = 0;
		this->col = 0;
	}
	position(int r, int c)
	{
		this->row = r;
		this->col = c;
	}
	~position() {}

	int row;
	int col;
};

#endif // !POSITION_H

迷宫类Maze.h

#ifndef MAZE_H
#define MAZE_H

#include <iostream>
#include <stack>
#include "position.h"

using namespace std;

class Maze
{
public:
	Maze();
	~Maze();
	void welcome();
	void inputMaze();
	void findPath();
	void outputPath();

private:
	int m;  //迷宫行数
	int n;  //迷宫列数
	int** maze;  //二维指针存取迷宫,(m+2)*(n+2)
	stack<position>* path;  //迷宫路线
};

#endif // !MAZE_H

迷宫类的实现

#include "Maze.h"

Maze::Maze()
{
	m = 0;
	n = 0;
}

Maze::~Maze()
{
	if (maze != NULL)
	{
		for (int i = 0; i < m + 2; ++i)
		{
			delete[] maze[i];
		}
		delete[] maze;
		maze = NULL;
	}

	if (path != NULL)
	{
		delete path;
		path = NULL;
	}
}

void Maze::welcome()
{
	cout << "Welcome To A MAZE" << endl;
}

void Maze::inputMaze()
{//返回存取迷宫的二维指针
	cout << "请输入迷宫的长和宽:" << endl;
	cin >> m >> n;
	
	this->maze = new int* [m + 2];
	for (int i = 0; i < m + 2; ++i)
	{
		maze[i] = new int[n + 2];
		maze[i][0] = maze[i][n + 1] = 1;  //第一列和最后一列为墙
	}

	for (int i = 0; i < n + 2; ++i)
	{
		maze[0][i] = maze[m + 1][i] = 1;  //第一行和最后一行为墙
	}

	cout << "请输入迷宫内容:\n";
	//输入迷宫内容,0代表可通,1代表不通
	for (int i = 1; i < m + 1; ++i)
	{
		for (int j = 1; j < this->n + 1; ++j)
		{
			cin >> maze[i][j];
		}
	}
}

void Maze::findPath()
{
	//定义当前位置移动的4个方向,第0列为行偏移量,第1列为列偏移量
	int move[4][2] = { {0,1},{1,0},{0,-1},{-1,0} };   //右,下,左,上

	path = new stack<position>; // 存储路径信息
	position here(1, 1);  //起始位置
	maze[1][1] = 1;  //防止回到入口
	int option = 0;  //可选的方向,右、下、左、上=(0,1,2,3)
	int max_option = 3;  //方向的选择范围

	while (here.row != m || here.col != n)  //没走到迷宫出口
	{
		//找到要移动的相邻一步
		int r = 0, c = 0;
		while (option <= max_option)
		{
			r = here.row + move[option][0];
			c = here.col + move[option][1];
			if (maze[r][c] == 0)  //可以走通
			{
				break;
			}
			++option;  //寻找下一个方向
		}

		if (option <= max_option)  //可以接着走通的情况
		{
			path->push(here);  //更新路径
			//here更新位置
			here.row = r;
			here.col = c;

			maze[here.row][here.col] = 1;  //防止往下寻找时重复访问到此位置
			option = 0;
		}
		else  //当走不通时,可以把当前位置置1封死路,返回上一位置
		{
			if (path->empty())
			{
				cout << "There Is No Path For This Maze!" << endl;
				return;
			}
			else
			{
				//返回重新搜索
				position next = path->top();
				path->pop();
				//将当前位置封死,避免重复搜索
				maze[here.row][here.col] = 1;
				here = next;
				option = 0;
			}
		}
	}
	path->push(here);  //出口位置入栈

	cout << "I Find The Path For This Maze!" << endl;
	return;
}

void Maze::outputPath()
{
	if (path == NULL)
	{
		cout << "There Is No Path For This Maze!" << endl;
		return;
	}

	char** mazePath = new char* [m];
	//拷贝迷宫到mazePath
	for (int i = 0; i < m; ++i)
	{
		mazePath[i] = new char[n];
		for (int j = 0; j < n; ++j)
		{//四周的墙去掉
			if (maze[i + 1][j + 1] == 0)
			{
				mazePath[i][j] = '0';
			}
			else if (maze[i + 1][j + 1] == 1)
			{
				mazePath[i][j] = '1';
			}
		}
	}
	//拷贝走出迷宫的路线到mazePath

	position tmp;
	while (!path->empty())
	{
		tmp = path->top();
		path->pop();
		mazePath[tmp.row - 1][tmp.col - 1] = '*';  //去除墙
	}

	//打印输出迷宫路线
	for (int i = 0; i < m; ++i)
	{
		for (int j = 0; j < n; ++j)
		{
			cout << mazePath[i][j] << " ";
		}
		cout << endl;

		delete[] mazePath[i];   //删除指针空间
	}

	delete[] mazePath;  //删除指针空间
}

内部实现算法注释已经写得很清楚了,注意最后输出的迷宫算法将查找路线过程也一并显示了,查找过程走错的路线都置为1了。

2.测试用例

测试1:
请输入迷宫的长和宽:
5 5
请输入迷宫内容:
0 1 1 0 0
0 0 1 1 0
1 0 0 1 1
1 0 0 1 0
1 1 0 0 0

测试结果:
测试结果

测试2:
请输入迷宫的长和宽:
9 8
请输入迷宫内容:
0 0 1 0 0 0 1 0
0 0 1 0 0 0 1 0
0 0 0 0 1 1 0 1
0 1 1 1 0 0 1 0
0 0 0 1 0 0 0 0
0 1 0 0 0 1 0 1
0 1 1 1 1 0 0 1
1 1 0 0 0 1 0 1
1 1 0 0 0 0 0 0

测试结果:
测试结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值