Data structure based on C language_graph study notes

Table of contents

09 Data Structure Diagram

09.1 Representation of adjacency matrix

09.2 Implementation method of adjacency matrix

09.3 Representation method of adjacency list

09.4 Implementation of adjacency list

09.5 Cross linked list

09.6 Adjacency Multitable


09 Data Structure Diagram

Preface: This section mainly talks about some conceptual things, pure vernacular

        We have talked about the queue stack linked list before. For these structures, we can understand them as some linear data structures. This linear structure is generally a one-to-one relationship. Each element has a unique corresponding predecessor and successor. , can also be said to be a linear table. For the tree binary tree, it is a one-to-many relationship, which means that each node can have multiple nodes. The structure of the graph in this section is a many-to-many relationship. In this relationship, any two nodes may be associated. Each node can have multiple predecessors and successors, which is similar to a map traffic network diagram . You can imagine each city as a point, and highways and railways connect all cities with each other. In fact, the application of graphs is very extensive, such as circuit analysis to find the shortest path, engineering planning...

         Next, some concepts about graphs are introduced: usually graphs can be represented by binary groups, and graph G is divided into two parts VE . v is used to represent a vertex and E is used to represent an edge. A graph can be said to be composed of vertices and edges. V is a collection of vertices and E is a collection of edges. V cannot be empty and can have no edges, but it cannot be pointless (the reason is like a cow eating grass, the grass! It is eaten by the cow! The cow! Leave when you are full! ) But at the level of writing code, V can be empty but not in application.

        Generally speaking, there are two types of graphs: undirected graphs and directed graphs, where the direction refers to the direction. For a directed graph, it is like a one-way street, which can only go in one direction, so an undirected graph is like a two-way street.

        We can use (v1 v2) to represent the relationship between the vertices v1 v2 of the undirected graph. Use <v1 v2> to represent the relationship v1-->v2 of the directed graph v1 v2, where (v1 v2) = (v2 v1) <v1 v2> \= <v2 v1>. So the representation of the undirected graph G1: V(G1)={V1 V2 V3 V4} E(G1)={(V1 V2),(V1 V3),( V2 V3),(...), ...} The representation of G2 of an undirected graph V(G2)={V1 V2 V3 V4} E(G2)={<V1 V2>,<V1 V3>,<V2 V3>,<...>, ...} requires Pay attention to several special cases. The vast majority of graphs are simple graphs, and self-loops are not allowed. There are also multiple graphs (graphs with the same edge cannot appear twice or more)

The concept of a complete graph, any two points in the graph have an edge

        From this, the number of edges can be obtained by using mathematical knowledge to know the number of points. If there are n vertices, there are n(n-1)/2 edges in total. This is the number of edges in an undirected complete graph, and a directed complete graph. The number of sides is n(n-1)       

        In addition, the concept of network is introduced: similar to the time and money consumed by the distance from the city, there is a similar concept between points in the graph- weight . We call a graph with weights a network.

         Two important concepts: adjacency and association . Adjacency is the relationship between vertices. If two vertices share a common edge, we call them mutual adjacencies. We can say that v1 is connected to V2 or v2 is connected to v1. Association refers to the relationship between edges and vertices. For edges adjacent to vertices, we can call edge associations v1 and v2.

        Degree : The degree of a vertex refers to the number of edges associated with the vertex. There is a handshake theorem here. The sum of the degrees of a graph is equal to twice the number of edges. The reason is simple. Each edge is counted twice when calculating the sum of degrees.

        In a directed graph, degrees are further divided into in-degrees and out-degrees . The in-degree is based on the corresponding point as the end point, and the out-degree is based on the corresponding point as the starting point. In addition, the out-degree sum of all vertices is equal to the in-degree sum, which is also very good to understand that if there is an out-degree, there must be an in-degree, so they are equal.

        Path: A sequence of vertices connected by continuous edges (that is, one edge is completely connected to the other edge). The length of the path refers to the number of edges.

        Here are a few more concepts! What is a loopback path ; the first vertex and the last vertex are the same. A simple circuit means that there is no repetition of each node except the middle of the head and the tail. If there is a repetition, it is a non-simple circuit. Simple path: each vertex from vi to vj is not repeated; subgraph : a graph composed of several vertices and several edges taken out from the graph. Generate a subgraph : Take out all vertices and several edges. Connected graph : There is a path between vertices vi and j, which are not necessarily adjacent. If any two points in the graph are connected, it can be called a connected graph. Connected component : For the largest connected subgraph of an undirected graph (adding a point is not connected) is called a connected component. For a connected graph, the largest connected component is itself. For directed graphs, it can be divided into strongly connected graphs and strongly connected components . There is a path from vi to vj, and there is also a path from vj to vi. The largest strongly connected subgraph is to add a point, which means it is not a strongly connected graph.

09.1  Representation of adjacency matrix

Now design a data representation method, which requires the ability to store information such as nodes, node degrees, out-degrees and in-degrees of directed graphs...

Representation of an undirected graph

 The characteristics of the undirected graph adjacency matrix: symmetrical along the diagonal; the number of non-zero elements in the i-th row or i-th column is equal to the degree of the i-th vertex .

Directed graph representation

The characteristics of the directed graph adjacency matrix: not necessarily symmetrical; the number of non-zero elements in the i-th row is equal to the out-degree  of the i-th vertex; the number of non-zero elements in the i-th column is equal to the in- degree of the i-th vertex .

Representation of the net

The feature is the same as the directed graph, not only it is easy to get the in-degree and out-degree of node elements, but also it is easy to see the path weight.

09.2 Implementation method of adjacency matrix

Obviously, in order to store the matrix, we need a two-dimensional array and a one-dimensional array to store node information. In order to assist the traversal operation of the array, we need two elements to store the number of vertices and the number of edges.

Creation of undirected graph code

#include <stdio.h>
#include <stdlib.h>

#define MAX 100

struct AMG_Graph
{
	int vex_num, edge_num;

	char Vex[MAX];
	int Edge[MAX][MAX];
};

struct AMG_Graph *Create_AMG_Graph(void);
void Show_AMG_Graph(struct AMG_Graph *graph);
int search_vex(struct AMG_Graph *graph, char c);

int main(void)
{
	struct AMG_Graph *ud_graph;

	ud_graph = Create_AMG_Graph();
	Show_AMG_Graph(ud_graph);

	return 0;
}

struct AMG_Graph *Create_AMG_Graph(void)
{
	int i, j;
	char u, v;

	struct AMG_Graph *graph;

	graph = (struct AMG_Graph *)malloc(sizeof(struct AMG_Graph));

	printf("Please enter the number of vex: ");
	scanf("%d", &graph->vex_num);
	printf("Please enter the number of edge: ");
	scanf("%d", &graph->edge_num);

	while(getchar() != '\n');

	printf("Please enter vertex:\n");
	for(i = 0; i < graph->vex_num; i++)
	{
		graph->Vex[i] = getchar();
		while(getchar() != '\n');
	}

	for(i = 0; i < graph->vex_num; i++)
	{
		for(j = 0; j < graph->vex_num; j++)
			graph->Edge[i][j] = 0;
	}

	while(graph->edge_num--)
	{
		printf("Please enter the vex that connect each other by edge:\n");
		u = getchar();
		while(getchar() != '\n');
		v = getchar();
		while(getchar() != '\n');

		i = search_vex(graph, u);
		j = search_vex(graph, v);

		if(i != -1 && j != -1)
			graph->Edge[i][j] = graph->Edge[j][i] = 1;
		else
		{
			printf("You have entered wrong vex, please enter again.\n");
			graph->edge_num++;
		}

	}

	return graph;
}

void Show_AMG_Graph(struct AMG_Graph *graph)
{
	int i, j;

	printf("Show the vex: \n");
	for(i = 0; i < graph->vex_num; i++)
		printf("%c ", graph->Vex[i]);
	printf("\n");

	printf("Show the adjacency matrices:\n");
	for(i = 0; i< graph->vex_num; i++)
	{
		for(j = 0; j < graph->vex_num; j++)
			printf("%d\t", graph->Edge[i][j]);
		printf("\n");
	}
}

int search_vex(struct AMG_Graph *graph, char c)
{
	int i;

	for(i = 0; i < graph->vex_num; i++)
	{
		if(c == graph->Vex[i])
			return i;
	}

	return -1;
}

The creation of the directed graph code is
        based on the undirected graph code, delete and modify graph->Edge[i][j] = graph->Edge[j][i] = 1; this part is enough.

#include <stdio.h>
#include <stdlib.h>

#define MAX 100

struct AMG_Graph
{
	int vex_num, edge_num;

	char Vex[MAX];
	int Edge[MAX][MAX];
};

struct AMG_Graph *Create_AMG_Graph(void);
void Show_AMG_Graph(struct AMG_Graph *graph);
int search_vex(struct AMG_Graph *graph, char c);

int main(void)
{
	struct AMG_Graph *ud_graph;

	ud_graph = Create_AMG_Graph();
	Show_AMG_Graph(ud_graph);

	return 0;
}

struct AMG_Graph *Create_AMG_Graph(void)
{
	int i, j;
	char u, v;

	struct AMG_Graph *graph;

	graph = (struct AMG_Graph *)malloc(sizeof(struct AMG_Graph));

	printf("Please enter the number of vex: ");
	scanf("%d", &graph->vex_num);
	printf("Please enter the number of edge: ");
	scanf("%d", &graph->edge_num);

	while(getchar() != '\n');

	printf("Please enter vertex:\n");
	for(i = 0; i < graph->vex_num; i++)
	{
		graph->Vex[i] = getchar();
		while(getchar() != '\n');
	}

	for(i = 0; i < graph->vex_num; i++)
	{
		for(j = 0; j < graph->vex_num; j++)
			graph->Edge[i][j] = 0;
	}

	while(graph->edge_num--)
	{
		printf("Please enter the vex that connect each other by edge:\n");
		u = getchar();
		while(getchar() != '\n');
		v = getchar();
		while(getchar() != '\n');

		i = search_vex(graph, u);
		j = search_vex(graph, v);

		if(i != -1 && j != -1)
			graph->Edge[i][j] = 1;
		else
		{
			printf("You have entered wrong vex, please enter again.\n");
			graph->edge_num++;
		}

	}

	return graph;
}

void Show_AMG_Graph(struct AMG_Graph *graph)
{
	int i, j;

	printf("Show the vex: \n");
	for(i = 0; i < graph->vex_num; i++)
		printf("%c ", graph->Vex[i]);
	printf("\n");

	printf("Show the adjacency matrices:\n");
	for(i = 0; i< graph->vex_num; i++)
	{
		for(j = 0; j < graph->vex_num; j++)
			printf("%d\t", graph->Edge[i][j]);
		printf("\n");
	}
}

int search_vex(struct AMG_Graph *graph, char c)
{
	int i;

	for(i = 0; i < graph->vex_num; i++)
	{
		if(c == graph->Vex[i])
			return i;
	}

	return -1;
}

09.3  Representation method of adjacency list

Using the relationship between the rows and columns of the two-dimensional graph of the adjacency matrix, we can easily obtain the degree, in-degree and out-degree of the graph. This data structure relationship is stored sequentially. You will find that in order to form a matrix, a two-dimensional array we waste a lot of space and not every array is assigned a value.

So is there any other way to represent graphs like chained storage. Answer: Yes... adjacency list. For the study of the adjacency list, we need to focus on how it stores the degree, out-degree and in-degree of the representation graph. We can compare the representation method of the matrix.

Adjacency list of undirected graph

 Features: For n nodes and e edges, the vertex table has n nodes, and the adjacent contact table has 2e nodes.

Adjacency List for Directed Graphs

 Features: For n nodes and e edges, the vertex table has n nodes, and the adjacent contact table has e nodes. The out-degree of a vertex is the number of nodes in the singly-linked list behind the vertex, and the in-degree needs to be counted after traversing the adjacency point table. (If you pay more attention to counting in-degree than out-degree, you can point the arrow to negate and use an inverse adjacency list .)

09.4 Implementation of adjacency list

Adjacency List for Directed Graphs

#include <stdio.h>
#include <stdlib.h>

#define MAX 100

struct AdjNode
{
	int index;
	struct AdjNode *next;
};

struct VexNode
{
	char node;
	struct AdjNode *first;
};

struct ALG_Graph
{
	int vex_num, edge_num;
	struct VexNode Vex[MAX];
};

struct ALG_Graph *Create_ALG_Graph(void);
int search_vex(struct ALG_Graph *graph, char c);
void create_adj_node_list(struct ALG_Graph *graph, int i, int j);
void Show_ALG_Graph(struct ALG_Graph *graph);


int main(void)
{
	struct ALG_Graph *d_graph;
	d_graph = Create_ALG_Graph();
	Show_ALG_Graph(d_graph);
	return 0;
}

struct ALG_Graph *Create_ALG_Graph(void)
{
	int i, j;
	char u, v;

	struct ALG_Graph *graph;

	graph = (struct ALG_Graph *)malloc(sizeof(struct ALG_Graph));

	printf("Please enter the number of vex: ");
	scanf("%d", &graph->vex_num);
	printf("Please enter the number of edge: ");
	scanf("%d", &graph->edge_num);
	while(getchar() != '\n');

	printf("Please enter vertex:\n");
	for(i = 0; i < graph->vex_num; i++)
	{
		graph->Vex[i].node = getchar();
		while(getchar() != '\n');
	}

	for(i = 0; i < graph->vex_num; i++)
	{
		graph->Vex[i].first = NULL;
	}

	while(graph->edge_num--)
	{
		printf("Please enter the vex that connect each other by edge:\n");
		u = getchar();
		while(getchar() != '\n');
		v = getchar();
		while(getchar() != '\n');

		i = search_vex(graph, u);
		j = search_vex(graph, v);

		if(i != -1 && j != -1)
			create_adj_node_list(graph, i, j);
		else
		{
			printf("You have entered wrong vex, please enter again.\n");
			graph->edge_num++;
		}
	}
	return graph;
}

int search_vex(struct ALG_Graph *graph, char c)
{
	int i;

	for(i = 0; i < graph->vex_num; i++)
	{
		if(c == graph->Vex[i].node)
			return i;
	}

	return -1;
}

void create_adj_node_list(struct ALG_Graph *graph, int i, int j)
{
	struct AdjNode *s = (struct AdjNode *)malloc(sizeof(struct AdjNode));
	s->index = j;
	s->next = graph->Vex[i].first;
	graph->Vex[i].first = s;
}

void Show_ALG_Graph(struct ALG_Graph *graph)
{
	int i;
	struct AdjNode *t;

	printf("Show the ALG Graph:\n");

	for(i = 0; i < graph->vex_num; i++)
	{
		printf("%c: ", graph->Vex[i].node);
		t = graph->Vex[i].first;
		while(t != NULL)
		{
			printf("%d ", t->index);
			t = t->next;
		}
		printf("\n");
	}
}

Adjacency list of undirected graph

#include <stdio.h>
#include <stdlib.h>

#define MAX 100

struct AdjNode
{
	int index;
	struct AdjNode *next;
};

struct VexNode
{
	char node;
	struct AdjNode *first;
};

struct ALG_Graph
{
	int vex_num, edge_num;
	struct VexNode Vex[MAX];
};

struct ALG_Graph *Create_ALG_Graph(void);
int search_vex(struct ALG_Graph *graph, char c);
void create_adj_node_list(struct ALG_Graph *graph, int i, int j);
void Show_ALG_Graph(struct ALG_Graph *graph);


int main(void)
{
	struct ALG_Graph *md_graph;
	md_graph = Create_ALG_Graph();
	Show_ALG_Graph(md_graph);

	return 0;
}

struct ALG_Graph *Create_ALG_Graph(void)
{
	int i, j;
	char u, v;

	struct ALG_Graph *graph;

	graph = (struct ALG_Graph *)malloc(sizeof(struct ALG_Graph));

	printf("Please enter the number of vex: ");
	scanf("%d", &graph->vex_num);
	printf("Please enter the number of edge: ");
	scanf("%d", &graph->edge_num);
	while(getchar() != '\n');

	printf("Please enter vertex:\n");
	for(i = 0; i < graph->vex_num; i++)
	{
		graph->Vex[i].node = getchar();
		while(getchar() != '\n');
	}

	for(i = 0; i < graph->vex_num; i++)
	{
		graph->Vex[i].first = NULL;
	}

	while(graph->edge_num--)
	{
		printf("Please enter the vex that connect each other by edge:\n");
		u = getchar();
		while(getchar() != '\n');
		v = getchar();
		while(getchar() != '\n');

		i = search_vex(graph, u);
		j = search_vex(graph, v);

		if(i != -1 && j != -1){
			create_adj_node_list(graph, i, j);
            create_adj_node_list(graph, j, i);
        }
		else
		{
			printf("You have entered wrong vex, please enter again.\n");
			graph->edge_num++;
		}
	}
	return graph;
}

int search_vex(struct ALG_Graph *graph, char c)
{
	int i;

	for(i = 0; i < graph->vex_num; i++)
	{
		if(c == graph->Vex[i].node)
			return i;
	}

	return -1;
}

void create_adj_node_list(struct ALG_Graph *graph, int i, int j)
{
	struct AdjNode *s = (struct AdjNode *)malloc(sizeof(struct AdjNode));
	s->index = j;
	s->next = graph->Vex[i].first;
	graph->Vex[i].first = s;
}

void Show_ALG_Graph(struct ALG_Graph *graph)
{
	int i;
	struct AdjNode *t;

	printf("Show the ALG Graph:\n");

	for(i = 0; i < graph->vex_num; i++)
	{
		printf("%c: ", graph->Vex[i].node);
		t = graph->Vex[i].first;
		while(t != NULL)
		{
			printf("%d ", t->index);
			t = t->next;
		}
		printf("\n");
	}
}

09.5 Cross linked list

For ordinary adjacency lists, if you pay attention to the out-degree you can use the adjacency list of the directed graph, on the contrary if you pay attention to the in-degree you can use the inverse adjacency list of the directed graph. So is there a better solution that is easy to see both the in-degree and the out-degree? We need to add some space on the basis of the linked list...- cross linked list .

The cross-linked list is composed of node table + edge node table (whatever is called here is not the most important concept). The
node table is composed of vertices, incoming arcs + outgoing arcs (incoming arcs and outgoing arcs are pointers) and the
boundary point table is composed of tail + head + same head + tail

09.6 Adjacency Multitable

Compared with the adjacency list of an undirected graph, the adjacency multitable pays more attention to some operations of edges.

Guess you like

Origin blog.csdn.net/shelter1234567/article/details/130387573