c++链表实现队列,深搜加宽搜,加模版类实现迷宫问题;

数据结构作业二,用链表实现队列,用深搜宽搜解决迷宫问题,另是模版类的用法;
模版类用法举例:
栗子一:

template<class bbb>
class Node{
public:
    bbb data;
    Node *next;
    Node(){next=NULL;}
};//只在前面加template关键字就可以;

栗子二:

template<class ttt>
class Linkquuue{
public:
    Linkquuue();
    ~Linkquuue();
    void Enqueue(ttt x);
    int  Dequeue();
    ttt Getqueue();
    int Empty(){if(Front==Rear)return 1;return 0 ;}
private:
    Node<ttt>*Front,*Rear;
};
template<class ttt>
Linkquuue<ttt>::Linkquuue(){
    Node<ttt> *s=new Node<ttt>;
    s->next=NULL;
    Front=Rear=s;
}
template<class ttt>
Linkquuue<ttt>::~Linkquuue(){
    while(Rear!=Front){
        Node<ttt> *p;
        ttt x;
        p=Front->next;
        Front->next=p->next;
        if(p->next==NULL)Rear=Front;
        delete p;
    }
}

template<class ttt>
void Linkquuue<ttt>::Enqueue(ttt x){
    Node<ttt> *s=new Node<ttt>;
    s->data=x;
    s->next=NULL;
    Rear->next=s;
    Rear=s;
}
template<class ttt>
int Linkquuue<ttt>::Dequeue()
{
    if(Rear==Front)return 0;
    Node<ttt> *p;
    ttt x;
    p=Front->next;
    x=p->data;
    Front->next=p->next;
    if(p->next==NULL)Rear=Front ;
    delete p;
    return 1;
}
template<class ttt>
ttt Linkquuue<ttt>::Getqueue(){
    return Front->next->data;
}///类里只在类外加一个模版类声明即可,类外,在哪里加就在哪里加参数表;
///所以模版类声明的有效范围只在当前区域内有效;

链表实现队列:
代码:

template<class bbb>
class Node{
public:
    bbb data;
    Node *next;
    Node(){next=NULL;}
};
template<class ttt>
class Linkquuue{
public:
    Linkquuue();
    ~Linkquuue();
    void Enqueue(ttt x);
    int  Dequeue();
    ttt Getqueue();
    int Empty(){if(Front==Rear)return 1;return 0 ;}
private:
    Node<ttt>*Front,*Rear;
};
template<class ttt>
Linkquuue<ttt>::Linkquuue(){
    Node<ttt> *s=new Node<ttt>;
    s->next=NULL;
    Front=Rear=s;
}
template<class ttt>
Linkquuue<ttt>::~Linkquuue(){
    while(Rear!=Front){
        Node<ttt> *p;
        ttt x;
        p=Front->next;
        Front->next=p->next;
        if(p->next==NULL)Rear=Front;
        delete p;
    }
}

template<class ttt>
void Linkquuue<ttt>::Enqueue(ttt x){
    Node<ttt> *s=new Node<ttt>;
    s->data=x;
    s->next=NULL;
    Rear->next=s;
    Rear=s;
}
template<class ttt>
int Linkquuue<ttt>::Dequeue()
{
    if(Rear==Front)return 0;
    Node<ttt> *p;
    ttt x;
    p=Front->next;
    x=p->data;
    Front->next=p->next;
    if(p->next==NULL)Rear=Front ;
    delete p;
    return 1;
}
template<class ttt>
ttt Linkquuue<ttt>::Getqueue(){
    return Front->next->data;
}

深搜加宽搜实现迷宫问题(举例说明),
///实验问题及具体举例说明;
/*
迷宫问题。以一维数组Maze[m+2][n+2]数组描述一个迷宫,元素。值为0表示通道,值为1表示墙壁,以 Maze[1][1]表示迷宫的入口,maze[m][n]表示迷宫的出口,外层数据全为1表示外围墙壁,Maze数组内层数据表达一个迷宫(数据来源于输入或随机赋值),打印一条如何从Maze[1][1]到达出口Maze[m][n]的路径,若无解,则打印“无解”信息
迷宫问题举例:
设:
1):图大小给出,n行m列1<=n,m<=20,图中1为墙壁,0为可走的路;
2):从当前点可移动到上下左右四点(如果没有障碍及可走的情况下)
3):求(1,1)到(m,n)所走的最短路,如有多条输出任意一条,没有输出”no a way!”;
4):描述:多组数据读到文档尾,输入n,m,表示图的大小为n行m列,接下来n行每行有m个数;
输出:输出最短路径,每行一个坐标表示走过的点,多组解输出任意一组,无解情况输出”no a way!”,然后换行;
样例:
样例输入

2 5
0 1 0 0 0
0 0 0 1 0
4 6
0 1 1 0 0 0
0 0 1 0 1 1
0 1 1 1 1 0
0 1 1 1 0 0
2 2
0 1
1 0

样例输出1

1 1
2 1
2 2
2 3
1 3
1 4
1 5
2 5

no a way!

no a way!

*/
具体代码:
简版:

#include <bits/stdc++.h>
using namespace std;
template<class bbb>
class Node{
public:
    bbb data;
    Node *next;
    Node(){next=NULL;}
};
template<class ttt>
class Linkquuue{
public:
    Linkquuue();
    ~Linkquuue();
    void Enqueue(ttt x);
    int  Dequeue();
    ttt Getqueue();
    int Empty(){if(Front==Rear)return 1;return 0 ;}
private:
    Node<ttt>*Front,*Rear;
};
template<class ttt>
Linkquuue<ttt>::Linkquuue(){
    Node<ttt> *s=new Node<ttt>;
    s->next=NULL;
    Front=Rear=s;
}
template<class ttt>
Linkquuue<ttt>::~Linkquuue(){
    while(Rear!=Front){
        Node<ttt> *p;
        ttt x;
        p=Front->next;
        Front->next=p->next;
        if(p->next==NULL)Rear=Front;
        delete p;
    }
}

template<class ttt>
void Linkquuue<ttt>::Enqueue(ttt x){
    Node<ttt> *s=new Node<ttt>;
    s->data=x;
    s->next=NULL;
    Rear->next=s;
    Rear=s;
}
template<class ttt>
int Linkquuue<ttt>::Dequeue()
{
    if(Rear==Front)return 0;
    Node<ttt> *p;
    ttt x;
    p=Front->next;
    x=p->data;
    Front->next=p->next;
    if(p->next==NULL)Rear=Front ;
    delete p;
    return 1;
}
template<class ttt>
ttt Linkquuue<ttt>::Getqueue(){
    return Front->next->data;
}
struct zuobiao
{
    int x,y;
    zuobiao(int a,int b){x=a;y=b;}
    zuobiao(){};
};
const int maxn=22;
int tu[maxn][maxn];
int lu[maxn][maxn];
int n,m;
int showlu(int x,int y)
{
    if(x==0&&y==0){
        cout<<x+1<<" "<<y+1<<endl;
        return 0;
    }
    for(int i=-1;i<2;i++){
        for(int j=-1;j<2;j++){
          if((i==0||j==0)&&i^j!=0)
            {
                int si=x+i,wai=y+j;
                if(si>=0&&si<n&&wai>=0&&j<m){
                    if(lu[si][wai]==(lu[x][y]-1)){
                        showlu(si,wai);
                        cout<<x+1<<" "<<y+1<<endl;
                        return 0;
                    }
                }
            }
        }
    }
    return 0;
}
int main()
{
    while(cin>>n>>m){
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                cin>>tu[i][j];
            }
        }
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                if(tu[i][j]==1)
                    lu[i][j]=-1;
                if(tu[i][j]==0)
                    lu[i][j]=0;
            }
        }
        lu[0][0]=1;
        Linkquuue<zuobiao>qu;
        qu.Enqueue(zuobiao(0,0));
        while(!qu.Empty()){
            zuobiao now=qu.Getqueue();
            qu.Dequeue();
            for(int i=-1;i<2;i++){
                for(int j=-1;j<2;j++){
                    if((i==0||j==0)&&i^j!=0){
                        int si=now.x+i,wai=now.y+j;
                        if(si>=0&&si<n&&wai>=0&&wai<m){
                            if(lu[si][wai]==0){lu[si][wai]=lu[now.x][now.y]+1;
                            qu.Enqueue(zuobiao(si,wai));
                                }
                            }
                        }
                    }
                }

            }
        if(lu[n-1][m-1]==0||lu[n-1][m-1]==-1)
            cout<<"no a way!"<<endl;
        else{
            showlu(n-1,m-1);
            cout<<endl;
        }
    }
    return 0;
}

加注释版:

#include <bits/stdc++.h>
using namespace std;
template<class bbb>
class Node{                 ///链表里的节点;
public:
    bbb data;
    Node *next;
    Node(){next=NULL;} ///可直接生成节点;
};
template<class ttt>
class Linkquuue{            ///队列类,用链表结构存储;
public:
    ///构造函数,生成了一个标志节点,没注意这个,debug到天亮;
    Linkquuue();
    ///析构函数,因为是通过new申请的内存,必须要自己动手释放,
    ///否则析构函数一般不用写东西;
    ~Linkquuue();
    ///入队;
    void Enqueue(ttt x);
    ///出队,先入者先出;
    int  Dequeue();
    ///得到队头的元素,注意对头有标志节点;
    ttt Getqueue();
    ///判断是否为空;为空输出1,不为空输出0;
    int Empty(){if(Front==Rear)return 1;return 0 ;}
private:
    ///队列元素,只记录队首和队尾即可;
    Node<ttt>*Front,*Rear;
};
template<class ttt>
///构造函数,申请一个新节点,其实不用,但是改动麻烦,注意即可;
Linkquuue<ttt>::Linkquuue(){
    Node<ttt> *s=new Node<ttt>;
    s->next=NULL;
    Front=Rear=s;
}
template<class ttt>
///析构函数,析构掉申请的内存,主要构造时候申请的空节点;
Linkquuue<ttt>::~Linkquuue(){
    while(Rear!=Front){
        Node<ttt> *p;
        ttt x;
        p=Front->next;
        Front->next=p->next;
        if(p->next==NULL)Rear=Front;
        delete p;
    }
    delete Front;
}

template<class ttt>
///入队操作,在队首添加即可,注意空节点;
void Linkquuue<ttt>::Enqueue(ttt x){
    Node<ttt> *s=new Node<ttt>;
    s->data=x;
    s->next=NULL;
    Rear->next=s;
    Rear=s;
}
///出队操作,去掉队尾申请的内存即可;
template<class ttt>
int Linkquuue<ttt>::Dequeue()
{
    if(Rear==Front)return 0;
    Node<ttt> *p;
    ttt x;
    p=Front->next;
    x=p->data;
    Front->next=p->next;
    if(p->next==NULL)Rear=Front ;
    delete p;
    return 1;
}
///根据先入先出的原则,拿出队首元素,
///主要第一个为空节点,返回第二个节点
template<class ttt>
ttt Linkquuue<ttt>::Getqueue(){
    return Front->next->data;
}
///上面的操作均在模版类中实现,这里具体到类;
///为下面的程序开个坐标类,记录处理到的坐标;
struct zuobiao
{
    int x,y;
    ///支持类型强转;
    zuobiao(int a,int b){x=a;y=b;}
    ///支持直接建立坐标类,不必赋值;
    zuobiao(){};
};
///本程序的参数,及地图的最大是多少,后期可调;
const int maxn=22;
///存图,即原始的数据;
int tu[maxn][maxn];
///存路,之后的操作在这里进行,可保护原始数据;
int lu[maxn][maxn];
///参数允许范围内具体地图的大小,这里开全局是为深搜的调用;
int n,m;
///输出路径,宽搜跑地图得到路径,深搜可反向进行搜索,输出路径;
int showlu(int x,int y)
{
    ///深搜结束条件,即搜索到起始位置;
    if(x==0&&y==0){
        cout<<x+1<<" "<<y+1<<endl;
        return 0;
    }
    ///从高位向低位进行搜索,因为高位是低位宽搜来的,所以一定有路,
    ///关系如同,根可以找到n多叶子,叶子只能找到一个根;
    for(int i=-1;i<2;i++){
        for(int j=-1;j<2;j++){
          if((i==0||j==0)&&i^j!=0)
            {
                int si=x+i,wai=y+j;
                if(si>=0&&si<n&&wai>=0&&j<m){
                    if(lu[si][wai]==(lu[x][y]-1)){
                        ///找到下个点时进行递归操作;
                        showlu(si,wai);
                        ///因为要正着输出路径,所以,
                        ///放在递归的后面,可以从低位输出;
                        cout<<x+1<<" "<<y+1<<endl;
                        ///这里符合条件就返回,保证了只输出一条路径;
                        return 0;
                        }
                    }
                }
            }
        }
    return 0;
}
int main()
{
    ///保证有数据就可以读入操作;
    while(cin>>n>>m){
        ///读入数据结构;其实可以写成函数,不过意义不大;
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                cin>>tu[i][j];
            }
        }
        ///路径的初始化操作;
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                if(tu[i][j]==1)
                    lu[i][j]=-1;
                if(tu[i][j]==0)
                    lu[i][j]=0;
            }
        }
        ///因为下面的入队条件是等零,所以这里初始化下;
        lu[0][0]=1;
        ///首先声明队列,入队起点;
        Linkquuue<zuobiao>qu;
        qu.Enqueue(zuobiao(0,0));
        while(!qu.Empty()){
            ///得到队首元素;
            zuobiao now=qu.Getqueue();
            ///队首处理完成,出队;
            qu.Dequeue();
            for(int i=-1;i<2;i++){
                for(int j=-1;j<2;j++){
                    if((i==0||j==0)&&i^j!=0){
                        int si=now.x+i,wai=now.y+j;
                        if(si>=0&&si<n&&wai>=0&&wai<m){
                            if(lu[si][wai]==0){lu[si][wai]=lu[now.x][now.y]+1;
                            qu.Enqueue(zuobiao(si,wai));
                            ///搜索到下个符合条件的位置入队;
                                }
                            }
                        }
                    }
                }

            }
        ///lu数组没有改变,说明到达不到,输出no a way!;
        if(lu[n-1][m-1]==0||lu[n-1][m-1]==-1)
            cout<<"no a way!"<<endl<<endl;
        ///有路及输出路径;
        else{
            showlu(n-1,m-1);
            cout<<endl;
        }
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值