Graph storage (adjacency matrix, adjacency list, cross-linked list)

1. Adjacency matrix

(1) Basic idea

Use a one-dimensional array to store the information of the vertices in the graph (can be int, char, custom structure, used to store the information of the graph vertices); use a two-dimensional array (called adjacency matrix) to store the information of each vertex in the graph adjacency between

(2) Construction of adjacency matrix

1. Undirected graph

In the adjacency matrix, if the two vertices are connected, assign a value of 1, otherwise assign a value of 0; according to the properties of an undirected graph, the adjacency matrix of an undirected graph must have a main diagonal of 0 and must be a symmetric matrix, as shown in the figure below (The picture comes from the related courses of "Data Structure" by Lazy Cat Teacher)

Degree of a vertex: the sum of the row or column values ​​for that vertex

Connection between two vertices: whether arc[i][j] is 1

Adjacent points of vertices: Traverse the rows and look for points where arc[i][j]==1

2. Directed graph

 Unlike undirected graphs, for a vertex in a directed graph, such as a-->b, then the subscript of b in row a is assigned a value of 1

 

Out-degree of a vertex: the value of the row for that vertex and

In-degree of a vertex: the value of the vertex column and

Connection between two vertices: whether arc[i][j] is 1

Adjacent points of vertices: Traverse the rows and look for points where arc[i][j]==1

3. Network diagram

On the basis of the directed graph, the network graph assigns the node originally assigned a value of 1 as the weight of the edge, and the diagonal of the matrix is ​​assigned a value of 0, and other values ​​are assigned infinite

(3) Code implementation

Here we take the undirected graph as an example, and other graphs can be modified corresponding to the above; it is divided into two packages, the adjacency matrix.h package and the test.c package, and the combination is the complete code

1. Graph_adjacency matrix.h

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_VERTEX 10//最大的顶点个数
typedef int DataType;

//以下是无向图的定义
void MGraph(DataType *vertex, int arc[][MAX_VERTEX], int vertexNum, int arcNum) { //初始化构造图(邻接矩阵法)
	printf("请逐个输入顶点的内容:");
	DataType x;
	DataType vi, vj; //构建邻接矩阵时,一条边的两个结点编号
	for (int i = 0; i < vertexNum; i++) { //顶点数组赋值
		scanf("%d", &x);
		vertex[i] = x;
	}
	for (int i = 0; i < vertexNum; i++) //初始化邻接矩阵
		for (int j = 0; j < vertexNum; j++)
			arc[i][j] = 0;
	int count = 1;
	for (int i = 0; i < arcNum; i++) { //依次输入每一条边
		printf("请输入第%d条边依附的两个顶点的编号:", count++);
		scanf("%d %d", &vi, &vj); //输入该边依附的顶点的编号
		arc[vi][vj] = 1; //置有边标志
		arc[vj][vi] = 1;
	}

}

void printMGraph(DataType *vertex, int arc[][MAX_VERTEX], int vertexNum) { //输出
	printf("vertex:");
	for (int i = 0; i < vertexNum; i++) {
		printf("%d ", vertex[i]);
	}
	printf("\n");
	printf("arc:\n");
	for (int i = 0; i < vertexNum; i++) {
		for (int j = 0; j < vertexNum; j++) {
			if (j == vertexNum - 1)
				printf("%d\n", arc[i][j]);
			else
				printf("%d ", arc[i][j]);
		}
	}

}

int isLinked(int arc[][MAX_VERTEX], int i, int j) { //两顶点i,j是否有边相连,1是相连,0是不相连
	if (arc[i][j] == 1)
		return 1;
	else
		return 0;
}

int nodeDepth(int arc[][MAX_VERTEX], int index, int vertexNum) { //任意一顶点的度
	//无向图任意遍历行\列求和
	int count = 0;
	for (int i = 0; i < vertexNum; i++) {
		if (arc[index][i] == 1)
			count++;
	}
	return count;
}

2. Graph test_adjacency matrix.c

#include "图_邻接矩阵.h"

main() {
	DataType vertex[MAX_VERTEX];//储存所有的顶点
	int arc[MAX_VERTEX][MAX_VERTEX];//邻接矩阵,结点间的连通关系
	int vertexNum, arcNum; //结点个数,边的个数
	printf("输入顶点个数:");
	scanf("%d", &vertexNum);
	printf("输入边个数:");
	scanf("%d", &arcNum);
	MGraph(vertex, arc, vertexNum, arcNum);
	printMGraph(vertex, arc, vertexNum);
	printf("测试判断两顶点是否相连,请输入两个顶点下标:");
	int i, j;
	scanf("%d %d", &i, &j);
	if (isLinked(arc, i, j) == 1)
		printf("相连!\n");
	else
		printf("不相连!\n");
	printf("测试求顶点的度,请输入一个顶点下标:");
	int index;
	scanf("%d", &index);
	printf("该顶点的度为:%d", nodeDepth(arc, index, vertexNum));

}

(4) Output test

Test case:

output:

 2. Adjacency list

 (1) Basic idea

Create a one-dimensional array. The element structure in the one-dimensional array is defined as two parts, one part stores the information of the vertices, and the other part stores the head pointer of the linked list. And the head pointer of each linked list points to a linked list, and what is stored in the linked list is the point information to which the vertex is connected.

The one-dimensional array is called the vertex list , and the linked list pointed to by each array element is called the edge list.

(2) Construction of adjacency list

1. Data structure

typedef struct ArcNode { /*边表结点*/
	int adjvex;//边表数据域,即下标
	struct ArcNode *next; //指针域
} ArcNode;

typedef struct VertexNode { /*顶点表结点*/
	DataType vertex;//顶点的数据
	ArcNode *firstEdge; //指向储存该顶点所连接所有结点的边表
} VertexNode;

The construction of the edge table linked list here uses the head interpolation method, see the complete code at the bottom for details

2. Undirected graph

Vertex degree: Traverse the vertex table to find the vertex, traverse the linked list of the vertex, and find the number of nodes

Connection between two vertices: Traverse the vertex table to find the vertex, traverse the linked list of the vertex, and find out whether there is another node

3. Directed graph

The out-degree of the vertex: traverse the vertex table to find the vertex, traverse the linked list of the vertex, and find the number of nodes

The in-degree of a vertex: Traverse every other vertex in the vertex table, and traverse the linked list of every other vertex, and find the number of occurrences of this vertex

Adjacent point: traverse the vertex table to find the vertex, and traverse the linked list of the vertex, which is the adjacent point

4. Network diagram

Added storage of weights on the basis of directed graphs

(3) Code implementation

 Here we take the directed graph as an example, and other graphs can be modified accordingly; it is divided into two packages, the adjacency list.h package and the test.c package, and the combination is the complete code

1. Figure_adjacency list.h

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_VERTEX 10//最大的顶点个数
typedef int DataType;

typedef struct ArcNode { /*边表结点*/
	int adjvex;//边表数据域,即下标
	struct ArcNode *next; //指针域
} ArcNode;

typedef struct VertexNode { /*顶点表结点*/
	DataType vertex;//顶点的数据
	ArcNode *firstEdge; //指向储存该顶点所连接所有结点的边表
} VertexNode;
void initVertex(DataType *, int);

//以下是有向图的定义
void ALGraph(DataType *vertex, VertexNode *adjList, int vertexNum, int arcNum) { //初始化构造图(邻接表法)
	DataType vi, vj;
	int count = 0;
	initVertex(vertex, vertexNum);
	for (int i = 0; i < vertexNum; i++) { //初始化顶点表
		adjList[i].vertex = vertex[i];
		adjList[i].firstEdge = NULL;
	}
	for (int i = 0; i < arcNum; i++) {
		//输入边的信息储存在边表中
		printf("请输入第%d条边依附的两个顶点的编号(方向->):", count++);
		scanf("%d %d", &vi, &vj); //输入该边依附的顶点的编号
		ArcNode *s;
		s = (ArcNode *)malloc(sizeof(ArcNode));
		if (s != NULL) {
			s->adjvex = vj;
			s->next = adjList[vi].firstEdge; //头插法建立链表
			adjList[vi].firstEdge = s;
		} else
			printf("init error!\n");
	}
}

void initVertex(DataType *vertex, int vertexNum) {//输入函数
	printf("请逐个输入顶点的内容:");
	DataType x;
	for (int i = 0; i < vertexNum; i++) { //顶点数组赋值
		scanf("%d", &x);
		vertex[i] = x;
	}
}

void printALGraph(VertexNode *adjList, int vertexNum) {
	printf("vertex  firstEdge\n");
	ArcNode *p ;
	for (int i = 0; i < vertexNum; i++) {
		printf("%3d -->", adjList[i].vertex);
		p = adjList[i].firstEdge;
		while (p != NULL) {
			printf("%d -->", p->adjvex);
			p = p->next;
		}
		printf("NULL\n");
		printf("\n");
	}
}

int isLinked(VertexNode *adjList, int i, int j) { //两顶点i,j是否有边相连,1是相连,0是不相连
	ArcNode *p = adjList[i].firstEdge ;
	while (p != NULL) {
		if (p->adjvex == j)
			return 1;
		else
			p = p->next;
	}
	p = adjList[j].firstEdge;
	while (p != NULL) {
		if (p->adjvex == i)
			return 1;
		else
			p = p->next;
	}
	return 0;
}

int nodeDepth(VertexNode *adjList, int index, int vertexNum) { //任意一顶点的度
	int count = 0;
	ArcNode *p = adjList[index].firstEdge;
	while (p != NULL) {
		count++;
		p = p->next;
	}
	return count;
}

void freeArcNode(VertexNode *adjList, int vertexNum) {
	ArcNode *p;
	ArcNode *temp;
	for (int i = 0; i < vertexNum; i++) {
		p = adjList[i].firstEdge ;
		while (p != NULL) {
			temp = p;
			p = p->next;
			free(temp);
		}
	}
}

2. Graph test_adjacency list.c

#include "图_邻接表.h"

int main() {
	DataType vertex[MAX_VERTEX];//储存所有的顶点
	int vertexNum, arcNum; //结点个数,边的个数
	printf("输入顶点个数:");
	scanf("%d", &vertexNum);
	printf("输入边个数:");
	scanf("%d", &arcNum);
	VertexNode adjList[vertexNum];//顶点表
	ALGraph(vertex, adjList, vertexNum, arcNum);
	printALGraph(adjList, vertexNum);
	printf("测试判断两顶点是否相连,请输入两个顶点下标:");
	int i, j;
	scanf("%d %d", &i, &j);
	if (isLinked(adjList, i, j) == 1)
		printf("相连!\n");
	else
		printf("不相连!\n");
	printf("测试求顶点的度,请输入一个顶点下标:");
	int index;
	scanf("%d", &index);
	printf("该顶点的度为:%d", nodeDepth(adjList, index, vertexNum));
	freeArcNode(adjList, vertexNum);
}

(4) Test output

Test case:

output:

3. Cross linked list

A pointer field is added in the structure definition, pointing to the point in the <-- direction

 

Beginner Xiaobai, welcome to correct me if I make mistakes! !

Guess you like

Origin blog.csdn.net/m0_63223213/article/details/126300547