zoukankan      html  css  js  c++  java
  • 列出连通集(DFS及BFS遍历图) -- 数据结构

    题目:

    7-1 列出连通集 (30 分)

    给定一个有N个顶点和E条边的无向图,请用DFS和BFS分别列出其所有的连通集。假设顶点从0到N1编号。进行搜索时,假设我们总是从编号最小的顶点出发,按编号递增的顺序访问邻接点。

    输入格式:

    输入第1行给出2个整数N(0<N10)和E,分别是图的顶点数和边数。随后E行,每行给出一条边的两个端点。每行中的数字之间用1空格分隔。

    输出格式:

    按照 “ { v1, v2, v3, ... ,vk } ”的格式,每行输出一个连通集。先输出DFS的结果,再输出BFS的结果。

    1​​ v2​​ ... vk​​ }"的格式,每行输出一个连通集。先输出DFS的结果,再输出BFS的结果。

    输入样例:

    8 6
    0 7
    0 1
    2 0
    4 1
    2 4
    3 5
    

    输出样例:

    { 0 1 4 2 7 }
    { 3 5 }
    { 6 }
    { 0 1 2 7 4 }
    { 3 5 }
    { 6 }
    

    分析:

     当读完这道题之后,很容易就能够知道我们需要做的两件事:①构建图  ②DFS遍历和BFS遍历

    这里为了方便起见(同时数据量并不大),这里将采用邻接矩阵存储图。


    代码:

    对结构体结构的定义:

    #define max 10
    typedef int vertex_type;
    typedef int edge_type;
    typedef struct graph_matrix{
        int n, e;//顶点数;边数 
        vertex_type vexs[max];//顶点一维数组 
        edge_type edges[max][max];//邻接矩阵二维数组,元素类型为vector<vertex_type>
    }gm;

    全局变量visit[]

    //visit[]数组;全局变量 
    int visit[max] = {0};

    ①构建图

    //创建图 
    void create_gm(gm &gm)
    { 
        cin>>gm.n>>gm.e;
        memset(gm.edges, 0, sizeof(gm.edges));
        for(int i=0; i<gm.n; i++){
            gm.vexs[i] = i;
        }
        
        //输入边数据 
        int a, b;
        for(int i=0; i<gm.e; i++){
            cin>>a>>b;
            gm.edges[a][b] = 1;
            gm.edges[b][a] = 1;
        }
    }

    ②DFS遍历

    //深度优先 
    //id: 以id为起始点
    void DFS(gm &gm, int id)
    {
        visit[id] = 1;
        cout<<id<<" ";
        for(int i=0; i<gm.n; i++){
            if(gm.edges[i][id] == 1 && visit[i] == 0){
                DFS(gm, i);
            }
        }
     } 

    ③BFS遍历

    //宽度优先 
     void BFS(gm &gm, int id)
    {
        visit[id] = 1;
        queue<int> qu; 
        qu.push(id);
        while(qu.size() != 0){
            int mark = qu.front();
            qu.pop();
            cout<<mark<<" ";
            for(int i=0; i<gm.n; i++){
                if(gm.edges[i][mark] == 1 && visit[i] == 0){
                    visit[i] = 1;
                    qu.push(i);
                }
            }
        }
     }

    全部的代码:

    #include<iostream>
    #include<cstring>
    #include<queue>
    using namespace std;
    
    #define max 10
    typedef int vertex_type;
    typedef int edge_type;
    typedef struct graph_matrix{
        int n, e;//顶点数;边数 
        vertex_type vexs[max];//顶点一维数组 
        edge_type edges[max][max];//邻接矩阵二维数组,元素类型为vector<vertex_type>
    }gm;
    
    //函数声明 
    void create_gm(gm &gm);  
    void DFS(gm &gm, int id);
    void BFS(gm &gm, int id);
    
    //visit[]数组;全局变量 
    int visit[max] = {0};
    
    int main()
    {
        gm gm;//定义一个叫做gm的邻接矩阵 
        create_gm(gm);
        
        //调用DFS遍历 
        for(int i=0; i<gm.n; i++){
            if(visit[i] == 1)continue;
            cout<<"{ ";
            DFS(gm ,i);
            cout<<"}"<<endl;
        }
        
        //重置visit[]数组 
        memset(visit, 0, sizeof(visit));
        
        //调用BFS遍历 
        for(int i=0; i<gm.n; i++){
            if(visit[i] == 0){
                cout<<"{ ";
                BFS(gm ,i);
                cout<<"}"<<endl;
            }
        }
        return 0;
     } 
     
    //创建图 
    void create_gm(gm &gm)
    { 
        cin>>gm.n>>gm.e;
        memset(gm.edges, 0, sizeof(gm.edges));
        for(int i=0; i<gm.n; i++){
            gm.vexs[i] = i;
        }
        
        //输入边数据 
        int a, b;
        for(int i=0; i<gm.e; i++){
            cin>>a>>b;
            gm.edges[a][b] = 1;
            gm.edges[b][a] = 1;
        }
    }
    
    //深度优先 
    void DFS(gm &gm, int id)
    {
        visit[id] = 1;
        cout<<id<<" ";
        for(int i=0; i<gm.n; i++){
            if(gm.edges[i][id] == 1 && visit[i] == 0){
                DFS(gm, i);
            }
        }
     } 
     
    //宽度优先 
     void BFS(gm &gm, int id)
    {
        visit[id] = 1;
        queue<int> qu; 
        qu.push(id);
        while(qu.size() != 0){
            int mark = qu.front();
            qu.pop();
            cout<<mark<<" ";
            for(int i=0; i<gm.n; i++){
                if(gm.edges[i][mark] == 1 && visit[i] == 0){
                    visit[i] = 1;
                    qu.push(i);
                }
            }
        }
     }
    ALL

    总结:

     在这个题目中主要是对之前在树章节中,对关于树的前序遍历(DFS)和层次遍历(BFS)的知识迁移。

    ① DFS往往会运用到来进行实现,而递归就是利用栈的一个实现方法,递归特性使算法代码简洁的同时,也使算法理解困难,

    所以对于我这种初学者来说画图和动手实践是最好的学习方法。

    例子:“走迷宫,你没有办法用分身术同时走进多叉道路中,不撞南墙不回头。”(来源自网络)

    ② BFS则是要运用到队列,程序流程相对于DFS来说更为清晰。

    例子:“当你眼镜掉了,你趴在地上找,你总是会先摸靠近你的地方,如果没有,再摸远一点的地方。”(来源自网络)

    如何对已有知识的新运用也是能力提升的一种,在此我也对DFS和BFS有了更深一层的理解。

    嘻嘻:)

    ——但少闲人,所以等等。
  • 相关阅读:
    【Javascript】javascript学习 三十二 JavaScript 表单验证
    【Javascript】javascript学习 三十四 JavaScript 图像地图
    【Javascript】javascript学习 三十三 JavaScript 动画
    【Javascript】javascript学习 三十六 创建你自己的 JavaScript 对象
    【Javascript】javascript学习 三十七 JavaScript 总结
    【HTML】HTML 教程(系列教程转载)
    【XML】XML概述(连载)
    【Javascript】javascript学习 三十五 JavaScript 计时
    【XML】XML教程
    判断各版本IE的HTML和CSS语句
  • 原文地址:https://www.cnblogs.com/yi2105/p/10840943.html
Copyright © 2011-2022 走看看