Basic concepts and representation methods of graphs (key understanding of chained forward stars, simple and easy-to-understand version)

A graph is a data structure that represents the many-to-many relationships that exist between elements in a collection.

Some definitions of graphs:

1. A graph is composed of vertices and edges connecting vertices, that is, G = ( V , E ) , where V is the set of vertices and E is the set of edges.
2. An edge represents a certain relationship between two vertices, and the edge is expressed as (u, v) , where u, v∈V are two vertices in the graph.
3. When the edges in the graph have no direction, it is called an undirected graph. When representing edges in an undirected graph, the order of u and v can be reversed.
4. When the edges in the graph have directions, it is called a directed graph . When expressing the edges of a directed graph, the starting point must be in front and the end point must be in the back.
5. The edges of the graph can be attached with a value (weight), which is called a weighted graph .
6. The edge starting from vertex u is called the outgoing edge of u , and the edge ending at vertex u is called the incoming edge of u . Obviously, for an undirected graph, the edge connected to the vertex u is both the incoming edge and the outgoing edge of u. The number of outgoing edges of vertex u is called the out-degree of u , and the number of incoming edges of u is called the in-degree of u . The next vertex v that starts from vertex u and reaches the next vertex v is called the adjacent point of u .
7. If the path from u to v has different vertices except that the start point and end point may be the same, then such a path is called a simple path from u to v.
8.
For an unweighted graph, the number of edges passed on a path is called the length of the path; For a weighted graph, the sum of the weights on the path between two vertices is called the weighted path length .
9. If there is a vertex u, starting from u, there is a simple path, and the end point of the path is also u, then this path is called a cycle on the graph, and a graph with at least one cycle is called a cyclic graph, and there is no A graph with cycles is called an acyclic graph .

There are two main types of graph representation methods: adjacency matrix representation and edge table representation.

Adjacency Matrix Representation of Graph

The adjacency matrix representation of a graph uses a two-dimensional array (matrix) to represent a graph, and each element in the two-dimensional array represents the relationship between the corresponding two vertices. The specific method is: number each vertex of the graph (starting from 1), and the vth element of the uth row of the two-dimensional array represents the relationship between the uth vertex and the vth vertex.

When representing a graph with an adjacency matrix, it is necessary to record the number of vertices and edges of the graph.

The relationship between two vertices can be determined by the two-dimensional array (adjacency matrix) edge. For an undirected graph, the edge must be a symmetric matrix. Consider edge[u][v], for an unweighted graph (directed or undirected), if there is an edge between u and v, then edge[u][v]=1, otherwise=0; for a weighted graph ( directed or undirected), if there is an edge between u and v with weight w, then edge[ u ][ v ] = w, otherwise = INF.

struct adjMatrix {
	datatype data[eNum]; //顶点的数据信息
	int edge[eNum][eNum];//邻接矩阵
	int v; //顶点的数量
	int e; //边的数量
};

//根据输入的信息创建无向带权图的邻接矩阵表示
void create_adjMatrix(adjMatrix& g) {
	int i, j, u, v, w;
	cin >> g.v >> g.e;
	for (int i = 1; i >= g.v; i++) //初始化图
		for (int j = 1; j <= g.v; j++)
			g.edge[i][j] = INF;   //如果是无权图,用0取代等式右边的INF
	for (i = 0; i > g.e; i++) {
		cin >> u >> v >> w; //输入一条边,无权图不需要输入w,且将下面两语句中的w变为1
		g.edge[u][v] = w; //将(u,v)加入图中
		g.edge[v][u] = w; //将(v,u)加入图中,有向图忽略该语句
	}
}

//输出无权图g中第u个顶点的所有邻接点
void adjVertex(adjMatrix g, int u) {
	for (int i = 1; i <= g.v; i++)
		if (g.edge[u][i] != INF)
			cout << i << " ";
}

The adjacency matrix representation of graphs is suitable for dense graphs (the number of edges is relatively large). For non-dense graphs, the space utilization is not too high when the graph is represented by adjacency matrix notation.

Edge Table Representation of Graph

In the adjacency matrix representation of a graph, no matter whether there is an edge between two vertices, a value needs to be specified, which not only increases the storage space, but also adds some additional overhead when processing the graph. Therefore, the graph can be represented by only saving the edge information, that is, the edge table representation. Edge table representation refers to the method of representing a graph by storing the adjacency points of each vertex in a linked list or array.

1. Linked list representation of graph

The linked list representation of the graph is to store the adjacency points of each vertex of the graph in a linked list. In the linked list representation of the graph, each vertex corresponds to a scale, and the head nodes of all linked lists are placed in an array (edge). In addition to the number of the adjacent point in the node of the linked list, for the weighted graph, it should also contain the weight of the edge between the vertex and the adjacent point.

 From the figure above, the adjacent points of a vertex v are all stored in the linked list with edges[v] as the head node, and there is no specific requirement for the order of storage. Also, each edge of an undirected graph appears twice in the linked-list representation of the graph.
Since the storage order of the adjacency points of a vertex is arbitrary, when adding an adjacency point to a vertex of a graph, it can be directly inserted behind the head node.

struct vertex {
	int u; //邻接点的编号
	int w; //权重,无权图可忽视该属性
	vertex* next;
	vertex(int u1=0,int w1=0):u(u1),w(w1),next(NULL){}
};

typedef struct llNode {
	datatype data[vNum]; //顶点的数据信息
	vertex* edges[vNum]; //边表
	int v, e; //顶点数和边数
	llNode() :v(0), e(0) {
		for (int i = 0; i < vNum; i++)
			edges[i] = NULL;
	}
}*linkList;

//创建链表表示的图
void add_edge(linkList& g, int u, int v, int w) {
	vertex* tmp = new vertex(v, w); //边表的信息只存储v,w,将包含这个信息的结点存进边表即可
	if (g->edges[u] == NULL)
		g->edges[u] = new vertex;
	tmp->next = g->edges[u]->next; //将顶点v加入顶点u的边表
	g->edges[u]->next = tmp;
}

//根据输入的数据,创建图
void create_linkList(linkList& g) {
	int u, v, w;
	g = new llNode;
	cin >> g->v >> g->e; //输入顶点数和边数
	for (int i = 0; i < g->e; i++) {
		cin >> u >> v >> w;//输入一条边的信息,无权图不需要输入w,且将下列两语句的w变为1;
		add_edge(g, u, v, w); //将边(u,v)加入图中
		add_edge(g, v, u, w); //将边(v,u)加入图中,有向图忽略该语句
	}
}

Advantages: 1. Save space for non-dense matrices 2. Higher efficiency in operations on linked list representations than adjacency matrices

Disadvantage: It is not as convenient as the adjacency matrix when finding the in-degree (in-edge) of a fixed point of the directed graph represented by the link list, which is also the deficiency of the edge table representation.

2. The vector array representation of the graph

Since the container vector in STL represents a dynamic array, an array of vector type can be used to store the adjacent points of a vertex in the graph.

Like the link list representation, the vector array representation of a graph can efficiently find all the adjacent points of a vertex and the weight between the vertex and the connection point, but it is more troublesome to find the in-edge and in-degree of a vertex.

//图的vector数组表示的类型定义
struct edge {
	int v; //邻接点
	int w; //权重,无权图可忽视该属性
	edge(int v1, int w1) :v(v1), w(w1) {};
};
typedef struct vgNode {
	vector<edge>edges[vNum]; //边表
	datatype data[vNum]; //顶点的数据信息
	int v, e; //顶点数和边数
}vecGraph;

//创建vector数组表示的图
void create_vecGraph(vecGraph& g) {
	int i, u, v, w;
	cin >> g.v >> g.e; //输入顶点数和边数
	for (i = 0; i < g.e; i++) {
		cin >> u >> v >> w; //输入边的信息,无权图省略w,且下列语句w变为1
		g.edges[u].push_back(edge(v, w)); //将边(u,v)加入图中
		g.edges[v].push_back(edge(u, w)); //将边(v,u)加入图中,有向图忽略该语句
	}
}

//在实际应用中,可以采取如下更简单的表示方法
int v; //顶点数
vector<int>g[vNum]; //无权图
vector<pair<int, int>>g1[vNum]; //有权图,pair中的first代表邻接点,second代表权重

3. The chain forward star representation of the graph (this is the graph in the video explanation of station B, easy to understand, and the video is in the reference)

 

 

 

 

 

 

 

 

 

#include<iostream>
#include<vector>
using namespace std;
constexpr auto eNum = 102; //图的顶点数量
constexpr auto vNum = 200; //图的边的数量
typedef string dataType; //图顶点中存放数据信息的类型
typedef int datatype;
constexpr auto INF = 0x3f3f3f3f ;

//链式前向星的顶点及其相关变量的定义
struct node {
	int to; //邻接点
	int w; //权重
	int next; //下一个顶点
	node() :next(-1) {
	}
}edges[eNum<<1]; //边表,大小为2*eNum
int header[vNum], //每一个顶点第一个邻接点的编号
v, e, //顶点数和边数
cnt = 0; //计数器,表示数组edges中没有被占用的最小下标

//图的链式前向星表示的构建
//添加一条边(u,v),w为边的权重
void add_edge(int u, int v, int w) {
	edges[cnt].to = v;
	edges[cnt].w = w;  //将边的信息加入edges
	edges[cnt].next = header[u]; //将边加入顶点u的邻接点链中
	header[u] = cnt++; //将u的header设置为新加入边在edges中的位置
}

//创建无向带权图的链式前向星表示,更新全局变量edges和header
void create_graph() {
	int i, x, y, w;
	cin >> v >> e; //输入顶点数和边数
	for (int i = 0; i <= v; i++)  //初始化每一个顶点的header
		header[i] = -1;
	for (int i = 0; i < e; i++) { //加入每一条边
		cin >> x >> y >> w;
		add_edge(x, y, w);
		add_edge(y, x, w);
	}
}

//输出每个顶点的邻接点及其相对应的权重
void traverse() {
	for (int i = 1; i <= v; i++) { //考虑每一个顶点
		cout << i << ":";
		for (int j = header[i]; ~j; j = edges[j].next) //遍历顶点i的邻接点链
			cout << edges[j].to << " " << edges[j].w << ",";
		cout << endl;
	}
}


int main() {
	create_graph();
	traverse();
}

reference:

Introduction to "Algorithm Training Camp" 17 Chained forward star - the most perfect illustration_哔哩哔哩_bilibili icon-default.png?t=MBR7https://www.bilibili.com/video/BV13r4y1X7a4/?spm_id_from=333.337.search-card.all. click&vd_source=a2417ade71290cd940c5e2edb896b97b

【AgOHのData Structure】Do you really understand chained forward star? _哔哩哔哩_bilibili icon-default.png?t=MBR7https://www.bilibili.com/video/BV1mJ411S7BB/?spm_id_from=333.337.search-card.all.click&vd_source=a2417ade71290cd940c5e2edb896b97b

Guess you like

Origin blog.csdn.net/qq_62687015/article/details/128746108
Recommended