(c语言详解)06-图1 列出连通集(详细解释)

本博文取材于浙江大学《数据结构》。题目来源于PTA。
给定一个有N个顶点和E条边的无向图,请用DFS和BFS分别列出其所有的连通集。假设顶点从0到N−1编号。进行搜索时,假设我们总是从编号最小的顶点出发,按编号递增的顺序访问邻接点。

输入格式:
输入第1行给出2个整数N(0

输出格式:
按照"{ v1,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 }

分析三板斧

给题相面

这道题目考察的是无向图也就是权值可以默认为1,也可以不设的。因为是图(上)第一题,所以大家不要慌张,我们再次分析第一行给出图的顶点和图的边,顶点和边确定好了,下面就只需要插入边就行了,而插入边它是两个值
例如:

 0 6

说明我们要为0 结点和6结点设定联系,可以实现。题目中有明确DFS和BFS。所以这是一道经典的图的遍历找出联通集的一道题目。

输入、处理、输出

考虑解决一道题目所要研究的算法,必然是输入、处理、输出。输入就是让BuildGraph这个函数来实现,主要存结点就行了,数据不需要的。然后在深搜和广搜实现中,牢牢扣住题目中的要求,在ListComponents函数的时候,把格式调整一下,一切最核心的代码都在课上讲过的,学会拼接并且整理。深搜和广搜重要的是思想,因为思想掌握了可以解决很多题目。如果一味地生搬硬套结果会失去很多。

完整代码如下:

#include
#include
#define MaxVertexNum 10
#define MaxSize 10

typedef int WeightType;
typedef int Vertex;
typedef int ElementType;
int Visited_DFS[MaxVertexNum];
int Visited_BFS[MaxVertexNum];

struct GNode {
	int Nv;
	int Ne;
	WeightType G[MaxVertexNum][MaxVertexNum];
};
typedef struct GNode* PtrToGNode;
typedef PtrToGNode MGraph;

struct ENode {
	Vertex V1,V2;
	WeightType Weight;
	
};
typedef struct ENode* PtrToENode;
typedef PtrToENode Edge;

struct Node {
	ElementType Data;
	struct Node* Next;
};

struct QNode {
	struct Node* front;
	struct Node* rear;
};
typedef struct QNode* Queue;

MGraph CreateGraph(int VertexNum);
void InsertEdge(MGraph,Edge E);
MGraph BuildGraph();
void Visit(Vertex V);
void DFS(MGraph Graph,Vertex V,void (*Visit)(Vertex));
void BFS(MGraph Graph,Vertex S,void (*Visit)(Vertex));
void ListComponents_DFS(MGraph Graph);
void ListComponents_BFS(MGraph Graph);
Queue CreateQueue();
void AddQ(Queue Q,Vertex S);
ElementType DeleteQ(Queue Q);

int main()
{
	Vertex V;

	MGraph Graph = BuildGraph();
	ListComponents_DFS(Graph);
	ListComponents_BFS(Graph);
	return 0;
}

//MGraph初始化
MGraph CreateGraph(int VertexNum) {
	Vertex V,W;
	MGraph Graph;
	Graph = (MGraph)malloc(sizeof(struct GNode));
	Graph->Nv = VertexNum;
	Graph->Ne = 0;
	
	for(V=0;V<Graph->Nv;V++)
		for(W=0;W<Graph->Nv;W++)
			Graph->G[V][W]=0;
		
	return Graph;
}
//MGraph插入边
void InsertEdge(MGraph Graph,Edge E) {
	Graph->G[E->V1][E->V2] = E->Weight;
	Graph->G[E->V2][E->V1] = E->Weight;
	
}
//完整建立MGraph
MGraph BuildGraph() {
	MGraph Graph;
	Edge E;
	Vertex V;
	int Nv,i;
	scanf("%d",&Nv);
	Graph = CreateGraph(Nv);
	scanf("%d",&(Graph->Ne));
	if(Graph->Ne != 0) {
		E = (Edge)malloc(sizeof(struct ENode));
		for(i=0;i<Graph->Ne;i++) {
			scanf("%d %d",&E->V1,&E->V2);
			E->Weight = 1;
			InsertEdge(Graph,E);
			
		}
			
	}
	for(V=0;V<Graph->Nv;V++) {
		Visited_BFS[V] = 0;
		Visited_DFS[V] = 0;
	}
	return Graph;
}
//访问结点
void Visit(Vertex V) {
	printf(" %d",V);
}
//联通集DFS
void ListComponents_DFS(MGraph Graph) {
	
	for(Vertex V=0;V<Graph->Nv;V++) {
		if(!Visited_DFS[V]) {
			printf("{");
			DFS(Graph,V,Visit);
			printf(" }");
			printf("\n");
		}
	}
}
//联通集BFS
void ListComponents_BFS(MGraph Graph) {
	
	for(Vertex V=0;V<Graph->Nv;V++) {
		if(!Visited_BFS[V]) {
			printf("{");
			BFS(Graph,V,Visit);
			printf(" }");
			printf("\n");
		}
	}
}
//DFS搜索
void DFS(MGraph Graph, Vertex V, void (*Visit)(Vertex )) {
	Vertex W;
	Visited_DFS[V] = 1;
	Visit(V);
	for(W=0;W<Graph->Nv;W++)
	if(Graph->G[V][W] == 1 && !Visited_DFS[W])
		{
			DFS(Graph, W, Visit);
			
		}


}

void BFS(MGraph Graph,Vertex S,void (*Visit)(Vertex)) {
	Queue Q;
	Vertex V,W;
	Q = CreateQueue();
	Visit(S);
	Visited_BFS[S] = 1;
	AddQ(Q,S);
	
	while(Q->front != NULL ) {
		V = DeleteQ(Q);
		for(W = 0;W<Graph->Nv;W++) {
			if(Graph->G[V][W] == 1 && !Visited_BFS[W])
			{
				Visit(W);
				Visited_BFS[W] = 1;
				AddQ(Q,W);
			
			}
		}
	}
	
}
//J建造队列,假设为空
Queue CreateQueue(){
    Queue Q;
    Q=(Queue)malloc(sizeof(struct QNode));
    Q->front=Q->rear=NULL;
    return Q;
}
/*进队列*/
void AddQ(Queue Q,Vertex S){
    struct Node *temp;
    temp=(struct Node*)malloc(sizeof(struct Node));
    temp->Data=S;
    temp->Next=NULL;
    if(Q->front==NULL){
        Q->front=temp;
        Q->rear=temp;
    }
    else{
        Q->rear->Next=temp;
        Q->rear=temp;
    }
    // return Q;
}
/*出队列*/
ElementType DeleteQ(Queue Q){
    struct Node *FrontCell;
    ElementType FrontElem;
    if(Q->front==NULL){
        return -1;
    }
    FrontCell=Q->front;
    if(Q->front==Q->rear)
        Q->front=Q->rear=NULL;
    else Q->front=Q->front->Next;
    FrontElem=FrontCell->Data;
    free(FrontCell);
    return FrontElem;
}

你可能感兴趣的:(浙大pta)