DHU顺序栈ADT模板简单应用算法设计:迷宫问题

问题描述 :

目的:使用C++模板设计顺序栈的抽象数据类型(ADT)。并在此基础上,使用顺序栈ADT的基本操作,设计并实现简单应用的算法设计。

内容:(1)请参照顺序表的ADT模板,设计顺序栈的抽象数据类型。(由于该环境目前仅支持单文件的编译,故将所有内容都集中在一个源文件内。在实际的设计中,推荐将抽象类及对应的派生类分别放在单独的头文件中。参考教材、课件,以及网盘中的顺序表ADT原型文件,自行设计顺序栈的ADT。)

(2)ADT的简单应用:使用该ADT设计并实现若干应用顺序栈的算法设计。

应用:在迷宫中找出从入口到出口的路径是一个经典的程序设计问题。最简单的迷宫可以表示为一个由方块组成的矩阵,其中每个方块或为墙,或为通道。要求应用顺序栈,设计一个算法,在给定的迷宫矩阵maze中,找出从入口到出口的一条简单路径,即同一个通道在路径上不能出现两次以上。迷宫在计算机内可以用一个二维数组表示,每个数组元素表示一个方块。如果是通道,值为0,反之为1。

提示:

(1)可以用如图所示的方块表示迷宫。其中,图中的空白方块为通道;图中的斜线方块为墙;所求路径必须是简单路径,即在求得的路径上不能重复出现同一通道块。

主要思路:

代码:

#include <iostream>
#include <cmath>
#include <vector>
#include <cstring>
#include<algorithm>
#include <sstream>
using namespace std;
#define OK 1
#define ERROR 0
#define MAXSIZE  100//顺序栈存储空间的初始分配量
int sum=0;
typedef int Status;
typedef struct Point SElemType;

template<class SElemType>
class SqStack
{
public:
    SElemType *base;//栈底指针
    SElemType *top;//栈顶指针
    int stacksize;//栈可用的最大容量
public:
    int currentsize=0;
    SqStack()
    {
        base = new SElemType[MAXSIZE];//为顺序栈动态分配一个最大容量为MAXSIZE的数组空间
        top = base; //top初始为base,空栈
        stacksize = MAXSIZE; //stacksize置为栈的最大容量MAXSIZE
    }
    Status Push(SElemType e)
    {// 插入元素e为新的栈顶元素
        if (top - base == stacksize)
            return ERROR; //栈满
        *(top++) = e; //元素e压入栈顶,栈顶指针加1
        currentsize++;
        return OK;
    }
    Status Pop(SElemType &e)
    {//删除S的栈顶元素,用e返回其值
        if (base==top)
            return ERROR;//栈空
        e = *(--top); //栈顶指针减1,将栈顶元素赋给e
        currentsize--;
        return OK;
    }
    ~SqStack( )
    {
        if (base)
        {
            delete []base;
        }
    }
    SqStack<SElemType> operator=(SqStack<SElemType> &s);
    SqStack(const SqStack<SElemType> &s);
    Status GetTop(SElemType &e)
    {//返回S的栈顶元素,不修改栈顶指针
        if (top != base) //栈非空
        {
            e= *(top - 1); //返回栈顶元素的值,栈顶指针不变
            return OK;
        }
        else
            return ERROR;
    }
    bool judgeEmpty()//栈为空返回1
    {
        if (base==top)
            return 1;
        else
            return 0;
    }
};

struct Point
{//x=row,y=col;
	int x = 0;
	int y = 0;
	int direction;
	bool operator!=(const Point& rhs) {
		if (this->x != rhs.x || this->y != rhs.y)
			return true;
		return false;
	}
	bool operator==(const Point& rhs) {
		if (this->x == rhs.x && this->y == rhs.y)
			return true;
		return false;
	}
    void operator=(const Point& next){
        this->x=next.x;
        this->y=next.y;
        this->direction=next.direction;
    }
};

Point getNextPoint(Point current)//通过current数据得出next
{
    Point next=current;
    if (current.direction==0){
        next.x+=-1;
    }
    if (current.direction==1){
        next.y+=1;
    }
    if (current.direction==2){
        next.x+=1;
    }
    if (current.direction==3){
        next.y+=-1;
    }
    next.direction=0;
    return next;
}

int Pass(Point p,int maze[MAXSIZE][MAXSIZE],int row,int col)//判断点p是否可通过,若可以则返回1
{
    if (p.x<1||p.y<1||p.x>row||p.y>col)
        return 0;
    else if (maze[p.x][p.y]==1)
        return 0;
    else if (maze[p.x][p.y]==0)
        return 1;
    else if (maze[p.x][p.y]==2)
        return -1;
}


int maze_path(SqStack<Point>& s,int row,int col,Point entry,Point exit,int maze[MAXSIZE][MAXSIZE])
{
    s.Push(entry);
    if (maze[entry.x][entry.y]==1)
        return 0;
    maze[entry.x][entry.y]=2;
	int direction[4][2] = { -1,0,0,1,1,0,0,-1 };
	Point current,tmp;
	current.x=entry.x;current.y=entry.y;current.direction=0;
	if (entry==exit) return 1;
	while(current!=exit)//当前位置不为出口
    {
        current=getNextPoint(current);//current前进到下一个点
        if (Pass(current,maze,row,col)==1)//当前可以通过,且是未曾走到的通道块
        {
            maze[current.x][current.y]=2;//留下足迹
            s.Push(current);//将current点压入栈
        }
        else//当前不能通过
        {
            if (!s.judgeEmpty())//栈不为空
            {
                s.GetTop(current);//current回到上一个点
                while (current.direction==3&&!s.judgeEmpty())
                {
                    s.Pop(current);
                    s.GetTop(current);
                }
                if (current.direction<3)
                {
                    current.direction++;//改变方向
                    s.Pop(tmp);
                    s.Push(current);//将current点压入栈
                }
            }
            else
                return 0;
        }
    }
    return 1;
}

void printStack(SqStack<Point>& S)
{
    Point *p=S.base;
    int n=0;
	while (p != S.top)
	{
		cout <<"(" << p->x - 1 << "," << p->y - 1<<")";
		n++;
		if (p != S.top - 1)
			cout << "->";
		if (n == 4)
		{
			cout << endl;
			n = 0;
		}
		p++;
	}
	cout<<endl;
}

int main()
{
    int maze[MAXSIZE][MAXSIZE] = {0};
	int row, col,x,y,i,k;
	cin >> row >> col;
	Point in, out;
	cin >> x >> y;
	in.x = ++x; in.y = ++y;
	cin >> x >> y;
	out.x = ++x; out.y = ++y;
	for (i = 0; i < MAXSIZE; i++)
		for (k = 0; k < MAXSIZE; k++)
			maze[i][k] = 1;
	for (i = 1; i <= row; i++)
		for (k = 1; k <= col; k++)
		{
			cin >> maze[i][k];
			if (maze[i][k] == 0)
				sum++;
		}
    SqStack<Point> s;
    int pathNum=maze_path(s,row,col,in,out,maze);
	if (pathNum == 0)
		cout << "No Path";
	else
		printStack(s);

	return 0;
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值