#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
运行代码后面的测试用例结果为:
可见广度优先遍历可以使得我们找到迷宫路径一条最短路径。