接続セットのリスト(25ポイント)C ++実装

/ *このテーマに関する他の偉大な神々のコードを読んだ後、私はそれらを自分で書きました。いくつかの場所は私にとって少し難しい、初心者のデータ構造を持つ初心者です。変更が完了した後、理解できない場合は、MOOCに移動して、オンラインコースを見て理解することができます。* /

N個の頂点とE個のエッジを持つ無向グラフを前提として、DFSとBFSを使用して、接続されているすべてのセットを一覧表示します。頂点に0からN-1までの番号が付けられているとします。検索を実行するときは、常に最も番号の小さい頂点から開始し、番号の昇順で隣接するポイントを訪問すると想定されています。

入力形式:
最初の行を入力して、2つの整数N(0 <N≤10)とEを指定します。これらはそれぞれ、グラフの頂点とエッジの数です。次に、ラインEで、各ラインはエッジの2つの端点を示します。各行の番号は1スペースで区切られます。

出力フォーマット:
「{v1 vk}」フォーマットに従って、各ラインは接続されたセットを出力します。DFS結果が最初に出力され、次にBFS結果が出力されます。
入力例:

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

出力例:

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

元のタイトルの住所

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


元の記事を9件公開 賞賛3 訪問3134

おすすめ

転載: blog.csdn.net/qq_43469464/article/details/87886376