#ifndef _SQSTACK_H_
#define _SQSTACK_H_
//定义顺序栈类
template <class ElemType>//声明一个类模板
class SqStack
{
public: //顺序栈类的各成员函数
SqStack(int m = 100);
~SqStack();
void Clear();
bool Empty() const;
int Length() const;
ElemType & Top() const;
void Push(const ElemType &e);
void Pop();
private: //顺序栈类的数据成员
ElemType *m_base; //基地址指针
int m_top; //栈顶指针
int m_size; //向量空间大小
};
//构造函数,分配m个结点的顺序空间,构造一个空的顺序栈。
template <class ElemType>
SqStack <ElemType>::SqStack(int m)
{
m_top = 0;
m_base = new ElemType[m];
m_size = m;
}//SqStack
//析构函数,将栈结构销毁。
template <class ElemType>
SqStack <ElemType>::~SqStack()
{
if (m_base != NULL) delete[] m_base;
}//~SqStack
//清空栈。
template <class ElemType>
void SqStack <ElemType>::Clear()
{
m_top = 0;
}//Clear
//判栈是否为空,若为空,则返回true,否则返回false。
template <class ElemType>
bool SqStack <ElemType>::Empty() const
{
return m_top == 0;
}//Empty
//求栈的长度。
template <class ElemType>
int SqStack <ElemType>::Length() const
{
return m_top;
}//Length
//取栈顶元素的值。先决条件是栈不空。
template <class ElemType>
ElemType & SqStack <ElemType>::Top() const
{
return m_base[m_top - 1];
}//Top
//入栈,若栈满,则先扩展空间。插入e到栈顶。
template <class ElemType>
void SqStack <ElemType>::Push(const ElemType &e)
{
if(m_top >= m_size){ //若栈满,则扩展空间。
ElemType *newbase;
newbase = new ElemType[m_size + 10];
for(int j = 0; j < m_top; j++)
newbase[j] = m_base[j];
delete[] m_base;
m_base = newbase;
m_size += 10;
}
m_base[m_top++] = e;
}//Push
//出栈,弹出栈顶元素。先决条件是栈非空。
template <class ElemType>
void SqStack <ElemType>::Pop()
{
m_top--;
}//Pop
#endif
#include <iostream>
using namespace std;
#include "SqStack.h"
#define MAXSIZE 30 //设迷宫的最大行列为30
struct PosType //迷宫坐标位置类型
{
int x; //行值
int y; //列值
};
struct DataType //栈的元素类型
{
PosType seat; //点在迷宫中的"坐标位置"
int di; //从此点走向下一点的"方向"(0~3表示东~北)
};
class Maze
{
public:
Maze(int, int);
~Maze();
bool MazePath(PosType, PosType);
void Input();
void Print();
private:
PosType NextPos(PosType, int);
int **m_maze; //迷宫数组
int m_row; //迷宫的行数
int m_col; //迷宫的列数
};
//构造函数
Maze::Maze(int m, int n)
{
m_row = m + 2;
m_col = n + 2;
m_maze = new int * [m_row];
for (int i = 0; i < m_row; i++)
m_maze[i] = new int [m_col];
}//Maze
//析构函数
Maze::~Maze()
{
for (int i = 0; i < m_row; i++)
if (m_maze[i] != NULL)
delete [] m_maze[i];
if (m_maze != NULL)
delete[] m_maze;
}//~Maze
//若迷宫m_maze中存在从入口start到出口end的通路,则求得一条路径
//存放在栈中(从栈底到栈顶),并返回true;否则返回false。通过路径为足迹(以路径上的序号表示)
bool Maze::MazePath(PosType start, PosType end)
{
SqStack<DataType> path(MAXSIZE); //创建栈
PosType curpos;
DataType e;
curpos = start;
int curstep = 1; //当前足迹,初值为1
do {
if (m_maze[curpos.x][curpos.y] == 0) { //当前位置可以通过,即是未曾走到过的点
m_maze[curpos.x][curpos.y]=curstep; //留下足迹,迷宫m_maze的curpos点变为序号curstep
e.seat.x = curpos.x;
e.seat.y = curpos.y;
e.di = 0;
path.Push(e); //入栈当前位置及方向
curstep++; //足迹加1
if(curpos.x == end.x && curpos.y == end.y) //到达终点(出口)
return true;
curpos = NextPos(curpos, e.di);
}
else { //当前位置不能通过
if (!path.Empty()) {
e = path.Top(); //退栈到前一位置
path.Pop();
curstep--;
while (e.di == 3 && !path.Empty()) { //该位置已到最后一个方向(北)
m_maze[e.seat.x][e.seat.y] = -1; //留下不能通过的标记(-1)
e = path.Top(); //退回一步
path.Pop();
curstep--;
}
if (e.di < 3) { //没到最后一个方向(北)
e.di++; //换下一个方向探索
path.Push(e);
curstep++;
curpos = NextPos(e.seat, e.di); //设定当前位置是该新方向上的相邻点
}
}
}
} while (!path.Empty());
return false;
}//MazePath
//输入迷宫
void Maze::Input()
{
int i, j;
cout << "请输入" << m_row - 2 << "*" << m_col - 2 << "的迷宫:" << endl;
for (i = 1; i <= m_row - 2; i++)
for (j = 1; j <= m_col - 2; j++)
cin >> m_maze[i][j];
//周边设围墙,定义周边值为1(墙)
for (i = 0; i < m_row; i++) {
m_maze[i][0] = 1; //行周边
m_maze[i][m_col - 1] = 1;
}
for (j = 1; j < m_col - 1;j++) {
m_maze[0][j] = 1; //列周边
m_maze[m_row - 1][j] = 1;
}
}//Input
//输出迷宫的解
void Maze::Print()
{
int i,j;
for (i = 1; i < m_row - 1; i++) {
for (j = 1; j < m_col - 1; j++)
if (m_maze[i][j] >= 0 && m_maze[i][j] < 10) //输出对齐
cout << " " << m_maze[i][j] ;
else
cout << " " << m_maze[i][j] ;
cout << endl;
}
}//Print
//根据当前点的位置c及移动方向d,返回下一位置,移动方向,依次为东南西北
PosType Maze::NextPos(PosType c, int d)
{
PosType direct[4] = {{0,1}, {1,0}, {0,-1}, {-1,0}}; //{行增量,列增量}
c.x += direct[d].x;
c.y += direct[d].y;
return c;
}//NextPos
int main()
{
PosType begin, end;
int m, n;
cout << "请输入迷宫的行数,列数:";
cin >> m >> n;
Maze maze(m, n);
maze.Input();
cout << "请输入入口位置(行数,列数):" ;
cin >> begin.x >> begin.y;
cout << "请输入出口位置(行数,列数):";
cin >> end.x >> end.y;
if (maze.MazePath(begin,end)) { //求得一条通路
cout << "此迷宫从入口到出口的一条路径如下:" << endl;
maze.Print(); //输出此通路
}
else
cout << "此迷宫没有从入口到出口的路径" << endl;
system("pause");
return 0;
}
/*
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
*/