# 06-图1 列出连通集 (25 分)

06-图1 列出连通集 (25 分)

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


#include<stdio.h>
#include<string.h>
#include <stdlib.h>
#include<stdbool.h>
#define max 10
#define infinity   65535
typedef struct enode *polynode; 
struct enode 
{
    int v1,v2;
};
typedef polynode edge;
typedef struct gnode *polynomial;
struct gnode
{
    int nv,ev;
    int g[max][max];
    int data[max];
};
typedef polynomial mgraph;
typedef struct Node *PtrToNode;
struct Node { /* 队列中的结点 */
    int datas;
    PtrToNode next;
};
typedef PtrToNode Position;

struct QNode {
    Position front, rear;  /* 队列的头、尾指针 */   
};
typedef struct QNode *Queue;
void Visit(int w);
mgraph buildgraph(int nv,int ev);
mgraph creategraph (int nv);
bool IsEmpty( Queue Q );
bool IsEdge( mgraph graph, int V, int W );
void listdfs(mgraph graph);
void insert(mgraph graph,edge e);
Queue CreateQueue(int t );
void BFS ( mgraph graph, int s ,void (*Visit)(int));
void AddQ(Queue Q , int  S);
int DeleteQ( Queue Q );
void dfs(mgraph graph ,int s,void (*Visit)(int));
void listbfs(mgraph graph);
extern int Visited[max] = {0};
extern int Visiteds[max] = {0};
int main(void)
{
    int nv,ev;
    scanf("%d %d",&nv,&ev);
    mgraph graph;
	graph = buildgraph(nv,ev);
    listdfs(graph);
    listbfs(graph);
	return 0;
}
mgraph buildgraph(int nv,int ev)
{
    mgraph graph;
    edge e;
    int i;

    graph = creategraph(nv);
    graph->ev = ev;
    if(graph->ev != 0)
    {
    e = (edge)malloc(sizeof(struct enode));
    for(i = 0;i < graph->ev;i++)
    {
        scanf("%d %d",&e->v1,&e->v2);
   
        insert(graph ,e);
    }
    }
	return graph;
}
mgraph creategraph (int nv)
{
    mgraph graph;
    int i,j;
    graph = (mgraph)malloc(sizeof(struct gnode));
    graph->nv = nv;
    graph->ev = 0;
    for(i = 0;i < graph->nv; i++)
        for(j = 0;j <graph->nv;j++)
            graph->g[i][j] = infinity;
    return graph;
}

void insert(mgraph graph,edge e)
{
    graph->g[e->v1][e->v2] = 1;
    graph->g[e->v2][e->v1] = 1;
}
/*void dfs(mgraph graph)
{
    int v = 0;
    visited[v] = true;
    for(v 的每个灵界点w)
        if(!visited[w])
            dfs(w);
}
void listcomponents(graph g)
{
    for(each v in g)
        if(!visited[v])
            dfs(v)
}*/
void dfs(mgraph graph ,int s,void (*Visit)(int))
{
    int w;

    Visiteds[s] = true;
    Visit(s);
	for(w = 0; w <  graph->nv;w++)
    {
        if(Visiteds[w] != true && graph->g[s][w] == 1)
            dfs(graph,w,Visit);
    }
        
         
    
}
void listdfs(mgraph graph)
{
   int i;
    for(i = 0; i < graph->nv;i++)
    {
      
        if( !Visiteds[i] )
        {
            printf("{");
            dfs(graph,i,Visit);
            printf(" }\n");
        }
     }
}

void BFS ( mgraph graph, int s ,void (*Visit)(int))
{   /* 以S为出发点对邻接矩阵存储的图Graph进行BFS搜索 */
    Queue Q;    
    int V,W;
    Q = CreateQueue( max ); /* 创建空队列, MaxSize为外部定义的常数 */
    /* 访问顶点S:此处可根据具体访问需要改写 */
    Visit(s);
    Visited[s] = true; /* 标记S已访问 */
    AddQ(Q, s); /* S入队列 */
    
    while ( !IsEmpty(Q) ) {
        V = DeleteQ(Q);  /* 弹出V */
         
        for( W=0; W < graph->nv; W++ ) /* 对图中的每个顶点W */
            /* 若W是V的邻接点并且未访问过 */
            if ( !Visited[W] && IsEdge(graph, V, W) ) {
                /* 访问顶点W */
                 Visit(W);
                Visited[W] = true; /* 标记W已访问 */
                AddQ(Q, W); /* W入队列 */
            }

			
    } /* while结束*/
}
bool IsEdge( mgraph graph, int V, int W )
{
    return graph->g[V][W] < infinity ? true : false;
}

Queue CreateQueue(int t)
{
    Queue s;
    
	s = (Queue)malloc(sizeof(struct QNode));
	s->front =  s->rear = NULL;
	return s;
}
void Visit( int V )
{
    printf(" %d", V); 
}

void listbfs(mgraph graph){
    int i;
    for(i = 0; i < graph->nv; i++){
        if(!Visited[i]){//节点i未被访问过
            printf("{");
            BFS(graph, i, Visit);
            printf(" }");
            printf("\n");
        }
    }
}

void AddQ(Queue q , int  s)
{
    Position m;
    m = (Position)malloc(sizeof(struct Node));
    m->datas = s;
	m->next = NULL;
    if(q->front == NULL)
		q->front = q->rear = m;
	else
	{
		q->rear->next = m;
		q->rear = m;
	}
}
bool IsEmpty( Queue Q )
{
    return ( Q->front == NULL);
}
int DeleteQ( Queue Q )
{
    Position FrontCell; 
    int FrontElem;
    
    if  ( IsEmpty(Q) ) {
        return -1;
    }
    else {
        FrontCell = Q->front;
        if ( Q->front == Q->rear ) /* 若队列只有一个元素 */
            Q->front = Q->rear = NULL; /* 删除后队列置为空 */
        else                     
            Q->front = Q->front->next;
        FrontElem = FrontCell->datas;

        free( FrontCell );  /* 释放被删除结点空间  */
        return  FrontElem;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值