16-Data structure-storage structure of graph

Introduction: Mainly for sequential storage and chain storage of graphs. Among them, sequential storage is the drawing method and code of the adjacency matrix. The adjacency matrix is ​​divided into a weighted graph and an unweighted graph. The difference is that where there is data, fill in the weight value, and where there is no data, you can fill in 0 or ∞, while the weighted graph and the unweighted graph can be filled in. Weight graphs are further subdivided into directed graphs and undirected graphs. An undirected graph is a symmetric matrix because there is no direction at all, and the out-degree and in-degree are the same. There are differences in directed graphs. By the way, the adjacency matrix is ​​the out-degree when viewed horizontally, and the in-degree when viewed vertically. Linked storage includes adjacency lists, cross-linked lists and adjacency multiple lists. Adjacency lists, directed graphs and undirected graphs can be used, and cross-linked lists are the optimization of adjacency list directed graphs and can calculate in-degree and out-degree at the same time. Degree, and the adjacency multiple list is an optimization of the adjacency list undirected graph, which can save half of the edge space, from the original number of vertices + 2 * total number of edges to the number of vertices + total number of edges.

Table of contents

1. Sequential storage-adjacency matrix

1.1-Introduction

1.2-Code

1.3-Operation results

2. Linked storage-adjacency list

2.1 Adjacency list

2.1.1.Code

2.2 Cross linked list

2.2.1 Code

2.3 Adjacency multiple lists

2.3.1 Code:


1. Sequential storage-adjacency matrix

1.1-Introduction

Graphs naturally include vertices and edges. The adjacency matrix represents the graph in the form of an array.

A one-dimensional array is needed to store vertex information - a vertex is a unit like student 1, student 2 and so on.

A two-dimensional array, which is the adjacency matrix, is also needed to store the relationship between vertices; secondly, it is necessary to record the number of vertices and the total number of edges in the graph.

The idea of ​​​​my code is my own, from creation to runnability. If I encounter something simple, I will change it later.

Idea:

  1. First initialize the graph and enter the desired number of vertices and edges into the graph. Secondly, initialize the one-dimensional array and the two-dimensional array.
  2. To create and input data, first give the vertex information and enter it into the vertex array. The next step is to judge whether it is a directed graph or an undirected graph. (The default is an unauthorized map) (A authorized map is just an additional set of numbers that need to be entered manually).
  3. An undirected graph is a symmetric matrix. Enter the desired edge relationship, that is, 1 and 2, and the corresponding adjacency matrix is ​​directly changed to 1, indicating that two points are connected, and the symmetrical position is also updated to 1.
  4. Directed graph. Just update one, but not the other.

1.2-Code

#include <stdio.h>
#define Max 10
#include <string.h>
//图的顺序存储_邻接矩阵
typedef struct
{
	char vertex[Max];    //存放顶点的一维数组 
	int  edge[Max][Max];	//表示顶点之间关系的二维数组; 
	
	int vertex_num;  //顶点数 
	int edge_num;    //边数 
	
}MGragh; 
//初始化邻接矩阵 
void InitMGragh(MGragh *a) 
{
	printf("添加几个顶点\n");
	int x;
	scanf("%d",&x); 
	//赋值	
	a->vertex_num=x;
	
	printf("有多少条边\n"); 
	int c; 
	scanf("%d",&c);
	//赋值 
	a->edge_num=c;
	//初始化邻接矩阵存储边信息的二维数组 
	a->edge[Max][Max];
	int p,q;
	for(p=0;p<a->vertex_num;p++)
	{
		for(q=0;q<a->vertex_num;q++)
		{
			a->edge[p][q]=0;
		}
	} 
	//初始化,顶点数组 
	a->vertex[a->vertex_num]='0'; 	
}
//打印邻接矩阵 
void PrintMGragh(MGragh *a)
{
	int p,q;
		for(p=0;p<a->vertex_num;p++)
		{
			for(q=0;q<a->vertex_num;q++)
			{
				
				printf("%d ",a->edge[p][q]);
			}
			printf("\n");
		} 
}
void Creat_MGragh(MGragh *a)
{
	printf("图的顶点数%d\n",a->vertex_num);
	int i=0;
	printf("请加顶点到顶点数组\n"); 
	for(i=0;i<a->vertex_num;i++)
	{	printf("i=%d\n",i);
		char x;
		x=getchar();
		char k;//由于单个字符输入,回车也在输入序列中,因此还需要一个变量,来吃掉回车 
		k=getchar();
		a->vertex[i]=x;
	}
	printf("您想弄成无向图还是有向图,1为无向图,2为有向图\n");
	int text;
	scanf("%d",&text);
	if(text == 1)
	{
		printf("请添加顶点间关系\n"); 
		
		int w=0;
		while(w!=2)
		{
			printf("哪个顶点和哪个顶点之间有联系\n");
			int d1,d2;
			scanf("%d %d",&d1,&d2);
			a->edge[d1-1][d2-1]=1;
			a->edge[d2-1][d1-1]=1;
			printf("是否还需要继续添加,是填1,否填2\n");
			scanf("%d",&w); 
		}		
	}
	else
	{
		printf("请添加顶点间关系\n"); 
		
		int w=0;
		while(w!=2)
		{
			int d1,d2;
			printf("从哪个顶点到哪个顶点\n");
			scanf("%d %d",&d1,&d2);
			a->edge[d1-1][d2-1]=1;
			printf("是否还需要继续添加,是填1,否填2\n");
			scanf("%d",&w); 
		}
	} 
}

int main()
{
	MGragh a;
	//初始化图 
	InitMGragh(&a);
	//创建邻接矩阵图 
	Creat_MGragh(&a); 
	//打印邻接矩阵 
	PrintMGragh(&a);
	return 0;
 } 

1.3-Operation results

2. Linked storage-adjacency list

2.1 Adjacency list

        Introduction: The adjacency list is actually mainly a vertex table followed by a corresponding edge table. Record the total number of edges and vertices.

For chain storage. It is suitable for sparse graphs and is convenient for calculating the degree. You only need to find the corresponding vertex, and then traverse the string through the singly linked list of the vertex. But in-degree requires traversing each vertex singly linked list.

Both undirected and directed graphs are acceptable . In a directed graph , each vertex passes a direction, and either the degree is obtained or the degree is entered. So the space it needs is O(number of vertices+total number of edges); while graph is connected to the vertex, all of which are connected, so the required storage space is O(number of vertices+2*total edges) number).

2.1.1.Code

        Edge table ArcNode: includes the point subscript and next pointer field.

//边表 
typedef struct ArcNode
{
	int NodeName;
	struct ArcNode *next;
	
}ArcNode; 

         Vertex table: stores each vertex of the graph. Behind each vertex is actually a singly linked list of the corresponding out-degrees starting from it.

//顶点表
typedef struct
{
	int data;//顶点内容 
	ArcNode* first;	//顶点标的链的头指针 
	
}VNode;

        Adjacency list: The last one is the adjacency list, that is, you only need to go through the vertex table to access the out-degree of each vertex.

//创建邻接表,包含顶点表和边表,以及边数和顶点数的记录 
typedef struct
{
	VNode vertice[vertice_num];//顶点表,每个顶点标中的数据,串成一个对应的链 
	int vexnum;//顶点数 
	int edgenum;//边数	
}ALGragh; 

       Because of the implementation, at my current level, it feels a bit troublesome. I need to traverse each vertex, and each vertex needs to create an edge table node. I also need to give each vertex a single linked list to form. I have no idea at the moment and I get stuck in the middle of writing. Okay, once you become proficient in it, you can implement it again.        

2.2 Cross linked list

        Introduction: The cross linked list is only applicable to directed graphs. In order to make up for the directed graph in the adjacency list, only one-way degree can be calculated.

There is some more in-depth information. First, give the form of adjacency list and draw the out-degree. Then find the in-degree of each vertex in the vertex table. If the in-degree enters 0, start from 0 and look at which end point in the edge table is 0. Connect them. If not, set them to empty.

        The cross-linked list still traverses the out-degree chain and in-degree chain of the corresponding vertex through the vertex table, until it reaches the out-degree and in-degree of the corresponding vertex.

2.2.1 Code

//边表
typedef struct ArcNode
{
	int tailvex,headvex;//弧尾tail弧头head     弧尾(起点)->弧头(终点) 
	struct ArcNode *hlink,*tlink;//指针域,即出度指针域为弧头,入读指针域为弧尾,先连接弧头指针域,出度、再连接弧尾指针域 
	char info;//存储信息的指针 
}ArcNode; 
//顶点表
typedef struct VNode
{
	AreNode *firstin,*firstout;//出度入读头指针 
	int data;//顶点信息 
	
}VNode;
//十字链表
typedef struct GLGraph 
{
	VNode xlist[vertice_num];//顶点表 
	int vexnum,edgenum;//顶点数和边数 
	
}GLGraph;  

2.3 Adjacency multiple lists

Introduction: The adjacency multiple list is only applicable to undirected graphs. It is an optimization of the undirected graph in the adjacency list. The undirected graph in the adjacency list will repeat multiple connections, 2*the total number of edges, and the adjacency multiple list saves, which is E.

Drawing method: First draw the vertex table and edge table. The edge table contains the vertices related to the vertices in the leftmost vertex table, that is, the edges. It is the starting point and the end point of the edge, and has two related pointer fields. The first step is to mark the corresponding values ​​and draw them from top to bottom. If there are duplicate edges, they will not be drawn.

//Example of strongly connected institutions - I don’t want to draw it myself, just be lazy

The second step is chaining. Starting from the vertex in the left vertex table, find the same pointer field as the vertex in the right table and connect it. For example, the subscript of b is 2. Starting from b, find the right edge The pointer field of 2 in the table. There is one pointer field in the first line of 2 and two in the second line. Just string these three.

2.3.1 Code:

//邻接多重表-无向图
//边表
typedef struct AreNode
{
		int mark; //标记是否串过
		int ivex,jvex;//表示弧的两个顶点
		struct AreNode *ilink,*jlink;
		char info;//其他信息	
}AreNode;
//顶点表
typedef struct VNode
{
	int data;//顶点信息 
	AreNode *first;//指向边表中第一个挨着该顶点的结点 
	
}VNode;
//邻接多重表
typedef struct  AMLGraph
{
	VNode xlist[vertice_num];//顶点表 
	int vexnum,edgenum;//总边数和总结点数 
}AMLGraph; 

Guess you like

Origin blog.csdn.net/m0_59844149/article/details/132678679