数据结构实训四——图的操作

1.实验目的:
(1)掌握回溯算法;
(2)掌握图的深度优先和广度优先搜索算法并用来解决实际问题;
2. 实验内容:
迷宫求解:以一个m*n的长方阵表示迷宫,0和1分别表示迷宫中的通路和障碍。设计一个程序,对任意设定的迷宫,求出一条从入口到出口的通路,或得出没有通路的结论。要求如下:
(1)首先实现一个栈类型,利用回溯法求解迷宫路径(非递归程序)。求得的通路以三元组(i,j,d)的形式输出,其中(i,j)指示迷宫中的一个坐标,d表示走到下一坐标的方向。
(2)建立图的存储结构,利用深度优先搜索,求得迷宫路径。输出方式自行定义,简单清晰则可。
(3)利用广度优先搜索,求得迷宫路径。输出方式自行定义,简单清晰则可。
(4)假如有多条路径,如何求最短的那一条路径?
3.实验代码:

#include<bits/stdc++.h>
using namespace std;
int n,m;
int mp[110][110];
struct node
{
    int x,y;
    string dir;
};
bool check(node t)///判断某个节点是否可以走
{
    int x=t.x,y=t.y;
    if(x>=1&&x<=n&&y>=1&&y<=m&&!mp[x][y]) return 1;
    return 0;
}
void init()
{
    ///输入迷宫
    cin>>n>>m;
    for(int i=1; i<=n; i++)
        for(int j=1; j<=m; j++)
            cin>>mp[i][j];
}
void findpath1()///非递归求解迷宫路径
{
    stack<node>stk;
    node now= {1,1,"0"};
    stk.push({1,1,"0"});
    while(!stk.empty())
    {
        node t=stk.top();
        if(t.x==n&&t.y==m)
        {
            break;
        }
        node ne=t;
        mp[t.x][t.y]=2;

        ne=t;
        ne.x--;
        if(check(ne))
        {
            t.dir="up";
            stk.pop();
            stk.push(t);
            stk.push(ne);
            continue;
        }
        ne=t;
        ne.x++;
        if(check(ne))
        {
            t.dir="down";
            stk.pop();
            stk.push(t);
            stk.push(ne);
            continue;
        }
        ne=t;
        ne.y--;
        if(check(ne))
        {
            t.dir="left";
            stk.pop();
            stk.push(t);
            stk.push(ne);
            continue;
        }
        ne=t;
        ne.y++;
        if(check(ne))
        {
            t.dir="right";
            stk.pop();
            stk.push(t);
            stk.push(ne);
            continue;
        }
        t=stk.top();
        stk.pop();
        mp[t.x][t.y]=3;
    }
    vector<node>v;
    while(!stk.empty())
    {
        v.push_back(stk.top());
        stk.pop();
    }
    reverse(v.begin(),v.end());
    for(int i=0; i<v.size(); i++) cout<<v[i].x<<" "<<v[i].y<<" "<<v[i].dir<<endl;
}
stack<node>path,tmp;
int nx[]= {0,0,1,-1};
int ny[]= {1,-1,0,0};
int vis[110][110];
int cnt=0;
void findpath2(int x,int y) ///dfs求解迷宫所有路径
{
    if(x==n&&y==m)
    {
        cout<<"***************路径"<<++cnt<<"*****************"<<endl;
        while(!path.empty())
        {
            tmp.push(path.top());
            path.pop();
        }
        while(!tmp.empty())
        {
            cout<<"("<<tmp.top().x<<","<<tmp.top().y<<")"<<endl;
            path.push(tmp.top());
            tmp.pop();
        }
        return ;
    }
    if(x<1||x>n||y<1||y>m) return ;
    for(int i=0; i<4; i++)
    {
        int xx=x+nx[i],yy=y+ny[i];
        if(xx>=1&&xx<=n&&yy>=1&&yy<=m&&!mp[xx][yy]&&vis[xx][yy]==0)
        {
            vis[xx][yy]=1;
            path.push({xx,yy});
            findpath2(xx,yy);
            vis[xx][yy]=0;
            path.pop();
        }
    }
}
queue<node>q;
int dis[110][110],fx[110][110],fy[110][110];
void Prinpath3(int x,int y)///bfs打印路径 递归打印
{
    if(x!=-1&&y!=-1)
    {
        Prinpath3(fx[x][y],fy[x][y]);
        cout<<"("<<x<<","<<y<<")"<<endl;
    }
}
void findpath3()///bfs求解最短路径
{
    memset(dis,-1,sizeof dis);///初始化距离数组
    q.push({1,1});///将起始点放入队列
    dis[1][1]=0;///初始化距离
    fx[1][1]=fy[1][1]=-1;///表示这个点的上一个点的坐标
    while(!q.empty())
    {
        node now=q.front();
        q.pop();
        for(int i=0; i<4; i++)
        {
            node nex;
            nex.x=now.x+nx[i],nex.y=now.y+ny[i];
            if(check(nex)&&dis[nex.x][nex.y]==-1)
            {
                q.push(nex);
                dis[nex.x][nex.y]=dis[now.x][now.y]+1;
                fx[nex.x][nex.y]=now.x;
                fy[nex.x][nex.y]=now.y;
            }
        }
    }
    Prinpath3(n,m);
}
int main()
{
    init();
    //findpath1();
    // findpath2(1,1);
    findpath3();
    return 0;
}
/*
3 3
0 1 1
0 1 1
0 0 0
*/

posted @ 2020-12-23 13:04  OvO1  阅读(88)  评论(0编辑  收藏  举报