C language graph creation (adjacency matrix and adjacency list)

1. Adjacency matrix 

1. Adjacency matrix representation

The adjacency matrix is ​​one of the data structures used to represent graphs and can be represented by a two-dimensional array. In an adjacency matrix, each vertex corresponds to a row and a column of the matrix, and the values ​​in the matrix represent the connectivity between the corresponding two vertices. If there is an edge between two vertices, the corresponding position in the matrix is ​​1; otherwise, it is 0. If it is a network, the corresponding position in the matrix is ​​the weight; otherwise it is \infty (the computer allows, greater than the number on all sides). For undirected graphs, the adjacency matrix is ​​symmetric; for directed graphs, it is not necessarily symmetric. The adjacency matrix can facilitate graph traversal, search, and modification operations, but for sparse graphs (with a small number of edges), the adjacency matrix wastes a lot of space.

Representing a graph using adjacency matrix notation requires, in addition to a two-dimensional array to store the adjacency matrix, a one-dimensional array to store vertex information.

The storage structure is as follows:

#define MVNum 100//最大顶点数
#define MaxInt 66666//表示极大值
typedef struct {
	char vexs[MVNum];//顶点表(顶点为字符型)
	int arcs[MVNum][MVNum];//邻接矩阵(权值为整型)
	int vexnum, arcnum;//图的当前点数和边数
}AMGraph;

 2. Use adjacency matrix representation to create an undirected network

//定位
int LocateVex(AMGraph* G, char v) {
	int i;
	for (i = 0; i < G->vexnum; i++) {
		if (G->vexs[i] == v) {
			return i;
		}
	}
	return -1;
}
//创建无向网G
AMGraph* CreateUDN() {
	int i, j, k, w;
	char v1, v2;
	AMGraph* G = malloc(sizeof(AMGraph));
	printf("输入总顶点数,边数\n");
	scanf("%d%d", &G->vexnum, &G->arcnum);
	getchar();//吸收换行符
	printf("依次输入点的信息\n");
	for (i = 0; i < G->vexnum; i++) {
		scanf("%c", &G->vexs[i]);
	}
	getchar();//吸收换行符
	for (i = 0; i < G->vexnum; i++)
	    for (j = 0; j < G->vexnum; j++) {
		    if (i == j) {
			    G->arcs[i][j] = 0;
		    }
		    else {
			    G->arcs[i][j] = MaxInt;
		    }
	}
	for (k = 0; k < G->arcnum; k++) {
		printf("输入一条边依附的顶点及权值\n");
		scanf("%c%c", &v1, &v2);
		scanf("%d", &w);
		getchar();//吸收换行符
		i = LocateVex(G, v1), j = LocateVex(G, v2);//确定v1、v2在顶点数组的下标
		G->arcs[i][j] = w;//边<v1,v2>权值置为w
		G->arcs[j][i] = w;//无向网对称边<v2,v2>权值也置为w
	}
	return G;
}

Write another output function

void print(AMGraph* G) {
	int i, j;
	printf("  ");
	for (i = 0; i < G->vexnum; i++) {
		printf("%c ", G->vexs[i]);
	}
	printf("\n");
	for (i = 0; i < G->vexnum; i++) {
		printf("%c ", G->vexs[i]);
		for (j = 0; j < G->vexnum; j++) {
			if (G->arcs[i][j] == MaxInt)
				printf("∞ ");
			else
				printf("%d ", G->arcs[i][j]);
		}
		printf("\n");
	}
}

If you want to create an undirected graph, you only need to change two things: first, initialize the edge weights to 0 during initialization; second, change the weight w to 1 when constructing the adjacency matrix. Similarly, you can create a directed graph or a wired network with slight modifications (if you understand the previous knowledge, there will definitely be no problem here).

2. Adjacency list

1. Adjacency list representation

Adjacency List (Adjacency List) is a data structure that represents an undirected graph or a directed graph. It uses an array to store all vertices, and each vertex corresponds to a linked list. The linked list stores all vertices directly adjacent to this vertex. For a directed graph, the linked list in the adjacency list only stores the pointed vertices (the number is out-degree). Sometimes, in order to facilitate the determination of the in-degree of a vertex, an inverse adjacency list of a directed graph can be established. .

The adjacency list storage structure is as follows: 

#define MVNum 100  //最大顶点数
typedef struct ArcNode {  //边表结点
	int adjvex;//邻接点在顶点数组中的下标
	struct ArcNode* next;//指向下一条边的指针
}ArcNode;

typedef struct VNode {   //表头顶点信息结构体
	char data;
	ArcNode* first;//指向第一条依附于该顶点的边的指针
}VNode, AdjList[MVNum];

typedef struct {   //图结构体
	AdjList vertices;//邻接表
	int vexnum, arcnum;//顶点数和边数
}ALGraph;

2. Use adjacency list representation to create an undirected graph 

  • First enter the number of vertices and edges
  • For each edge, two vertices will be associated, so next enter the two vertices to be associated.
  • Call the LocateVex function through the input vertices to find the subscripts of these two vertices in the vertex array.
  • Create a new node and insert it into the singly linked list pointed to by the head node of the associated vertex using head interpolation.
//查找
int LocateVex(ALGraph* G, char v) {
	int i;
	for (i = 0; i < G->vexnum; i++) {
		if (G->vertices[i].data == v) {
			return i;
		}
	}
	return -1;
}
//无向图的创建
ALGraph* CreateALGraph() {
	int i, j, k;
	char v1, v2;
	ALGraph* G = malloc(sizeof(ALGraph));
	printf("输入顶点数和边数:\n");
	scanf("%d%d", &G->vexnum, &G->arcnum);
	getchar();//吸收换行符
	printf("依次输入顶点信息:\n");
	for (i = 0; i < G->vexnum; i++) {
		scanf("%c", &G->vertices[i].data);
		G->vertices[i].first = NULL;
	}
	getchar();//吸收换行符
	//构造边表
	for (k = 0; k < G->arcnum; k++) {
		printf("输入一条边依附的两个顶点:\n");
		scanf("%c%c", &v1, &v2);
		getchar();//吸收换行符
		i = LocateVex(G, v1), j = LocateVex(G, v2);//确定v1、v2在邻接表数组中的下标
		ArcNode* p1 = malloc(sizeof(ArcNode));//生成新的边结点*p1
		p1->adjvex = i;//邻接点序号为i
		p1->next = G->vertices[j].first;//头插法插到顶点vj的边表头部
		G->vertices[j].first = p1;
		//因为是无向图,所以生成对称的边结点*p2
		ArcNode* p2 = malloc(sizeof(ArcNode));
		p2->adjvex = j;
		p2->next = G->vertices[i].first;
		G->vertices[i].first = p2;
	}
	return G;
}

You can also write a function that outputs the adjacency list

void print(ALGraph* G) {
	int i;
	for (i = 0; i < G->vexnum; i++) {
		printf("顶点%c的邻结点有:", G->vertices[i].data);
		ArcNode* p = G->vertices[i].first;
		while (p != NULL) {
			printf(" %c", G->vertices[p->adjvex].data);
			p = p->next;
		}
		printf("\n");
	}
}

Run and build the adjacency list as shown below:

 The running results are as follows:

 Summarize

Guess you like

Origin blog.csdn.net/m0_73070900/article/details/130795983