数据结构第五天:列出连通集 【图的两种建立,图的两种遍历】

这道题是个图的入门题,其过程就是将图建立出来,然后对这个图进行两种遍历。

其实就三步:

1.建立图(邻接矩阵):

struct GNode{
   int N;
   int E;
   int map[11][11];
};
typedef GNode* UnicomSet;
UnicomSet MAP;
void GreateMap(int n,int m){
     MAP = (UnicomSet)malloc(sizeof(struct GNode));
     MAP -> N = n;
     MAP -> E = m;
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            MAP->map[i][j] = 0;
        }
    }
    while(m--){
        int a,b;
        cin>>a>>b;
        MAP->map[a][b]=1;
        MAP->map[b][a]=1;
    }
    return;
}

 2.深度遍历,就是只要两点有边事就递归出来然后打印然后用visD数组保存一下已经遍历过的事实即可。(类比于树的先序遍历)

void Dfs(int start,int n){
   cout<<start<<" ";
    visD[start] = 1;
    for(int j=0;j<n;j++){
        if(visD[j]!=1&&MAP->map[start][j]==1){
            Dfs(j,n);
        }
    }
    return;
}

3.广度遍历,将第一个节点压入队列,然后循环遍历,和第一个节点有边的节点就压入队列(并用visB数组记录一下已经遍历过的事实)(类比于树的层序遍历)

void Bfs(int start,int n){
    cout<<"{ ";
    int hh = 0,tt = -1;
    queue[++tt] = start;
    visB[start] = 1;
    while(tt >= hh){
        int i = queue[hh++];
        for(int j=0;j<n;j++){
            if(MAP->map[i][j]==1&&visB[j]!=1){
                queue[++tt] = j;
                visB[j] = 1;
            }
        }
    }
    for(int i=0;i<=tt;i++)
        cout<<queue[i]<<" ";
    cout<<"}"<<endl;
    return;
}

然后这是全部的代码

#include <iostream>
using namespace std;

struct GNode{
   int N;
   int E;
   int map[11][11];
};
typedef GNode* UnicomSet;
UnicomSet MAP;
int visB[11];
int visD[11];
int queue[11];
void GreateMap(int n,int m){
     MAP = (UnicomSet)malloc(sizeof(struct GNode));
     MAP -> N = n;
     MAP -> E = m;
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            MAP->map[i][j] = 0;
        }
    }
    while(m--){
        int a,b;
        cin>>a>>b;
        MAP->map[a][b]=1;
        MAP->map[b][a]=1;
    }
    return;
}

void Bfs(int start,int n){
    cout<<"{ ";
    int hh = 0,tt = -1;
    queue[++tt] = start;
    visB[start] = 1;
    while(tt >= hh){
        int i = queue[hh++];
        for(int j=0;j<n;j++){
            if(MAP->map[i][j]==1&&visB[j]!=1){
                queue[++tt] = j;
                visB[j] = 1;
            }
        }
    }
    for(int i=0;i<=tt;i++)
        cout<<queue[i]<<" ";
    cout<<"}"<<endl;
    return;
}

void Dfs(int start,int n){
   cout<<start<<" ";
    visD[start] = 1;
    for(int j=0;j<n;j++){
        if(visD[j]!=1&&MAP->map[start][j]==1){
            Dfs(j,n);
        }
    }
    return;
}

int main(){
    int n,m;
     int a,b;
    cin>>n>>m;
    GreateMap(n,m);
    for(int i=0;i<n;i++){
        if(!visD[i]){
            cout<<"{ ";
            Dfs(i,n);
            cout<<"}"<<endl;
        }
    }
    for(int i=0;i<n;i++){
        if(!visB[i])Bfs(i,n);
    }
    return 0;
}

邻接表

解释一下为啥不用邻接表来建立,我试过了,过不了这道题感觉,因为判题机就是将我们输出的结果和电脑服务器中的样例对比一下,所以说我们如果输入的顺序不一样的话也是过不了的。

下面是我写的邻接表的代码

#include <iostream>
using namespace std;
#define N 100
//邻接表
struct Node{
    int id;
    Node *next;
    Node(int _id):id(_id),next(NULL){} 
}*head[N];

void add(int a,int b){
    auto B = new Node(b);
    auto A = new Node(a);
    B->next = head[a];
    A->next = head[b];
    head[a] = B;
    head[b] = A;
}
int visB[N];
int visD[N];
int queue[1000];
void Bfs(int start,int n){
    int hh =0 , tt = -1;
    queue[++tt] = start;
    while(hh <= tt){
        int end = queue[hh++];
        if(visB[end]==0){
            cout<<end<<" ";
            visB[end]=1;
        }
        for(auto p = head[end];p;p=p->next){
            if(visB[p->id]==0){
                cout<<p->id<<" ";
                visB[p->id]=1;
                queue[++tt] = p->id;
            }
        }
    }
    return;
}

void Dfs(int start,int n){
    if(visD[start]==0){
        visD[start] = 1;
        cout<<start<<" ";
    }
    for(auto p=head[start];p;p=p->next){
        if(visD[p->id]==0){
            Dfs(p->id,n);
        }
    }
    return;
}

int main(){
    int n,m;
     int a,b;
    cin>>n>>m;
//建立表
    while(m--){
        cin>>a>>b;
        add(a,b);
    }
    for(int i=0;i<n;i++){
        if(!visD[i]){
            cout<<"{ ";
            Dfs(i,n);
            cout<<"}"<<endl;
        }
    }
    for(int i=0;i<n;i++){
        if(!visB[i]){
            cout<<"{ ";
            Bfs(i,n);
            cout<<"}"<<endl;
        }
    }
    return 0;
}

这种方式出来的答案如下,所以就会判我们错,所以不用尝试了,这道题只能用邻接矩阵写。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值