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 (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: