06-图1 列出连通集(C)

  进入图的学习,发现难度直线上升,哈哈,全部满分

其实,在这个题里,邻接矩阵更好,但我们是来学习数据结构的,便突发奇想都来实现一遍。

以下是我的两种形式

给定一个有 n 个顶点和 m 条边的无向图,请用深度优先遍历(DFS)和广度优先遍历(BFS)分别列出其所有的连通集。假设顶点从 0 到 n−1 编号。进行搜索时,假设我们总是从编号最小的顶点出发,按编号递增的顺序访问邻接点。

输入格式:

输入第 1 行给出 2 个整数 n (0<n≤10) 和 m,分别是图的顶点数和边数。随后 m 行,每行给出一条边的两个端点。每行中的数字之间用 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 }

邻接矩阵,这个最易理解,也很轻松,满分

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>

#define MaxVertex 10
#define MaxSize 10
bool Visited_DFS[MaxVertex];
bool Visited_BFS[MaxVertex];

typedef struct ENode *Edge;
struct ENode{
	int V1, V2;
	int Weight;
};

typedef struct GNode *PtrToGNode;
typedef PtrToGNode MGraph;
struct GNode{
	int Nv;
	int Ne;
	bool G[MaxVertex][MaxVertex];
};

typedef struct Node *Queue;
struct Node{
	int data[MaxSize];
	int front;
	int rear;
};

MGraph Creat_Graph(int Nv, int Ne);
void Insert_Graph(MGraph M, Edge E);
MGraph Build_Graph();
void Visit(int V);
Queue Init_Q();
void Add_Q(Queue Q, int Vertex);
int Delete_Q(Queue Q);
bool IsFull_Q(Queue Q);
bool IsEmpty_Q(Queue Q);
void List_DFS(MGraph M);
void List_BFS(MGraph M);

int main()
{
	int Vertex;
	MGraph M;
	M = Build_Graph();
	List_DFS(M);
	List_BFS(M);
	return 0;
}
MGraph Build_Graph()
{
	MGraph MG;
	Edge E;
	int Nv, Ne, i, j;
	scanf("%d%d", &Nv, &Ne);
	MG = Creat_Graph(Nv, Ne);
	E = (Edge)malloc(sizeof(struct ENode));
	for(i = 0; i < (MG ->Ne); i++){
		scanf("%d%d",&(E ->V1), &(E ->V2));
		E ->Weight = 1;
		Insert_Graph(MG, E);
	}
	for(j = 0; j < (MG ->Ne); j++){
		Visited_DFS[j] = false;
		Visited_BFS[j] = false;
	}
	return MG;
}
MGraph Creat_Graph(int Nv, int Ne)
{
	MGraph M;
	M = (MGraph)malloc(sizeof(struct GNode));
	M ->Nv = Nv;
	M ->Ne = Ne;
	for(int i = 0; i < Nv; i++){
		for(int j = 0; j < Nv; j++){
			M ->G[i][j] = false;
		}
	}
	return M;
}
void Insert_Graph(MGraph M, Edge E)
{
	M ->G[E ->V1][E ->V2] = true;
	M ->G[E ->V2][E ->V1] = true;
}
void Visit(int V)
{
	printf(" %d", V);
}

void DFS(MGraph M, int Vertex, void(*Visit)(int))
{
	int T;
	Visited_DFS[Vertex] = true;
	Visit(Vertex);
	for(int i = 0; i < M ->Nv; i++){
		if(!Visited_DFS[i] && M ->G[Vertex][i] == true){
			DFS(M, i, Visit);
		}
	}
}
void BFS(MGraph M, int Vertex, void(*Visit)(int))
{
	Queue Q;
	int T, i;
	Q = Init_Q();
	Visit(Vertex);
	Visited_BFS[Vertex] = true;
	Add_Q(Q, Vertex);
	while(!IsEmpty_Q(Q)){
		T = Delete_Q(Q);
		for(i = 0; i < M ->Nv; i++){
			if(!Visited_BFS[i] && M ->G[T][i]){
				Visit(i);
				Visited_BFS[i] = true;
				Add_Q(Q, i);
			}
		}
	}
}
Queue Init_Q()
{
	Queue Q;
	Q = (Queue)malloc(sizeof(struct Node));
	Q ->front = 0;
	Q ->rear = 0;
	return Q;
}
void Add_Q(Queue Q, int Vertex)
{
	if(IsFull_Q(Q)){
		printf("队列满!");
		return ;
	}
	Q ->rear = (Q ->rear + 1) % MaxSize;
	Q ->data[Q ->rear] = Vertex;
}
int Delete_Q(Queue Q)
{
	if(IsEmpty_Q(Q)){
		printf("队列空!");
        return -1;
	}else{
		Q ->front = (Q ->front + 1) % MaxSize;
		return Q ->data[Q ->front];
	}
}
bool IsFull_Q(Queue Q)
{
	return (Q ->rear + 1) % MaxSize == Q ->front;
}
bool IsEmpty_Q(Queue Q)
{
	return Q ->front == Q ->rear;
}
void List_DFS(MGraph M)
{
	for(int V=0; V < M->Nv;V++) {
		if(!Visited_DFS[V]) {
			printf("{");
			DFS(M, V, Visit);
			printf(" }");
			printf("\n");
		}
	}
}
void List_BFS(MGraph M)
{
	for(int V=0; V < M->Nv;V++) {
		if(!Visited_BFS[V]) {
			printf("{");
			BFS(M, V, Visit);
			printf(" }");
			printf("\n");
		}
	}
}

这个是邻接表,完全动态分配,有点难度,249行,

其实怪耽误我时间呢,主要是队列处理,忘记了删除仅有一个节点的队列不需要释放空间,哎!排查好久。

 这个是我认为的,比较有创新的地方,其实最开始想单拿,图M,作为参数,但发现会陷入无限循环,让我头疼死了,

后来晚上吃饭想明白,指哪里改哪里,或许有奇效,结果是对,哈哈,同时也证明了,逻辑没问题。

void Sort_Graph(PtrToAdjVNode *Link)
{
	PtrToAdjVNode head, Temp, Key;
	head = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));
	head ->Next = (*Link) ->Next;
	Temp = head;
	Key = (*Link);
	Key ->Next = NULL;
	if(!(head ->Next)){
		return ;
	}
	while(head ->Next){
		if(Key ->V > (head ->Next ->V)){
			head = head ->Next;
		}else{
			Key ->Next = head ->Next;
			head ->Next = Key;
			break;
		}
	}
	if(!(head ->Next)){
		head ->Next = Key;
	}
	(*Link) = Temp ->Next;
	return ;
}

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>

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

typedef struct AdjVNode *PtrToAdjVNode;
struct AdjVNode{
	int V;
	int Weight;
	PtrToAdjVNode Next;
};

typedef struct VNode **AdjList;
struct VNode{
	PtrToAdjVNode FirstEdge;
};

typedef struct GNode *PtrToGNode;
typedef PtrToGNode LGraph;
struct GNode{
	int Nv;
	int Ne;
	AdjList G;
};

typedef struct Node *QNode;
struct Node{
	int Data;
	QNode Next;
};
typedef struct QNode *Queue;
struct QNode{
	QNode front;
	QNode rear;
};

LGraph Build_Graph();
LGraph Init_Graph(int Nv, int Ne);
void Insert_Graph(LGraph M, Edge E);
void Sort_Graph(PtrToAdjVNode *Link);
void Visit(int Vertex);
void DFS(LGraph M, int Vertex, bool *Visited, void(*Visit)(int));
void BFS(LGraph M, int Vertex, bool *Visited, void(*Visit)(int));
void List_DFS(LGraph M);
void List_BFS(LGraph M);
Queue Init_Q();
void Add_Q(Queue Q, int Vertex);
int Delete_Q(Queue Q);
bool IsEmpty_Q(Queue Q);

int main()
{
	LGraph M;
	M = Build_Graph();
	List_DFS(M);
	List_BFS(M);
	return 0;
}
LGraph Build_Graph()
{
	LGraph M;
	Edge E;
	int Nv, Ne;
	int i;
	scanf("%d%d", &Nv, &Ne);
	M = Init_Graph(Nv, Ne);
	E = (Edge)malloc(sizeof(struct ENode));
	if(M ->Nv){
		for(i = 0; i < (M ->Ne); i++){
			scanf("%d%d", &E ->V1, &E ->V2);
			Insert_Graph(M, E);
		}
	}
	return M;
}
LGraph Init_Graph(int Nv, int Ne)
{
	LGraph M;
	M = (LGraph)malloc(sizeof(struct GNode));
	M ->Nv = Nv;
	M ->Ne = Ne;
	M ->G = (AdjList)malloc(sizeof(struct VNode) * Nv);
	for(int i = 0; i < Nv; i++){
		M ->G[i] = (struct VNode*)malloc(sizeof(struct VNode));
		M ->G[i] ->FirstEdge = NULL;
	}
	return M;
}
void Insert_Graph(LGraph M, Edge E)
{
	// 无向图
	PtrToAdjVNode NewNode1, NewNode2;
	NewNode1 = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));
	NewNode1 ->V = E ->V2;
	NewNode1 ->Weight = E ->Weight;
	NewNode1 ->Next = M ->G[E ->V1] ->FirstEdge;
	M ->G[E ->V1] ->FirstEdge = NewNode1;
	Sort_Graph(&(M ->G[E ->V1] ->FirstEdge));
	
	NewNode2 = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));
	NewNode2 ->V = E ->V1;
	NewNode2 ->Weight = E ->Weight;
	NewNode2 ->Next = M ->G[E ->V2] ->FirstEdge;
	M ->G[E ->V2] ->FirstEdge = NewNode2;
	Sort_Graph(&(M ->G[E ->V2] ->FirstEdge));
}
void Sort_Graph(PtrToAdjVNode *Link)
{
	PtrToAdjVNode head, Temp, Key;
	head = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));
	head ->Next = (*Link) ->Next;
	Temp = head;
	Key = (*Link);
	Key ->Next = NULL;
	if(!(head ->Next)){
		return ;
	}
	while(head ->Next){
		if(Key ->V > (head ->Next ->V)){
			head = head ->Next;
		}else{
			Key ->Next = head ->Next;
			head ->Next = Key;
			break;
		}
	}
	if(!(head ->Next)){
		head ->Next = Key;
	}
	(*Link) = Temp ->Next;
	return ;
}
void Visit(int Vertex)
{
	printf(" %d", Vertex);
}
void DFS(LGraph M, int Vertex, bool *Visited, void(*Visit)(int))
{
	PtrToAdjVNode W;
	Visit(Vertex);
	Visited[Vertex] = true;
	for(W = M ->G[Vertex] ->FirstEdge; W; W = W ->Next){
		if(!Visited[W ->V]){
			DFS(M, W ->V, Visited, Visit);
		}
	}
}
void BFS(LGraph M, int Vertex,  bool *Visited, void(*Visit)(int))
{
	Queue Q;
	PtrToAdjVNode G;
	int V;
	Q = Init_Q();
	Visited[Vertex] = true;
	Visit(Vertex);
	Add_Q(Q, Vertex);
	while(!IsEmpty_Q(Q)){
		V = Delete_Q(Q);
		for(G = M ->G[V] ->FirstEdge; G; G = G ->Next){
			if(Visited[G ->V] == false){
				Visit(G ->V);
				Visited[G ->V] = true;
				Add_Q(Q, G ->V);
			}
		}
	}
}
Queue Init_Q()
{
	Queue Q;
	Q = (Queue)malloc(sizeof(struct QNode));
	Q ->front = NULL;
	Q ->rear = Q ->front;
	return Q;
}
void Add_Q(Queue Q, int Vertex)
{
	QNode Node;
	Node = (QNode)malloc(sizeof(struct Node));
	Node ->Data = Vertex;
	Node ->Next = NULL;
	if(!(Q ->front) && !(Q ->rear)){
		Q ->front = Node;
		Q ->rear = Node;
	}else{
		Q ->rear ->Next = Node;
		Q ->rear = Node;
	}
}
int Delete_Q(Queue Q)
{
	if(IsEmpty_Q(Q)){
		printf("很遗憾,是空的!\n");
		return -1;
	}else{
		QNode Temp;
		int Vertex;
		if(Q ->front == Q ->rear){
			Vertex = Q ->front ->Data;
			Q ->front = NULL;
			Q ->rear = NULL;
		}else{
			Temp = Q ->front;
			Q ->front = Q ->front ->Next;
			Vertex = Temp ->Data;
			free(Temp);
		}
		return Vertex;
	}
}
bool IsEmpty_Q(Queue Q)
{
	return Q ->front == NULL;
}
void List_DFS(LGraph M)
{
	bool *Visited;
	Visited = (bool*)calloc(M ->Nv, sizeof(bool));
	for(int V=0; V < M->Nv;V++) {
		if(!Visited[V]) {
			printf("{");
			DFS(M, V, Visited, Visit);
			printf(" }");
			printf("\n");
		}
	}
	free(Visited);
}
void List_BFS(LGraph M)
{
	bool *Visited;
	Visited = (bool*)calloc(M ->Nv, sizeof(bool));
	for(int V=0; V < M->Nv;V++) {
		if(!Visited[V]) {
			printf("{");
			BFS(M, V, Visited, Visit);
			printf(" }");
			printf("\n");
		}
	}
	free(Visited);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值