列出连通集

二刷数据结构删了以前写的现在再来一次是真的感觉像是通了一样,全身舒爽,顺便一提md真不错,虽然目前就会写个标题,学习视频来自中国大学MOOC浙大数据结构

题目叙述:给定一个有N个顶点和E条边的无向图,请用DFS和BFS分别列出其所有的连通集。假设顶点从0到N−1编号。进行搜索时,假设我们总是从编号最小的顶点出发,按编号递增的顺序访问邻接点。
输入格式: 输入第1行给出2个整数N(0<N≤10)和E,分别是图的顶点数和边数。随后E行,每行给出一条边的两个端点。每行中的数字之间用1空格分隔。
输出格式: 按照"{ v​1​​ v​2​​ … v​k​​ }"的格式每行输出一个连通集。先输出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 }

程序
邻接矩阵程序
邻接表程序

邻接矩阵表示法
邻接表表示法


  • 邻接矩阵表示法[C]

主函数

#include <stdio.h>
#include <stdlib.h>
typedef int Vertex;//节点数据类型
typedef struct GNode{
    int Nv; //存储节点数
    int Ne; //存储边数
    Vertex **G; //指向存储邻接矩阵的二维数组的指针
}*Graph;
    Graph g;
int main(void){
    int i;
    creat_graph(&g); //初始化构建的图,并将题目中给定的边加入其中
    Vertex visit[g->Nv] ;//构建检测数组
    for(i=0;i<g->Nv;i++)//初始化,可做出全局数组,依个人喜好来做,建议少使用全局变量
    visit[i] = 0;
    for(i = 0;i<g->Nv;i++)//从节点0开始使用DFS找出所有连通集
    if(visit[i]==0){
    printf("{ ");
    DFS(i,visit);//深度优先搜索算法
    printf("}\n");
    }
    for(i=0;i<g->Nv;i++)//恢复检测数组全置为0
    visit[i] = 0;
    for(i = 0;i<g->Nv;i++)//从节点0开始使用BFS找出所有连通集
    if(visit[i]==0){
    printf("{ ");
    BFS(i,visit);//广度优先搜索算法
    printf("}\n");
    }
    free(g); //释放动态分配的内存
    return 0;
}

调用函数

void creat_graph(Graph *g){//初始化一个邻接矩阵
    int i,j,Nv,Ne;
    scanf("%d %d",&Nv,&Ne);
    (*g) = (Graph)malloc(sizeof(struct GNode));
    (*g)->Nv = Nv;
    (*g)->Ne = Ne;
    (*g)->G = (Vertex **)malloc(Nv*(sizeof(Vertex *)));//实现对使用矩阵大小的动态内存大小分配
    for(i = 0; i < Nv; i++){
        (*g)->G[i] = (Vertex *)malloc(Nv*(sizeof(Vertex)));
        for(j = 0; j<Nv; j++){
            (*g)->G[i][j] = 0;//图中全部边初始化为0
        }
    }
    while(Ne--){//输入图中所有的边
        scanf("%d %d",&i,&j);
        (*g)->G[i][j] = 1;
        (*g)->G[j][i] = 1;
    }
}
void DFS(Vertex x , Vertex *visit){ //DFS输出连通集
     int i;
     visit[x]=1;
     printf("%d ",x);
     for(i=0; i<g->Nv;i++){
         if(g->G[x][i]==1&&visit[i]==0)
         DFS(i,visit);
     }
}
void BFS(Vertex x,Vertex *visit){//BFS输出连通集
    Vertex queue[g->Nv];//构建一个队列用于存放以某一个节点为出发点的BFS路径上的节点
    int front =0, rear =0;
    int i ;
    queue[rear++] = x;
    visit[x] = 1;
    printf("%d ",x);//输出连通路头节点
    while(front!=rear){//当队首和队尾指针指向同一个位置时说明队列已空,即此连通路已遍历完毕
    int p=queue[front++];
    for(i=0;i<g->Nv;i++){
        if(g->G[p][i]==1&&visit[i]==0){
        printf("%d ",i);//输出其余节点
        visit[i]=1;
        queue[rear++] = i;
        }
    }
    }
}
  • 邻接表表示法[C]

待续……2019/4/19/21:15,
大晚上的熬死也要把他给贴出来,不过这道题由于其是黑盒测试,其实如果是邻接表的话无法准确的给出要求的答案,因为邻接表是无序的,若想使用邻接表的话还得对每一个建立的表进行排序,然而已经没必要做下去了,so就贴出下面的代码,他也可以得到计算结果,不过缺点就是未对first表排序,所以未达到了邻接表的要求,但目的已经达到就好,……Orz……哦哦哦,还有一点,代码最后未释放动态分配的内存,这点一定要记着释放,免得造成内存泄漏,最后的最后,今夜真美2019/4/20/00:51

主函数

#include <stdio.h>
#include <stdlib.h>
typedef int Vertex;
typedef struct ArcNode
{
    Vertex adjacent;
    struct ArcNode *next;
}ArcNode;
typedef ArcNode* PtrNode;
typedef struct VNode
{
    Vertex data;
    ArcNode *first;
}VNode;
typedef struct AGraph{
    int Nv; //存储节点数
    int Ne; //存储边数
    VNode *adjList;
}AGraph;
typedef AGraph* Graph;
int main(void){
    int i;
    Graph G;
    creat_graph(&G);
    int visit[G->Nv] ;
    for(i=0;i<G->Nv;i++)
    visit[i] = 0;
    for(i = 0;i<G->Nv;i++)
    if(visit[i]==0){
    printf("{ ");
    DFS(i,visit,G);
    printf("}\n");
    }
    for(i=0;i<G->Nv;i++)
    visit[i] = 0;
    for(i = 0;i<G->Nv;i++)
    if(visit[i]==0){
    printf("{ ");
    BFS(i,visit,G);
    printf("}\n");
    }
    return 0;
}

调用函数

void creat_graph(Graph *g){//初始化一个邻接矩阵
    int i,j,Nv,Ne;
    scanf("%d %d",&Nv,&Ne);
    (*g) = (Graph)malloc(sizeof(AGraph));
    (*g)->Nv = Nv;
    (*g)->Ne = Ne;
    (*g)->adjList = (VNode *)malloc(Nv*sizeof(VNode));
    for(i = 0; i < Nv; i++){
    (*g)->adjList[i].data=i;
    (*g)->adjList[i].first=NULL;
    }
    while(Ne--){//输入图中所有的边
        scanf("%d %d",&i,&j);
        PtrNode Vnew = (PtrNode)malloc(sizeof(ArcNode));
        Vnew->adjacent = j;
        Vnew->next = (*g)->adjList[i].first;
        (*g)->adjList[i].first = Vnew;
        Vnew = (PtrNode)malloc(sizeof(ArcNode));
        Vnew->adjacent = i;
        Vnew->next = (*g)->adjList[j].first;
        (*g)->adjList[j].first = Vnew;
    }
}
void DFS(Vertex x , Vertex *visit , Graph G){  //DFS输出连通集
     visit[x]=1;
     printf("%d ",x);
     PtrNode NowNode = G->adjList[x].first; //定义一个节点类型的指针指向头结点为X的头指针
     for (; NowNode!=NULL; NowNode=NowNode->next)//深度优先搜素
     {
        if(visit[NowNode->adjacent]==0)         
            DFS(NowNode->adjacent,visit,G);
     }
}
void BFS(Vertex x,Vertex *visit, Graph G){//BFS输出连通集
    Vertex queue[G->Nv];//队列构造
    int front =0, rear =0;
    queue[rear++] = x;
    visit[x] = 1;
    printf("%d ",x);
    while(front!=rear){
    int p=queue[front++];
    PtrNode NowNode = G->adjList[p].first;
    for (; NowNode!=NULL; NowNode=NowNode->next){
        if(visit[NowNode->adjacent]==0){
        printf("%d ",NowNode->adjacent);
        visit[NowNode->adjacent]=1;
        queue[rear++] = NowNode->adjacent;
        }
    }
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值