Lista de conjuntos conectados (25 puntos) Implementación de C ++

/ * Después de leer los códigos de otros grandes dioses sobre este tema, los escribí yo mismo. Algunos lugares son un poco difíciles para mí, un principiante con la estructura de datos del principiante. Mi código principal es el código proporcionado por la Universidad MOOC Zhejiang después de la clase de estructura de datos. Una vez completada la modificación, si no comprende, puede ir a MOOC para ver el curso en línea para comprender jaja. * /

Dado un gráfico no dirigido con N vértices y bordes E, use DFS y BFS para enumerar todos sus conjuntos conectados. Supongamos que los vértices están numerados de 0 a N − 1. Al realizar una búsqueda, se supone que siempre comenzamos desde el vértice con el número más bajo y visitamos los puntos adyacentes en orden creciente.

Formato de entrada:
Ingrese la primera línea para dar 2 enteros N (0 <N≤10) y E, que son el número de vértices y bordes del gráfico, respectivamente. Luego, en la línea E, cada línea da dos puntos finales de un borde. Los números en cada línea están separados por 1 espacio.

Formato de salida: de
acuerdo con el formato "{v1 vk}", cada línea emite un conjunto conectado. El resultado DFS se genera primero, seguido del resultado BFS.
Entrada de muestra:

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

Salida de muestra:

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

Dirección del título original

/*	参考资料
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");
		}
	}
}


Publicado 9 artículos originales · elogiado 3 · visitas 3134

Supongo que te gusta

Origin blog.csdn.net/qq_43469464/article/details/87886376
Recomendado
Clasificación