列出连通集

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

输入格式:

输入第1行给出2个整数N(0

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXVERTEXNUM 100//最大顶点数

typedef int vertex;
typedef struct VNode* PtrToVertex;
struct VNode{//图的定义
    int Nv;//顶点数
    int Ne;//边数
    int G[MAXVERTEXNUM][MAXVERTEXNUM];//以邻接矩阵存储任意两个顶点之间边的情况(无边、有边、边的权重等)
};
typedef PtrToVertex MGraph;

//队列的定义,用于广度优先遍历
typedef struct QU{
    int H[MAXVERTEXNUM];
    int front;//数组中首元素的下标
    int rear;//数组中最后 一个元素的下标
}Queue;

int visit[MAXVERTEXNUM];//用来标记该顶点已被访问过

MGraph CreateGraph(int N);
MGraph BuildGraph(void);
void DFS(MGraph Graph, int v);
void Print(MGraph Graph);
void BFS(MGraph Graph, int s);
int IsEmpty(Queue* Q);
int DeleteQ(Queue* Q);

int main()
{

    MGraph Graph;
    Graph = BuildGraph();
    memset(visit, 0, sizeof(visit));//也可以不要,全局变量在编译时如未定义则初始化为0
    Print(Graph);
    return 0;
}

//创建一个图并初始化
MGraph CreateGraph(int N)
{
    vertex v, w;//表示二位矩阵的行号与列号
    MGraph Graph = (MGraph)malloc(sizeof(struct VNode));
    Graph->Nv = N;
    Graph->Ne = 0;
    for(v = 0; v < Graph->Nv; v++){
        for(w = 0; w < Graph->Nv; w++){
            Graph->G[v][w] = 0;
        }
    }
    return Graph;
}

//主要要做插入边
MGraph BuildGraph(void)
{
    int N, result, i;
    MGraph Graph;
    vertex v1, v2;

    QQ: ;
    result = scanf("%d", &N);
    if(result != 1 || N <= 0 || N > 10){
        printf("输入有误!\n请重新输入\n");
        goto QQ;
    }
    Graph = CreateGraph(N);

    scanf("%d", &(Graph->Ne));
    if(Graph->Ne != 0){
        for(i = 0; i < Graph->Ne; i++){
            scanf("%d%d", &v1, &v2);
            Graph->G[v1][v2] = 1;
            Graph->G[v2][v1] = 1;
        }
    }
    return Graph;
}

//深度优先搜索
void DFS(MGraph Graph, int v)
{
    /*类似树中的先序遍历,先访问该未被访问的顶点,然后一个一个找它的未被访问的邻接点访问,
      当找到邻接点,再重复上述操作,递推再返回
    */
    int i;
    printf(" %d", v);
    visit[v] = 1;
    for(i = 0; i < Graph->Nv; i++){
        if(!visit[i] && Graph->G[v][i] == 1){
            DFS(Graph, i);
        }
    }
}

void Print(MGraph Graph)
{
    //深度优先搜索
    int i;
    for(i = 0; i < Graph->Nv; i++){
        if(visit[i] == 0){
            printf("{");
            DFS(Graph, i);//它完后,一个连通集已全部遍历过,并且其中每个顶点都已经标记访问过
            printf(" }\n");//下一个进来的必定是另一个连通集中某一个元素,作为入口
        }
    }
    memset(visit, 0, sizeof(visit));//将visit[]数组清零

    //广度优先搜索
    for(i = 0; i < Graph->Nv; i++){
        if(visit[i] == 0){
            printf("{");
            BFS(Graph, i);
            printf(" }\n");
        }
    }
}


//以s为出发点对邻接矩阵存储的图Graph进行BFS搜索
void BFS(MGraph Graph, int s)
{
    Queue Q;//该队列我用了数组,有时会用链表
    vertex v, w;

    Q.front = 0; Q.rear = 0;

    /*同样类似层序遍历,在第一个结点入队之前先访问,然后结点入队,结点出队,分别找到它的
      邻结点访问,再入队,只要队列不空,一直进行出队、入队
    */

    printf(" %d", s);
    visit[s] = 1;
    Q.H[(Q.rear)++] = s;

    while(!IsEmpty(&Q)){
        v = DeleteQ(&Q);
        for(w = 0; w < Graph->Nv; w++){
            if(!visit[w] && Graph->G[v][w] == 1){
                printf(" %d", w);
                visit[w] = 1;
                Q.H[(Q.rear)++] = w;
            }
        }
    }
}

int IsEmpty(Queue* Q)
{
    if(Q->front == Q->rear){
        return 1;
    }else{
        return 0;
    }
}

int DeleteQ(Queue* Q)
{
    return (Q->H[(Q->front)++]);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值