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;
}
}