栈的应用之迷宫问题

/************************************************************************/
/*自定义栈                                                                         */
/*通过自定义的简单栈以满足迷宫求解                */
/*功能:push() 将元素加入栈中                                  */
/*               pop() 退栈;topValue() 获得栈顶元素        */
/*                clear() 清除栈 length() 获得栈中元素个数*/


栈的应用之迷宫:maze:
(0)过程:
(0.1)构建迷宫:
(0.2)寻找路径:
(0.3)打印路径:
(1)迷宫图解:


(1.1)迷宫图解:


(1.2)迷宫路径:
寻找一条从入口到出口的路径,路径是一个点栈(即栈中元素是点),每个点上都没有障碍,
且每一个点都是前一个点的上、下、左、右(东、南,西,北)的邻居。


(2)思路:穷举求解:


从入口出发,沿着某一个方向探索,如果可以走通,则继续前行;
否则沿原路返回,换一个方向再继续探索,知道所有的通路都探索到为止。


/************************************************************************/
#include <stack>
#include <iostream>
#include <windows.h>
using namespace std;


template<typename Elem> class PathStack: public stack<Elem>
{
private:
    int size;
    int top;
    Elem* listArray;
public:
    PathStack(int sz ){
        size = sz;
        top = 0;
        listArray = new Elem[sz];
    }
    ~PathStack(){ delete []listArray; }
    void clear(){ top = 0; }
    /****向栈中加入元素****/
    bool push(const Elem& item);
    /***********退栈**********/
    Elem pop();
    /********获得栈顶元素*******/
    Elem topValue() const;
    int length() const { return top; }


    bool isEmpty();
};


template<typename Elem>
bool PathStack<Elem>::push(const Elem& item){
    if(top == size) return false;
    listArray[top++] = item;
    return true;
}
template<typename Elem>
bool PathStack<Elem>::isEmpty(){
return top==0;
}


template<typename Elem>
Elem PathStack< Elem>::pop(){
    Elem it;
    if(top == 0) return it;
    it = listArray[--top];
    return it;
}


template<typename Elem>
Elem PathStack< Elem>::topValue() const{
    Elem it;
    if(top == 0) return it;
    it = listArray[top - 1];
    return it;
}
 //迷宫求解的方法类
//功能:通过findPath() 方法实现对路径的查找
//              通过printPath()方法将路径打印出来


class MazeSolveMethod
{
private:
    static int maze[10][10];//存放迷宫数据
    PathStack<int> pathStack;//定义栈
public:
    MazeSolveMethod():pathStack(100){
    }
    ~MazeSolveMethod(){ }
    bool findPath(int startX,int startY);
    void printPath() const;
};


int MazeSolveMethod::maze[10][10] = {
      {1,1,1,1,1,1,1,1,1,1},
    {1,0,0,0,0,0,0,0,0,1},
    {1,0,0,1,1,0,0,0,0,1},
    {1,1,0,1,1,0,1,1,0,1},
    {1,1,0,0,1,0,1,1,0,1},
    {1,0,1,0,1,0,0,1,0,1},
    {1,0,1,0,0,0,0,1,0,1},
    {1,1,1,1,1,0,0,0,0,1},
    {1,1,1,1,1,1,1,0,0,1},
    {1,1,1,1,1,1,1,1,1,1},


};
/*
maze[i][j]=0,表示可通;
maze[i][j]=1,表示不通;
maze[i][j]=2,表示已经走过;
maze[i][j]=3,也表示死胡同;
*/
bool MazeSolveMethod::findPath(int startX,int startY){
    int x = startX;
    int y = startY;
    pathStack.push(x);
    pathStack.push(y);
    maze[x][y] = 2;
    cout<<"进入方法!!"<<endl;
    while(!pathStack.isEmpty()){
          /*方法不好之处是由于起点通常在左上,然后终点在右下,所以
          应该先将判断当前节点的右,下,然后再判断左,上;这样可以快一点;
          另外,此中如果无法到达终点,好像是无限循环的。显然不可以。
          */
        if(maze[x][y+1] == 0){
              /*判断当前节点的右邻居*/
            pathStack.push(x);
            pathStack.push(++y);
            maze[x][y] = 2;


        }else if(maze[x+1][y] == 0){
              /*判断当前节点的下邻居*/
            pathStack.push(++x);
            pathStack.push(y);
            maze[x][y] = 2;




        }else if(maze[x][y-1] == 0){
              /*判断当前节点的左邻居*/
            pathStack.push(x);
            pathStack.push(--y);
            maze[x][y] = 2;


        }else if(maze[x-1][y] == 0){
              /*判断当前节点的上邻居*/
            pathStack.push(--x);
            pathStack.push(y);
            maze[x][y] = 2;


        }
        if(x==6&& y==6)
        return true;


       cout<<"( "<<x<<" , "<<y<<" )  ";
        /*
        注意:此中的当前点的上下左右可通,则将当前点可通的上下左右压入栈中;
        然后更新当前点为刚压入栈中的元素。
        因为:此中是++x,--x,++y,--y,所以x,y发生了改变,即当前点发生了更新;
        */
        if(maze[x-1][y] != 0 && maze[x][y+1] != 0 && maze[x+1][y] != 0 && maze[x][y-1] != 0){
            /*如果当前位置的右,下,左,上均走过或不通*/


                maze[x][y] = 3;
                y = pathStack.pop();
                x = pathStack.pop();
                /*当前点的上下左右不通,或者已经走过,就将当前点标记为死胡同。
                然后从栈中弹出当前点。
                */
                if(pathStack.isEmpty()==true)
                return false;




       y = pathStack.topValue();
            int temp = pathStack.pop();
            x = pathStack.topValue();
            pathStack.push(temp);
            /*
            更新当前点,先获取y,要获取x,必须弹出y,然后在将弹出的y压入进去。(x始终没有弹出。)
            */
        }
    }


    return false;
}




void MazeSolveMethod::printPath() const{
    cout<<"printPath"<<endl;
    for(int i=0; i<10; i++){
        for(int j=0; j<10; j++){
            if(maze[i][j] == 2)
                cout<<'>'<<"  ";
            else if(maze[i][j] == 3)
                cout<<'x'<<"  ";
            else if(maze[i][j]==1)
                cout<<1<<"  ";
            else
                  cout<<0<<"  ";
        }
        cout<<endl;
    }
}
int main(){


    MazeSolveMethod solve;
    if(solve.findPath(1,1))
    solve.printPath();


    else
    cout<<"no path from start to end "<<endl;
    system("pause");
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值