使用C++解决迷宫深度搜索路径问题解法(二)广度遍历,寻找一条最优解线路

#include <iostream>
using namespace std;
//
const int RIGHT = 0;
const int DOWN = 1;
const int LEFT = 2;
const int UP = 3;
//
const int YES = 4;
const int NO = 5;
class Node {
public:
	int _x;
	int _y;
	int _val;
	int _state[4];//保存四个方向的状态值
};
class Queue
{
public:
	Queue(const Queue&obj) = delete;
	void operator=(const Queue&obj) = delete;
	Queue(int size = 10) :
		_size(size),
		_front(0),
		_rear(0)
	{
		_pQue = new Node[_size];
	}
	~Queue()
	{
		delete[] _pQue;
		_pQue = nullptr;
	}
	void push(Node &node)
	{
		if (full())
			expand();
		_pQue[_rear] = node;
		_rear = (_rear + 1) % _size;
	}
	void pop()
	{
		if (empty())
			return;
		_front++;
	}
	Node front()
	{
		if (empty())
			return Node();
		return _pQue[_front % _size];
	}
	bool full()const
	{
		return (_rear + 1) % _size == _front;
	}
	bool empty()const
	{
		return _front == _rear;
	}

private:
	int _front;
	int _rear;
	int _size;
	Node *_pQue;
	void expand()
	{
		Node *tmp = new Node[_size * 2];
		int index = 0;
		for (int i = _front; i != _rear; (i + 1) % _size)
		{
			tmp[index++] = _pQue[i];
		}
		delete[] _pQue;
		_pQue = tmp;
		_front = 0;
		_rear = index;
		_size *= 2;
	}
};
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];
		SArr = new Node[_row * _col];
	}
	~Maze()
	{
		for (int i = 0; i < _row; i++)
			delete[]_pMaze[i];
		delete[] _pMaze;
		_pMaze = nullptr;
		delete[] SArr;
		SArr = nullptr;
	}
	void InitMaze(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 < 4; i++)
			_pMaze[x][y]._state[i] = NO;
	}
	void SetNodeState()
	{
		for (int i = 0; i < _row; i++)
			for (int j = 0; j < _col; j++)
			{
				//右
				if (j + 1 < _col && _pMaze[i][j + 1]._val == 0)
				{
					_pMaze[i][j]._state[RIGHT] = YES;
				}
				//下
				if (i + 1 < _row && _pMaze[i + 1][j]._val == 0)
				{
					_pMaze[i][j]._state[DOWN] = YES;
				}
				//左
				if (j - 1 >= 0 && _pMaze[i][j - 1]._val == 0)
				{
					_pMaze[i][j]._state[LEFT] = YES;
				}
				//上
				if (i - 1 >= 0 && _pMaze[i - 1][j]._val == 0)
				{
					_pMaze[i][j]._state[UP] = YES;
				}
			}
	}
	void SearchNodePath_Queue()//广度搜索
	{
		if (_pMaze[0][0]._val == 1)
			return;
		_queue.push(_pMaze[0][0]);
		int x, y;
		while (!_queue.empty())
		{
			Node tmp = _queue.front();
			x = tmp._x;
			y = tmp._y;
			if (x == _row - 1 && y == _col - 1)
				break;
			//右
			if (_pMaze[x][y]._state[RIGHT] == YES)
			{
				_pMaze[x][y]._state[RIGHT] = NO;
				_pMaze[x][y + 1]._state[LEFT] = NO;
				_queue.push(_pMaze[x][y + 1]);
				int index = _pMaze[x][y + 1]._x * _row + _pMaze[x][y + 1]._y;
				SArr[index] = _pMaze[x][y];
			}
			//下
			if (_pMaze[x][y]._state[DOWN] == YES)
			{
				_pMaze[x][y]._state[DOWN] = NO;
				_pMaze[x + 1][y]._state[UP] = NO;
				_queue.push(_pMaze[x + 1][y]);
				int index = _pMaze[x + 1][y]._x * _row + _pMaze[x + 1][y]._y;
				SArr[index] = _pMaze[x][y];
			}
			//左
			if (_pMaze[x][y]._state[LEFT] == YES)
			{
				_pMaze[x][y]._state[LEFT] = NO;
				_pMaze[x][y - 1]._state[RIGHT] = NO;
				_queue.push(_pMaze[x][y - 1]);
				int index = _pMaze[x][y - 1]._x*_row + _pMaze[x][y - 1]._y;
				SArr[index] = _pMaze[x][y];
			}
			//右
			if (_pMaze[x][y]._state[UP] == YES)
			{
				_pMaze[x][y]._state[UP] = NO;
				_pMaze[x - 1][y]._state[UP] = NO;
				_queue.push(_pMaze[x - 1][y]);
				int index = _pMaze[x - 1][y]._x*_row + _pMaze[x - 1][y]._y;
				SArr[index] = _pMaze[x][y];
			}
			_queue.pop();
		}
	}
	void ShowMaze_Queue()
	{
		if (_queue.empty())
		{
			cout << "不存在一条路径" << endl;
			return;
		}
		else
		{
			int begin = _row * _col - 1;
			_pMaze[_row - 1][_col - 1]._val = '*';
			while (begin != 0)
			{
				_pMaze[SArr[begin]._x][SArr[begin]._y]._val = '*';
				begin = SArr[begin]._x * _row + SArr[begin]._y;
			}
			_pMaze[0][0]._val = '*';
			
			for (int i = 0; i < _row; i++)
			{
				for (int j = 0; j < _col; j++)
				{
					if (_pMaze[i][j]._val == '*')
						printf("* ");
					else
						printf("%d ", _pMaze[i][j]._val);
				}
				cout << endl;
			}
		}
	}
	
private:
	Node **_pMaze;
	Queue _queue;
	Node *SArr;
	int _row;
	int _col;
};
int main()
{
	int col, row;
	int data;
	cout << "请输入迷宫的大小例子:(5 5)";
	cin >> row >> col;
	Maze maze(row, col);
	cout << "请输入迷宫的路径" << endl;
	for (int i = 0; i < row; i++)
		for (int j = 0; j < col; j++)
		{
			cin >> data;
			maze.InitMaze(i, j, data);
		}
	maze.SetNodeState();

	maze.SearchNodePath_Queue();

	maze.ShowMaze_Queue();
}

//0 0 1 1 1 1
//1 0 0 0 0 1
//1 0 1 1 0 1
//1 0 0 0 0 1
//1 0 1 1 1 1
//1 0 0 0 0 0

运行代码后面的测试用例结果为:

可见广度优先遍历可以使得我们找到迷宫路径一条最短路径。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值