(10) Figure

1. Definition: It consists of a finite non-empty set of vertices and a set of edges between vertices, usually expressed as: G(V, E), G represents a graph, V is the set of vertices in graph G, and E is graph G A collection of middle edges. The data elements in the linear table are called elements, the trees are called nodes, and the data elements in the graph are called vertices. A linear table without data elements is called an empty table, and a tree without nodes is called an empty tree. The graph structure emphasizes that the vertex set V must be finite and non-empty. In a linear table, there is a linear relationship between adjacent data elements. In a tree structure, nodes in two adjacent layers have a hierarchical relationship. In a graph structure, there may be a relationship between any two vertices. The logic between vertices Relationships are represented by edges, and the set of edges can be empty.

2. Undirected graph: If the edge between vertices Vi and Vj has no direction, the edge is called an undirected edge, which is represented by an unordered pair (Vi, Vj). Vertices V1 and V2 are adjacent to each other. The degree of vertex V is the number of edges associated with V, denoted as TD(V), vertex A and vertex B are adjacent to each other, edges (A, B) are attached to vertices A and B, and the degree of vertex A is 3 .

G1是一个无向图,G1={V1,E1}
V1={A,B,C,D}
E1={(A,B),(B,C),(C,D),(D,A),(A,C)}

3. Directed graph: If the edge from vertex Vi to Vj has a direction, then the edge is called a directed edge or arc. It is represented by an ordered pair <Vi, Vj>, Vi is called the arc tail, Vj is called the arc head, the vertex V1 is adjacent to the vertex V2, and the vertex V2 is adjacent to the vertex V1. Taking vertex V as the number of head arcs is called the in-degree of V, denoted as ID(V), and the number of tail arcs at V is called the out-degree of V, denoted as OD(V), so the degree of vertex V is TD(V )=ID(V)+OD(V). A is in degree 2, out degree 1, and A's degree is 3.

G2是一个有向图,G2={V2,E2}
V2={A,B,C,D}
E2={<B,A>,<B,C>,<C,A>,<A,D>}

4. Sparse graph and dense graph: It is generally considered that the graph with the number of edges or arcs less than n*logn (n is the number of vertices) is called a sparse graph, otherwise it is called a dense graph. The edges or arcs of some graphs have numbers associated with them. Such numbers associated with the edges or arcs of the graph are called weights, and graphs with weights are usually called nets.

5. Connected graph: In an undirected graph G, if there is a path from vertex V1 to vertex V2, then V1 and V2 are connected, and if any two vertices Vi and Vj in the graph are connected, then G is called is a connected graph. In a directed graph G, if there is a path for every pair Vi to Vj, then G is said to be strongly connected.

6. Adjacency matrix: For undirected graphs, two arrays are used to represent the graph. A one-dimensional array stores vertex information in the graph, and a two-dimensional array (called an adjacency matrix) stores information about edges or arcs in the graph. . Determine whether any two vertices have edges and no edges; to know the degree of a vertex, it is actually the sum of the elements in the i-th row (or i-th column) of the vertex Vi in the adjacency matrix; to find all the adjacent points of the vertex Vi is to convert the matrix The element in the i-th row is scanned once, and arc[i][j] is 1, which is the adjacent point.

#define MAXVEX 100      // 最大顶点数
#define INFINITY 65535  // 用65535来代表无穷大
typedef struct {
  char vexs[MAXVEX];          // 顶点表
  int arc[MAXVEX][MAXVEX];    // 邻接矩阵
  int numVertexes, numEdges;  // 图中当前的顶点数和边数
} MGraph;

// 建立无向网图的邻接矩阵
void CreateMGraph(MGraph* G) {
  int i, j, k, w;
  printf("请输入顶点数和边数:\n");
  scanf("%d %d", &G->numVertexes, &G->numEdges);
  for (i = 0; i < G->numVertexes; i++) scanf("%c", &G->vexs[i]);
  for (i = 0; i < G->numVertexes; i++)
    for (j = 0; j < G->numVertexes; j++)
      G->arc[i][j] = INFINITY;  // 邻接矩阵初始化
  for (k = 0; k < G->numEdges; k++) {
    printf("请输入边(Vi,Vj)上的下标i,下标j和对应的权w:\n");
    scanf("%d %d %d", &i, &j, &w);
    G->arc[i][j] = w;
    G->arc[j][i] = G->arc[i][j];  // 是无向网图,对称矩阵
  }
}

7. Adjacency list: The vertices in the graph are stored in a one-dimensional array, and all the adjacent points of each vertex Vi in the graph form a linear table. Since the number of adjacent points is uncertain, a singly linked list is chosen to be stored.

#define MAXVEX 100
typedef struct EdgeNode			// 边表结点
{
         int adjvex;					// 邻接点域,存储该顶点对应的下标
         int weight;					// 用于存储权值,对于非网图可以不需要
         struct EdgeNode *next;		// 链域,指向下一个邻接点
} EdgeNode;

typedef struct VertexNode		// 顶点表结点
{
         char data;					// 顶点域,存储顶点信息
          EdgeNode *firstEdge;		// 边表头指针
} VertexNode, AdjList[MAXVEX];

typedef struct
{
         AdjList adjList;
         int numVertexes, numEdges;	// 图中当前顶点数和边数
} GraphAdjList;

// 建立图的邻接表结构
void CreateALGraph(GraphAdjList *G)
{
	int i, j, k;
	EdgeNode *e;
	printf("请输入顶点数和边数:\n");
	scanf("%d %d", &G->numVertexes, &G->numEdges);
	
	// 读取顶点信息,建立顶点表
	for( i=0; i < G->numVertexes; i++ )
	{
	         scanf("%c", &G->adjList[i].data);
	         G->adjList[i].firstEdge = NULL;		// 初始化置为空表
	}
	for( k=0; k < G->numEdges; k++ )
	{
		printf("请输入边(Vi,Vj)上的顶点序号:\n");
		scanf("%d %d", &i, &j);
		
		e = (EdgeNode *)malloc(sizeof(EdgeNode));
		e->adjvex = j;						// 邻接序号为j
		e->next = G->adjList[i].firstEdge;
		G->adjList[i].firstEdge = e;
		
		e = (EdgeNode *)malloc(sizeof(EdgeNode));
		e->adjvex = i;						// 邻接序号为i
		e->next = G->adjList[j].firstEdge;
		G->adjList[j].firstEdge = e;
	}
}

8. Adjacency list (net): For a network graph with weights, you can add another data field to the node definition of the edge table to store the weights

 9. Edge set array: composed of two one-dimensional arrays, one is to store vertex information, and the other is to store edge information. Each data element of this edge array is composed of the start subscript, end subscript and weight of an edge.

 10. Depth-first traversal: DFS, first search a room thoroughly before starting another room search.

#define TRUE 1
#define FALSE 0
#define MAX 256
typedef int Boolean;  // 这里我们定义Boolean为布尔类型,其值为TRUE或FALSE
Boolean visited[MAX];  // 访问标志的数组
void DFS(MGraph G, int i) {
  int j;
  visited[j] = TRUE;         // 访问过的顶点设置为TRUE
  printf("%c ", G.vexs[i]);  // 打印顶点
  for (j = 0; j < G.numVertexes; j++)
    if (G.arc[i][j] == 1 && !visited[j])
      DFS(G, j);  // 对为访问的邻接顶点递归调用
}

// 邻接矩阵的深度遍历操作
void DFSTraverse(MGraph G) {
  int i;
  for (i = 0; i < G.numVertexes; i++)
    visited[i] = FALSE;  // 初始化所有顶点状态都是未访问过状态
  for (i = 0; i < G.numVertexes; i++)
    if (!visited[i]) DFS(G, i);  // 若是连通图,只会执行一次
}

11. Breadth-first traversal: BFS, a method of gradually expanding the search range, using queues to achieve

// 邻接矩阵的广度遍历算法
void BFSTraverse(MGraph G)
{
	int i, j;
	Queue Q;
	for( i=0; i < G.numVertexes; i++ ) visited[i] = FALSE;
	initQueue( &Q );
	for( i=0; i < G.numVertexes; i++ )
	{
		if( !visited[i] )
		{
			printf("%c ", G.vex[i]);
			visited[i] = TRUE;
			EnQueue(&Q, i);
			while( !QueueEmpty(Q) )
			{
				DeQueue(&Q, &i);
				for( j=0; j < G.numVertexes; j++ )
				{
					if( G.art[i][j]==1 && !visited[j] )
					{
						printf("%c ", G.vex[j]);
						visited[j] = TRUE;
						EnQueue(&Q, j);
					}
				}
			}
		}
	}
}

12. Minimum Spanning Tree (Primm's Algorithm)

Taking a vertex as the starting point, gradually find the edge with the smallest weight on each vertex to construct the minimum spanning tree.

// Prim算法生成最小生成树
void MiniSpanTree_Prim(MGraph G)
{
	int min, i, j, k;
	int adjvex[MAXVEX];	// 保存相关顶点下标
	int lowcost[MAXVEX];	// 保存相关顶点间边的权值
	lowcost[0] = 0;			// V0作为最小生成树的根开始遍历,权值为0
	adjvex[0] = 0;			// V0第一个加入
	
	// 初始化操作
	for( i=1; i < G.numVertexes; i++ )
	{
		lowcost[i] = G.arc[0][i];	// 将邻接矩阵第0行所有权值先加入数组
		adjvex[i] = 0;		// 初始化全部先为V0的下标
	}
	
	// 真正构造最小生成树的过程
	for( i=1; i < G.numVertexes; i++ )
	{
		min = INFINITY;		// 初始化最小权值为65535等不可能数值
		j = 1;
		k = 0;
		
		// 遍历全部顶点
		while( j < G.numVertexes )
		{
			// 找出lowcost数组已存储的最小权值
			if( lowcost[j]!=0 && lowcost[j] < min )
			{
				min = lowcost[j];
				k = j;		// 将发现的最小权值的下标存入k,以待使用。
			}
			j++;
		}
		
		// 打印当前顶点边中权值最小的边
		printf("(%d,%d)", adjvex[k], k);
		lowcost[k] = 0;		// 将当前顶点的权值设置为0,表示此顶点已经完成任务,进行下一个顶点的遍历
		
		// 邻接矩阵k行逐个遍历全部顶点
		for( j=1; j < G.numVertexes; j++ )
		{
			if( lowcost[j]!=0 && G.arc[k][j] < lowcost[j] )
			{
				lowcost[j] = G.arc[k][j];
				adjvex[j] = k;	
			}
		}
	}
}

13. Minimum spanning tree (Kruskal algorithm)

Starting from the edge, the weight is on the edge, and it is a natural idea to directly find the edge with the smallest weight to construct a spanning tree.

int Find(int* parent, int f) {
  while (parent[f] > 0) f = parent[f];
  return f;
}
// Kruskal算法生成最小生成树
void MiniSpanTree_Kruskal(MGraph G) {
  int i, n, m;
  Edge edges[MAGEDGE];  // 定义边集数组
  int parent[MAXVEX];  // 定义parent数组用来判断边与边是否形成环路
  for (i = 0; i < G.numVertexes; i++) parent[i] = 0;
  for (i = 0; i < G.numEdges; i++) {
    n = Find(parent, edges[i].begin);  // 4 2 0 1 5 3 8 6 6 6 7
    m = Find(parent, edges[i].end);    // 7 8 1 5 8 7 6 6 6 7 7
    if (n != m)  // 如果n==m,则形成环路,不满足!
    {
      parent[n] =
          m;  // 将此边的结尾顶点放入下标为起点的parent数组中,表示此顶点已经在生成树集合中
      printf("(%d, %d) %d ", edges[i].begin, edges[i].end, edges[i].weight);
    }
  }
}

14. Shortest path (Dijkstra's algorithm)

A net graph is a path with the least sum of weights on the edges traversed by two vertices.

A non-mesh graph is a path between two vertices that traverses the least number of edges.

#define MAXVEX	9
#define	INFINITY	65535
typedef int    Patharc[MAXVEX];		// 用于存储最短路径下标的数组
typedef int    ShortPathTable[MAXVEX];	// 用于存储到各点最短路径的权值和
void ShortestPath_Dijkstar(MGraph G, int V0, Patharc *P, ShortPathTable *D)
{
	int v, w, k, min;
	int final[MAXVEX];		// final[w] = 1 表示已经求得顶点V0到Vw的最短路径
	// 初始化数据
	for( v=0; v < G.numVertexes; v++ )
	{
		final[v] = 0;			// 全部顶点初始化为未找到最短路径
		(*D)[V] = G.arc[V0][v];		// 将与V0点有连线的顶点加上权值
		(*P)[V] = 0;			// 初始化路径数组P为0
	}
	(*D)[V0] = 0;		// V0至V0的路径为0
	final[V0] = 1;		// V0至V0不需要求路径
	// 开始主循环,每次求得V0到某个V顶点的最短路径
	for( v=1; v < G.numVertexes; v++ )
	{
		min = INFINITY;
		for( w=0; w < G.numVertexes; w++ )
		{
			if( !final[w] && (*D)[w]<min )
			{
				k = w;
				min = (*D)[w];
			}
		}
		final[k] = 1;	// 将目前找到的最近的顶点置1
		// 修正当前最短路径及距离
		for( w=0; w < G.numVextexes; w++ )
		{
			// 如果经过v顶点的路径比现在这条路径的长度短的话,更新!
			if( !final[w] && (min+G.arc[k][w] < (*D)[w]) )
			{
				(*D)[w] = min + G.arc[k][w];	// 修改当前路径长度
				(*p)[w] = k;			// 存放前驱顶点
			}
		}
	}
}

15. Shortest Path (Freud’s Algorithm)

Dijkstra's algorithm is the shortest path from one vertex to all vertices, but Freud's algorithm is to find the shortest path from all vertices to all vertices.

#define MAXVEX 9
#define INFINITY 65535
typedef int Pathmatirx[MAXVEX][MAXVEX];
typedef int ShortPathTable[MAXVEX][MAXVEX];
void ShortestPath_Floyd(MGraph G, Pathmatirx* P, ShortPathTable* D) {
  int v, w, k;
  // 初始化D和P
  for (v = 0; v < G.numVertexes; v++)
    for (w = 0; w < G.numVertexes; w++) {
      (*D)[v][w] = G.matirx[v][w];
      (*P)[v][w] = w;
    }
  // 优美的弗洛伊德算法
  for (k = 0; k < G.numVertexes; k++)
    for (v = 0; v < G.numVertexes; v++)
      for (w = 0; w < G.numVertexes; w++)
        if ((*D)[v][w] > (*D)[v][k] + (*D)[k][w]) {
          (*D)[v][w] = (*D)[v][k] + (*D)[k][w];
          (*P)[v][w] = (*P)[v][k];  
        }
}

16. Topological sort

An acyclic graph with phases is called an acyclic graph.

Topological sequence: Let G=(V, E) be a directed graph with n vertices, the vertex sequence V1, V2, ..., Vn in V satisfies that if there is a path from vertex Vi to Vj, then in the vertex sequence Vertex Vi must precede vertex Vj. We call such a vertex sequence a topological sequence.

Topological sorting: The so-called topological sorting is actually the process of constructing a topological sequence for a directed graph.

Topological sorting algorithm: select a vertex with no predecessor from the AOV net (the in-degree of the vertex is 0) and output it; delete the vertex from the net, and delete all directed edges from the vertex; repeat the above Two steps until there are no more vertices without predecessors in the remaining net.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324244992&siteId=291194637