迷宫

#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
*/


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值