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