深度遍历迷宫搜索C++实现

news/2024/7/24 1:58:13 标签: python, 算法, java, 数据结构, 二叉树
// 深度遍历迷宫路径搜索.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

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

#if 0
/*
深度遍历搜索迷宫路径,软件运行要求如下:

请输入迷宫的行列数(例如:10 10):5 5
请输入迷宫的路径信息(0表示可以走,1表示不能走):
0 0 0 1 1
1 0 1 0 1
1 1 0 1 1
1 1 0 0 1
1 1 1 0 0
迷宫路径搜索中...
>>>如果没有路径,直接输出<<<
不存在一条迷宫路径!
>>>如果有路径,直接输出<<<
* * * 1 1
1 0 * 0 1
1 1 * 1 1
1 1 * * 1
1 1 1 * *
*/

// 定义迷宫每一个节点的四个方向
const int RIGHT = 0;
const int DOWN = 1;
const int LEFT = 2;
const int UP = 3;

// 迷宫每一个节点方向的数量
const int WAY_NUM = 4;

// 定义节点行走状态
const int YES = 4;
const int NO = 5;

// 迷宫
class Maze
{
public:
	// 初始化迷宫,根据用户输入的行列数,生成存储迷宫路径信息的二维数组
	Maze(int row, int col)
		:_row(row)
		, _col(col)
	{
		_pMaze = new Node*[_row];
		for (int i = 0; i < _row; ++i)
		{
			_pMaze[i] = new Node[_col];
		}
	}

	// 初始化迷宫路径节点信息
	void initNode(int x, int y, int val)
	{
		_pMaze[x][y]._x = x;
		_pMaze[x][y]._y = y;
		_pMaze[x][y]._val = val;
		// 节点四个方向默认的初始化
		for (int i = 0; i < WAY_NUM; ++i)
		{
			_pMaze[x][y]._state[i] = NO;
		}
	}

	// 初始化迷宫0节点四个方向的行走状态信息
	void setNodeState()
	{
		for (int i = 0; i < _row; ++i)
		{
			for (int j = 0; j < _col; ++j)
			{
				if (_pMaze[i][j]._val == 1)
				{
					continue;
				}

				if (j < _col - 1 && _pMaze[i][j + 1]._val == 0)
				{
					_pMaze[i][j]._state[RIGHT] = YES;
				}

				if (i < _row - 1 && _pMaze[i + 1][j]._val == 0)
				{
					_pMaze[i][j]._state[DOWN] = YES;
				}

				if (j > 0 && _pMaze[i][j - 1]._val == 0)
				{
					_pMaze[i][j]._state[LEFT] = YES;
				}

				if (i > 0 && _pMaze[i - 1][j]._val == 0)
				{
					_pMaze[i][j]._state[UP] = YES;
				}
			}
		}
	}

	// 深度搜索迷宫路径
	void searchMazePath()
	{
		if (_pMaze[0][0]._val == 1)
		{
			return;
		}
		_stack.push(_pMaze[0][0]);

		while (!_stack.empty())
		{
			Node top = _stack.top();
			int x = top._x;
			int y = top._y;

			// 已经找到右下角出口得迷宫路径
			if (x == _row - 1 && y == _col - 1)
			{
				return;
			}

			// 往右方向寻找
			if (_pMaze[x][y]._state[RIGHT] == YES)
			{
				_pMaze[x][y]._state[RIGHT] = NO;
				_pMaze[x][y + 1]._state[LEFT] = NO;
				_stack.push(_pMaze[x][y + 1]);
				continue;
			}

			// 往下方向寻找
			if (_pMaze[x][y]._state[DOWN] == YES)
			{
				_pMaze[x][y]._state[DOWN] = NO;
				_pMaze[x + 1][y]._state[UP] = NO;
				_stack.push(_pMaze[x + 1][y]);
				continue;
			}

			// 往左方向寻找
			if (_pMaze[x][y]._state[LEFT] == YES)
			{
				_pMaze[x][y]._state[LEFT] = NO;
				_pMaze[x][y - 1]._state[RIGHT] = NO;
				_stack.push(_pMaze[x][y - 1]);
				continue;
			}

			// 往上方向寻找
			if (_pMaze[x][y]._state[UP] == YES)
			{
				_pMaze[x][y]._state[UP] = NO;
				_pMaze[x - 1][y]._state[DOWN] = NO;
				_stack.push(_pMaze[x - 1][y]);
				continue;
			}

			_stack.pop();
		}
	}

	// 打印迷宫路径搜索结果
	void showMazePath()
	{
		if (_stack.empty())
		{
			cout << "不存在一条迷宫路径!" << endl;
		}
		else
		{
			while (!_stack.empty())
			{
				Node top = _stack.top();
				_pMaze[top._x][top._y]._val = '*';
				_stack.pop();
			}

			for (int i = 0; i < _row; ++i)
			{
				for (int j = 0; j < _col; ++j)
				{
					if (_pMaze[i][j]._val == '*')
					{
						cout << "* ";
					}
					else
					{
						cout << _pMaze[i][j]._val << " ";
					}
				}
				cout << endl;
			}
		}
	}
private:
	// 定义迷宫节点路径信息
	struct Node
	{
		int _x;   
		int _y;
		int _val; // 节点的值
		int _state[WAY_NUM]; // 记录节点四个方向的状态
	};

	Node **_pMaze; // 动态生成迷宫路径
	int _row;
	int _col;
	stack<Node> _stack; // 栈结构,辅助深度搜索迷宫路径
};

int main()
{
	cout << "请输入迷宫的行列数(例如:10 10):";
	int row, col, data;
	cin >> row >> col;

	Maze maze(row, col); // 创建迷宫对象

	cout << "请输入迷宫的路径信息(0表示可以走,1表示不能走):" << endl;
	for (int i = 0; i < row; ++i)
	{
		for (int j = 0; j < col; ++j)
		{
			cin >> data;
			// 可以初始化迷宫节点的基本信息
			maze.initNode(i, j, data);
		}
	}

	// 开始设置所有节点的四个方向的状态
	maze.setNodeState();

	// 开始从左上角搜索迷宫的路径信息了
	maze.searchMazePath();

	// 打印迷宫路径搜索的结果
	maze.showMazePath();

	return 0;
}
#endif

http://www.niftyadmin.cn/n/923550.html

相关文章

数据结构中二叉树的度

首先说说什么是度&#xff1a;通俗的讲二叉树中连接节点和节点的线就是度&#xff0c;有n个节点&#xff0c;就有n-1个度&#xff0c;节点数总是比度要多一个&#xff0c;那么度为0的节点一定是叶子节点&#xff0c;因为该节点的下面不再有线&#xff1b;度为1的节点即&#xf…

大数的加减法

#include "pch.h" #include <iostream> #include <string> #include <algorithm> using namespace std;#if 0 // 编程题目&#xff1a;请实现以下类的方法&#xff0c;完成大数的加减法 class BigInt { public:BigInt(string str) :strDigit(str) …

C++实现LRU(最久未使用)缓存算法

LRU缓存算法也叫LRU页面置换算法&#xff0c;是一种经典常用的页面置换算法&#xff0c;本文将用C实现一个LRU算法。 LRU算法实现并不难&#xff0c;但是要高效地实现却是有难度的&#xff0c;要想高效实现其中的插入、删除、查找&#xff0c;第一想法就是红黑树&#xff0c;但…

从你输入一个网址,到网页显示,其间发生了什么?

1.解析URL 首先浏览器做的第一步工作就是要对 URL 进行解析&#xff0c;从而生发送给 Web 服务器的请求信息。 当没有路径名时&#xff0c;就代表访问根目录下事先设置的默认文件&#xff0c;也就是 /index.html 或者 /default.html 这些文件&#xff0c;这样就不会发生混乱了…

BST树元素区间搜索问题

由于BST的中序遍历的性质&#xff0c;遍历完成之后是一个有序的序列 所以&#xff0c;在有序的序列当中查找某个区间当中的元素是非常容易的&#xff0c;我们可以简单的运用递归来实现这个操作 //在区间[l...r]中搜索元素 void findValues(Node *node,int l,int r) {if(node!n…

《程序员的自我修养---温故而知新》第一章总结

1.多道程序&#xff1a;当某个程序暂时无须使用CPU的时候&#xff0c;监控程序就把另外的正在等待CPU资源的程序启动&#xff0c;使得CPU能够充分利用起来 2.分时系统&#xff1a;每个程序运行一段时间以后都主动让出CPU给其他程序&#xff0c;使得一段时间内每个程序都有机会…

《程序员的自我修养---编译和链接》第二章总结

被隐藏了的过程 gcc hello.c ./a.out上述过程可分为4个过程&#xff1a;预处理&#xff0c;编译&#xff0c;汇编&#xff0c;链接 预编译->.i 预编译主要是以文件中‘#’开始的预编译指令 将所有的”#define“删除&#xff0c;并且展开所有的宏定义处理所有条件预编译指…

《程序员的自我修养---目标文件里有什么》第三章总结

程序源代码编译后的机器指令经常被放在代码段里&#xff0c;代码段常见的名字有.code和.text段 全局变量和局部静态变量经常放在数据段&#xff08;.data&#xff09; C语言的编译后执行语句都编译成机器代码&#xff0c;保存在.text段&#xff0c;已初始化的全局变量和局部静…