/*=====================================================================================
# COPYRIGHT NOTICE
# Copyright (c) 2016
#
# @Author :Zehao Wang
# @Email :zehaowang@163.com
# @from :https://pta.patest.cn/pta/test/1342/exam/4/question/22500
# @Last modified :2016-12-07
# @Description :06-图1 列出连通集
========================================================================================*/
#include<stdio.h>
#include<stdlib.h>
#define MaxVertexNum 10
int Visited[MaxVertexNum];
typedef struct {
int Vertices[MaxVertexNum];//顶点表
int Edges[MaxVertexNum][MaxVertexNum];//邻接矩阵,边表
int n, e;//顶点数和边数
}MGraph;
typedef struct QNode {
int Data[MaxVertexNum];
int front;
int rear;
}QNode,*Queue;
void Reset_Visited();
int Check_Visited(MGraph*G);
Queue Creat_Queue();
void Add_Queue(Queue Q,int item);
int Delete_Queue(Queue Q);
//int IsEmpty_Queue(Queue Q);
void Creat_MGraph(MGraph*G);
void DFS(MGraph*G, int i);
void BFS(MGraph*G);
int FirstAdjV(MGraph*G, int V);
int NextAdjV(MGraph*G, int V, int W);
Queue Creat_Queue()
{
Queue Q =(Queue) malloc(sizeof(struct QNode));
Q->front = -1;
Q->rear = -1;
return Q;
}
void Add_Queue(Queue Q,int item)
{
if ((Q->rear + 1) % MaxVertexNum == Q->front)
{
printf("队列满");
return;
}
else
{
Q->rear = (Q->rear + 1) % MaxVertexNum;
Q->Data[Q->rear] = item;
}
}
int Delete_Queue(Queue Q)
{
if (Q->rear == Q->front)
{
printf("队列空");
return -1;
}
else
{
Q->front = (Q->front + 1) % MaxVertexNum;
return Q->Data[Q->front];
}
}
int Check_Visited(MGraph *G)//看看是否还存在未被点亮的节点
{
for (int i = 0; i < G->n; i++)
{
if (!Visited[i])
return 1;
}
return 0;
}
void Reset_Visited()
{
for (int i = 0; i < MaxVertexNum; i++)
Visited[i] = 0;
}
void Creat_MGraph(MGraph *G)
{
scanf("%d %d", &(G->n), &(G->e));
for (int i = 0; i < G->n; i++)
{
for (int j = 0; j < G->n; j++)
{
G->Edges[i][j] = 0;
}
}
int a;
int b;
for (int k = 0; k < G->e; k++)
{
scanf("%d %d", &a, &b);
G->Edges[a][b] = 1;
G->Edges[b][a] = 1;
}
}
void DFS(MGraph *G, int i)
{
Visited[i] = 1;
printf("%d", i);
for (int j = 0; j < G->n; j++)
{
if (G->Edges[i][j] == 1 && Visited[j] == 0)
DFS(G, j);
}
}
void BFS(MGraph *G)
{
int V;
int W;
Queue Q = Creat_Queue();
for (int i = 0; i < G->n; i++)
{
if (!Visited[i])
{
printf("{");
Visited[i] = 1;
printf("%d", i);
Add_Queue(Q, i);
while (Q->front != Q->rear)//当队列不空
{
V = Delete_Queue(Q);
for (W = FirstAdjV(G, V); W < G->n; W = NextAdjV(G, V, W))
{
if (!Visited[W])
{
Visited[W] = 1;
printf("%d", W);
Add_Queue(Q, W);
}
else
break;
}
}
printf("}");
if (Check_Visited(G))
printf("\n");
}
}
}
int FirstAdjV(MGraph *G, int V)//和节点V相邻的第一个节点
{
for (int i = 0; i < G->n; i++)
{
if (G->Edges[V][i] == 1 && Visited[i] == 0)
return i;
}
}
int NextAdjV(MGraph *G, int V, int W)//和节点V相邻的第二个节点(第一个节点为W)
{
for (int i = W; i < G->n; i++)
{
if (G->Edges[V][i] == 1 && Visited[i] == 0)
return i;
}
}
int main(void)
{
MGraph *G;
G = (MGraph*)malloc(sizeof(MGraph));
for (int i = 0; i < MaxVertexNum; i++)
{
Visited[i] = 0;
}
Creat_MGraph(G);
for (int j = 0; j < G->n; j++)
{
if (Visited[j] == 0)
{
printf("{");
DFS(G, j);
printf("}\n");
}
}
Reset_Visited();
BFS(G);
return 0;
}
/*============================================================================================
注:这道题考察了图的一些基本操作,包括图的建立以及图的DFS和BFS的实现。图的建立又分两种情况,第
一种为图的邻接矩阵表示,适合稠密的图,本题用的就是这种表示方法。第二种为图的邻接表表示。
图的遍历有两种情况,第一种为深度优先遍历(DFS),它的遍历方式类似于树的先序遍历,用递归实现。第二
为广度优先遍历(BFS),它的遍历方式类似于树的层序遍历,用队列来实现。
==============================================================================================*/
06-图1 列出连通集
最新推荐文章于 2023-04-07 22:42:58 发布