Liste des ensembles connectés (25 points) Implémentation C ++

/ * Après avoir lu les codes d'autres grands dieux à ce sujet, je les ai écrits moi-même.Certains endroits sont un peu difficiles pour moi, débutant avec la structure de données des débutants. Une fois la modification terminée, si vous ne comprenez pas, vous pouvez aller au MOOC pour voir le cours en ligne pour comprendre haha. * /

Étant donné un graphe non orienté avec N sommets et arêtes E, utilisez DFS et BFS pour répertorier tous ses ensembles connectés. Supposons que les sommets sont numérotés de 0 à N − 1. Lorsque vous effectuez une recherche, il est supposé que nous partons toujours du sommet avec le nombre le plus bas et visitons les points adjacents dans l'ordre croissant.

Format d'entrée:
entrez la première ligne pour donner deux entiers N (0 <N≤10) et E, qui sont le nombre de sommets et d'arêtes du graphique. Ensuite, dans la ligne E, chaque ligne donne deux extrémités d'une arête. Les numéros de chaque ligne sont séparés par 1 espace.

Format de sortie:
Selon le format "{v1 vk}", chaque ligne sort un ensemble connecté. Le résultat DFS est affiché en premier, suivi du résultat BFS.
Exemple d'entrée:

  1. 8 6
  2. 0 7
  3. 0 1
  4. 2 0
  5. 4 1
  6. 2 4
  7. 3 5 »

Exemple de sortie:

  1. {0 1 4 2 7}
  2. {3 5}
  3. {6}
  4. {0 1 2 7 4}
  5. {3 5}
  6. {6}

Adresse du titre d'origine

/*	参考资料
1 中国大学MOOC 浙大 数据结构 第六讲 图(上) 
2 DFS
	作者:拉风小宇 
	来源:CSDN 
	原文:https://blog.csdn.net/lafengxiaoyu/article/details/53493080 
	版权声明:本文为博主原创文章,转载请附上博文链接! 
3 BFS
	作者:拉风小宇 
	来源:CSDN 
	原文:https://blog.csdn.net/lafengxiaoyu/article/details/53502873 
	版权声明:本文为博主原创文章,转载请附上博文链接!*/

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

/* 图的邻接矩阵表示法 */
 
#define MaxVertexNum 100    /* 最大顶点数设为100 */
#define INFINITY 65535        /* ∞设为双字节无符号整数的最大值65535*/
int Visited[MaxVertexNum];/* 标记V已访问 */
#define ERROR 0  
typedef int Vertex;         /* 用顶点下标表示顶点,为整型 */
typedef int WeightType;        /* 边的权值设为整型 */
//typedef char DataType;        /* 顶点存储的数据类型设为字符型 */
typedef int ElementType;
typedef int Position;

/* 边的定义 */
typedef struct ENode *PtrToENode;
struct ENode{
    Vertex V1, V2;      /* 有向边<V1, V2> */
    WeightType Weight;  /* 权重 */
};
typedef PtrToENode Edge;

/* 图结点的定义 */
typedef struct GNode *PtrToGNode;
struct GNode{
    int Nv;  /* 顶点数 */
    int Ne;  /* 边数   */
    WeightType G[MaxVertexNum][MaxVertexNum]; /* 邻接矩阵 */
    //DataType Data[MaxVertexNum];      /* 存顶点的数据 */
    /* 注意:很多情况下,顶点无数据,此时Data[]可以不用出现 */
};
typedef PtrToGNode MGraph; /* 以邻接矩阵存储的图类型 */



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


MGraph CreateGraph( int VertexNum );
void InsertEdge( MGraph Graph, Edge E );
MGraph BuildGraph();

void Visit(Vertex V);
int IsEmpty(Queue Q);
Queue CreateQueue();
int DeleteQ(Queue PtrQ);
void InsertQ(int item, Queue PtrQ);
bool IsEdge(MGraph Graph, Vertex V, Vertex W);

void BFS(MGraph Graph, Vertex S, void(*Visit)(Vertex));
void ListComponentsBFS(MGraph Graph);

void DFS(MGraph Graph, Vertex V, void(*Visit)(Vertex));
void ListComponentsDFS(MGraph Graph);

int main()
{
	MGraph Graph;
	Graph = BuildGraph();
	
	for (int i = 0; i < MaxVertexNum; i++) {
		Visited[i] = false; 
	}
	//printf("下面执行DFS\n");
	ListComponentsDFS( Graph );
	
	/* 	在执行完 ListComponentsDFS( Graph ); 后,需重置 Visited[i] 
		否则 ListComponentsBFS( Graph ); 执行不了。。。 */
	for (int i = 0; i < MaxVertexNum; i++) {
		Visited[i] = false; 
	} 
	//printf("下面执行BFS\n");
	ListComponentsBFS( Graph );
	
	return 0;
}

MGraph CreateGraph( int VertexNum )
{ /* 初始化一个有VertexNum个顶点但没有边的图 */
    Vertex V, W;
    MGraph Graph;
     
    Graph = (MGraph)malloc(sizeof(struct GNode)); /* 建立图 */
    Graph->Nv = VertexNum;
    Graph->Ne = 0;
    /* 初始化邻接矩阵 */
    /* 注意:这里默认顶点编号从0开始,到(Graph->Nv - 1) */
    for (V=0; V<Graph->Nv; V++)
        for (W=0; W<Graph->Nv; W++)  
            Graph->G[V][W] = INFINITY;
    //printf("图初始化完成\n");         
    return Graph; 
}
        
void InsertEdge( MGraph Graph, Edge E )
{
     /* 插入边 <V1, V2> */
     Graph->G[E->V1][E->V2] = E->Weight;    
     /* 若是无向图,还要插入边<V2, V1> */
     Graph->G[E->V2][E->V1] = E->Weight;
}
 
MGraph BuildGraph()
{
    MGraph Graph;
    Edge E;
    Vertex V;
    int Nv, Ne, i;
    //printf("输入顶点数\n"); 
    scanf("%d %d", &Nv, &Ne);   /* 读入顶点个数 */
    Graph = CreateGraph(Nv); /* 初始化有Nv个顶点但没有边的图 */
	Graph->Ne = Ne; 
    //printf("输入边数\n");
    //scanf("%d", &(Graph->Ne));   /* 读入边数 */
    if ( Graph->Ne != 0 ) { /* 如果有边 */ 
        E = (Edge)malloc(sizeof(struct ENode)); /* 建立边结点 */ 
        /* 读入边,格式为"起点 终点 权重",插入邻接矩阵 */
        for (i=0; i<Graph->Ne; i++) {
        	//printf("输入一条边的两个端点\n");
            scanf("%d %d", &E->V1, &E->V2); 
            E->Weight = 1;
            /* 注意:如果权重不是整型,Weight的读入格式要改 */
            InsertEdge( Graph, E );
        }
    } 
 
    /* 如果顶点有数据的话,读入数据 */
    //for (V=0; V<Graph->Nv; V++) 
    //    scanf(" %c", &(Graph->Data[V]));
	//printf("图建立完成\n");
    return Graph;
}


void Visit(Vertex V)
{
	printf("正在访问顶点%d\n", V + 1);
} 
 
 
int IsEmpty(Queue Q) {
	return(Q->front == NULL);
};
 
Queue CreateQueue() {
	Queue PtrQ;
	PtrQ = (Queue)malloc(sizeof(struct QNode));
	struct Node *rear;
	struct Node *front;
	rear = (Node*)malloc(sizeof(struct Node));
	rear = NULL;
	front = (Node*)malloc(sizeof(struct Node));
	front = NULL;
	PtrQ->front = front;
	PtrQ->rear = rear;
	return PtrQ;
};
 
int DeleteQ(Queue PtrQ) {
	struct Node *FrontCell;
	int FrontElem;
 
	if (IsEmpty(PtrQ)) {
		printf("队列空");
		return ERROR;
	}
	FrontCell = PtrQ->front;
	if (PtrQ->front == PtrQ->rear)
		PtrQ->front = PtrQ->rear = NULL;
	else {
		PtrQ->front = PtrQ->front->Next;
	}
	FrontElem = FrontCell->Data;
	free(FrontCell);
	return FrontElem;
}
 
void InsertQ(int item, Queue PtrQ) {
	struct Node *FrontCell;
	FrontCell = (Node*)malloc(sizeof(struct Node));
	FrontCell->Data = item;
	FrontCell->Next = NULL;
 
	if (IsEmpty(PtrQ)) {
		PtrQ->front = FrontCell;
		PtrQ->rear = FrontCell;
	}
	else {
		PtrQ->rear->Next = FrontCell;
		PtrQ->rear = FrontCell;
	}
};
/* 邻接矩阵存储的图 - BFS */
 
/* IsEdge(Graph, V, W)检查<V, W>是否图Graph中的一条边,即W是否V的邻接点。  */
/* 此函数根据图的不同类型要做不同的实现,关键取决于对不存在的边的表示方法。*/
/* 例如对有权图, 如果不存在的边被初始化为INFINITY, 则函数实现如下:         */
bool IsEdge(MGraph Graph, Vertex V, Vertex W)
{
	return Graph->G[V][W]<INFINITY ? true : false;
}
 
/* 	Visited[]为全局变量,已经初始化为false 
	在main函数中执行 */

void BFS(MGraph Graph, Vertex S, void(*Visit)(Vertex))
{   /* 以S为出发点对邻接矩阵存储的图Graph进行BFS搜索 */
	Queue Q;
	Vertex V, W;
 
	Q = CreateQueue(); /* 创建空队列, MaxSize为外部定义的常数 */
	
	/* 访问顶点S:此处可根据具体访问需要改写 */
	//Visit(S);
	Visited[S] = true; /* 标记S已访问 */
	InsertQ(S, Q); /* S入队列 */
	printf("{");
	while (!IsEmpty(Q)) {
		V = DeleteQ(Q);  /* 弹出V */
		printf(" %d", V);
		for (W = 0; W<Graph->Nv; W++) /* 对图中的每个顶点W */
									  /* 若W是V的邻接点并且未访问过 */
			if (!Visited[W] && IsEdge(Graph, V, W)) {
				/* 访问顶点W */
				//Visit(W);
				Visited[W] = true; /* 标记W已访问 */
				InsertQ(W, Q); /* W入队列 */
			}
	} /* while结束*/
	printf(" }\n");
}

void ListComponentsBFS(MGraph Graph)
{
	int V;
	for (V=0; V<Graph->Nv; V++) {
		if (!Visited[V]) {
			BFS(Graph, V, Visit);
		}
	}
}

void DFS(MGraph Graph, Vertex V, void(*Visit)(Vertex))
{   /* 以V为出发点对邻接表存储的图Graph进行DFS搜索 */
	Vertex W;
 
	//Visit(V); /* 访问第V个顶点 */
	Visited[V] = true; /* 标记V已访问 */
	printf(" %d", V);
	for (W = 0; W<Graph->Nv;W++ ) /* 对V的每个邻接点W */
		if ((!Visited[W])&&(Graph->G[V][W]==1))    /* 若未被访问 */
			DFS(Graph, W, Visit);    /* 则递归访问之 */
}

void ListComponentsDFS(MGraph Graph)
{
	int V;
	for (V=0; V<Graph->Nv; V++) {
		if (!Visited[V]) {
			printf("{");
			DFS(Graph, V, Visit);
			printf(" }\n");
		}
	}
}


Publié 9 articles originaux · loué 3 · visites 3134

Je suppose que tu aimes

Origine blog.csdn.net/qq_43469464/article/details/87886376
conseillé
Classement