PTA_2019春_061_列出连通集

这篇博客介绍了如何在无向图中利用深度优先搜索(DFS)和广度优先搜索(BFS)算法列出所有的连通集。首先,给出一个包含N个顶点和E条边的图,然后按照顶点编号从小到大的顺序访问邻接点。文章提供了输入输出格式以及样例,说明了如何读取图的数据,并展示DFS和BFS两种方法的连通集结果输出方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

给定一个有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 }
/*列出连通集*/
/*递归实现DFS*/
/*注意题意:假设顶点从0到N?1编号。进行搜索时,假设我们总是从编号最小的顶点出发,按编号递增的顺序访问邻接点*/
/*这题一开始做不对的原因是我,写insert函数时,将V1插入V2时,直接赋值V1操作的代码,并且有些变量名忘记改了,所以导致插入操作进入死循环,引以为戒*/
#include<stdio.h>
#include<stdlib.h>
/*边的定义*/
typedef struct Enode* Edge;
struct Enode {
	int V1, V2;
};
/*邻接点的定义*/
typedef struct Adjvnode* prttoadjvnode;
struct Adjvnode {
	int adjv;
	prttoadjvnode next;
};
/*顶点定义*/
typedef struct Vnode {
	prttoadjvnode firstedge;
}adjlist[11];
/*图节点定义*/

struct Gnode {
	int Nv;/*顶点数*/
	int Ne;/*边数*/
	adjlist G; /*邻接表*/
};
typedef struct Gnode* Lgraph;

typedef struct Qnode* ptrtoQnode;
struct Qnode {
	int* Data;/*data数组,*/
	int front, rear;/*队列头尾指针*/
	int maxsize;/*容量*/
};
typedef ptrtoQnode Queue;

Lgraph creatgraph(int size);
void insertedge(Lgraph graph, Edge E);
Lgraph buildgraph(int N);
void DFS(Lgraph graph, int v, int* visited, void(*visit)(int));
void visit(int v);
void BFS(Lgraph graph, int v, int* visited);
int AddQ(Queue Q, int x);
Queue CreateQueue(int maxsize);
int isempty(Queue Q);
int DeleteQ(Queue Q);


int main() {
	int visited[11];
	for (int i = 0; i < 11; i++) {
		visited[i] = 0;/*初始化为0代表没有访问过*/
	}
	int N;
	scanf("%d", &N);
	Lgraph graph = buildgraph(N);
	/*以下测试图的输出
	  1.输出时出现死循环,用k来测试,是插入的问题,还是输出操作的问题
	  2.由k的测试,除了0以外,其他行没有输出结果,说明是插入的问题*/
/*
	int k = 0;
	for (int i = 0; i < N; i++) {
		printf("第%d ", i);
		prttoadjvnode temp = graph->G[i].firstedge;
		while (temp) {
			if (k == 12) break;
			printf("%d ", temp->adjv);
			temp = temp->next;
			k++;
		}
		printf("\n");
	}
*/
	/*DFS*/
	for (int i = 0; i < N; i++) {
		if (visited[i] == 0) {
			printf("{ ");
			DFS(graph, i, visited, visit);
			printf("}\n");
		}
	}
	/*BFS*/
	for (int i = 0; i < 11; i++) {
		visited[i] = 0;/*初始化为0代表没有访问过*/
	}
	for (int i = 0; i < N; i++) {
		if (visited[i] == 0) {
			printf("{ ");
			BFS(graph, i, visited);
			printf("}\n");
		}
	}

	
}
Lgraph creatgraph(int size) {
	Lgraph graph = (Lgraph)malloc(sizeof(struct Gnode));
	graph->Nv = size;
	graph->Ne = 0;
	for (int i = 0; i < size; i++) {
		graph->G[i].firstedge = NULL;
	}
	return graph;
}
void insertedge(Lgraph graph, Edge E) {/*插入时要保证从小到大的顺序*/
	/*v1,v2*/
	prttoadjvnode temp,front;
	prttoadjvnode newnode = (prttoadjvnode)malloc(sizeof(struct Adjvnode));
	newnode->adjv = E->V2;
	/*插入*/
	front = graph->G[E->V1].firstedge;
	if (!front || front->adjv > newnode->adjv)/*如果没有邻接点,或者第一个邻接点的数大于带插入的数*/
	{
		newnode->next = front;
		front = newnode;
		graph->G[E->V1].firstedge = front;
	}
	else/**/
	{
		while (front) {
			if (!front->next || front->next->adjv > newnode->adjv) {
				newnode->next = front->next;
				front->next = newnode;
				break;
			}
			front = front->next;
		}
	}
	

	prttoadjvnode newnode1 = (prttoadjvnode)malloc(sizeof(struct Adjvnode));
	newnode1->adjv = E->V1;
	temp = graph->G[E->V2].firstedge;
	if (!temp || temp->adjv > newnode1->adjv)/*如果没有邻接点,或者第一个邻接点的数大于带插入的数*/
	{
		newnode1->next = temp;
		temp = newnode1;
		graph->G[E->V2].firstedge = temp;
	}
	else/**/
	{
		while (temp) {
			if (!temp->next || temp->next->adjv > newnode1->adjv) {
				newnode1->next = temp->next;
				temp->next = newnode1;
				break;
			}
			temp = temp->next;
		}
	}

}
Lgraph buildgraph(int N) {
	Lgraph graph;
	
	graph = creatgraph(N);
	scanf("%d", &graph->Ne);
	if (graph->Ne != 0) {
		Edge E = (Edge)malloc(sizeof(struct Enode));
		for (int i = 0; i < graph->Ne; i++) {
			scanf("%d %d", &E->V1, &E->V2);
			insertedge(graph, E);
		}
	}
	return graph;
}
void DFS(Lgraph graph, int v,int *visited,void(* visit)(int)) {
	prttoadjvnode w;
	visit(v);
	visited[v] = 1;
	for (w = graph->G[v].firstedge; w; w = w->next) {/*遍历v的每一个邻接点*/
		if (!visited[w->adjv]) {
			DFS(graph, w->adjv, visited, visit);
		}
	}
}
void visit(int v) {
	printf("%d ", v);
}
void BFS(Lgraph graph,int v,int * visited) {
	Queue Q = CreateQueue(11);
	prttoadjvnode w;
	visited[v] = 1;
	printf("%d ", v);
	AddQ(Q,v);
	while (isempty(Q) == 0) {
		v = DeleteQ(Q);
		for (w = graph->G[v].firstedge; w; w = w->next) {/*每个邻接点*/
			if (visited[w->adjv] != 1) {
				printf("%d ", w->adjv);
				visited[w->adjv] = 1;
				AddQ(Q, w->adjv);
			}
		}
	}
}
Queue CreateQueue(int maxsize) {
	Queue Q = (Queue)malloc(sizeof(struct Qnode));
	Q->Data = (int*)malloc(maxsize * sizeof(int));
	Q->front = Q->rear = 0;
	Q->maxsize = maxsize;
	return Q;
}
int AddQ(Queue Q, int x) {
	Q->rear = (Q->rear + 1) % (Q->maxsize);
	Q->Data[Q->rear] = x;
	return 1;
}
int isempty(Queue Q) {
	return(Q->rear == Q->front);
}
int DeleteQ(Queue Q) {
	Q->front = (Q->front + 1) % Q->maxsize;
	return Q->Data[Q->front];
}
/*
10 6
6 7
6 1
2 6
4 1
2 4
3 5*/
/*
8 6
0 1
0 7
2 0
4 1
2 4
3 5
*/

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值