Definition and storage structure of graphs

Source: Internet
Author: User
Tags in degrees

Learning Objectives and applications: navigation, GPS, network planning, Path planningTraffic flow can be modeled with a graph, each street intersection represents a vertex, and each street is an edge. The value of the edge may represent a throttling speed, or capacity (number of lanes), and so on. At this point we may need to find a shortest path, or use this information to find out where the traffic bottlenecks are most likely to occur,
definition of diagram:is made up of verticeshave a poor non-empty collectionand between verticesthe collection of edgesform a data structure representation method: Graph = (v,e) V = {x | x belongs to a data object} is a vertex with a poor non-empty set E = {(x, y) | (x, y) belongs to V}, with a poor set of relationships between vertices, also called edge sets
Vertex: The data element in the diagram
the definition of a non-direction graph and a forward graph:? No graph: The edges between any two vertices are non-forward edges.no edges: edges between vertices A and b do not have a direction, which is said to be a non-directional edge (A, B)
The direction graph: The edges between any two vertices in the graph are forward edges, also known as Arcsdirected Edge: The edge between vertices A and B has a direction, which is said to have a forward edge < B, a> definition of the degree:The degree of vertex v is the number of edges associated with V, which is recorded as TD (V).?In: The number of sides with the Head V as the ID (v)?The number of edges with a tail of V, as OD (v)
Some formulas for degrees: TD (v) = ID (v) + OD (v)
E = [TD (V1) + TD (V2) + ...]/2E = ID (v1) + ID (v2) + ...//Enter the sum
E = OD (v1) + OD (v2) + ...//out of the sum

definition of Rights:The numbers associated with the edges of the graph are called weights.?Weights are commonly used to denote distances or costs between vertices in a graph.
Some operations of the diagram:
/* Create and return a graph structure of n vertices */graph* graph_creat (int n);/* Destroy diagram Structure */void Graph_destroy (graph* graph);/* Clear diagram structure */void graph_clear ( graph* graph);/* Increases the weight of W */int graph_add_edge (graph* graph, int v1, int v2, int w) between vertices v1 and v2 of the graph;/* Delete vertices v1 and v2 edges, return weights */int Graph_remove_edge (graph* Graph, int v1, int v2);/* Gets the weight of the edge between the vertex v1 and v2 */int graph_get_edge (graph* graph,int v1, int v2);/* Returns the degree of the vertex v */int graph_td (graph* graph, int v);/* Returns the number of vertices of the graph */int graph_vertex_count (graph* graph);/* Returns the number of edges of vertices in the graph */int graph_ Edge_count (graph* Graph);

storage structure of graphs
I. adjacency Matrix methodBasic idea: Using two arrays to represent a one-dimensional array storing vertex information in a two-dimensional array the information of the Edge (ARC) in the storage graph A = (V, E) is a graph with n vertices, and the adjacency matrix of the graph is arc[n][n], defined as:
about the head node of the adjacency matrix:? Record the number of vertices?Record the data description associated with a vertex?Record a two-dimensional array describing the edge set
typedef struct {    int count;    m_vertex** v;    int** Matrix;} Tm_graph;

Actions implemented:
#include <stdio.h> #include <malloc.h> #include "graph.h"/* head node structure */typedef struct {int count; m_vertex** v; A pointer area that points to n types (M_vertex *). The pointer to this area points to the memory of the record node information int** matrix; Tm_graph; mgraph* Graph_creat (m_vertex** v, int n) {tm_graph* ret = null;if ((v! = NULL) && (n > 0)) {ret = (tm_graph*) Mallo C (sizeof (tm_graph)), if (ret! = NULL) {int i = 0;int *p = Null;ret->count = N;ret->v = (m_vertex**) malloc (sizeof (m_ve Rtex *) *n);/* Apply one-dimensional address space */ret->matrix = (int**) malloc (sizeof (int*) * n);/* Apply a one-dimensional data space, use Calloc to empty the adjacency matrix, initialize to 0*///p = ( int*) malloc (sizeof (int) * n * N);p = (int *) calloc (n * n, sizeof (int)); if ((ret->v! = NULL) && (Ret->matrix ! = null) && (P! = null)) {for (i=0; i < n; i++) {/* save pointer to vertex data */ret->v[i] = v[i];/* Connect data space to address space */ret->matr Ix[i] = (p + i * n);}} Else{free (RET-&GT;V); free (Ret->matrix); free (P);}}} return ret;} void Graph_destroy (mgraph* graph) {tm_graph* t_graph = (tm_graph*) graph;if (t_graph! = NULL) {free (T_GRAPH-&GT;V)*/* NOTE: The following two steps can not be released in the order of */free (t_graph->matrix[0]); t_graph->matrix; (t_graph); }}/* empty diagram structure */void Graph_clear (mgraph* graph) {tm_graph* t_graph = (tm_graph*) graph;if (t_graph! = NULL) {int i = 0;int J = 0;f or (i=0; i < t_graph->count; i++) {for (j=0; J < t_graph->count; J + +) {T_graph->matrix[i][j] = 0;}}}}  /* Add an edge */int Graph_add_edge (mgraph* graph, int v1, int v2, int w) {tm_graph* t_graph = (tm_graph*) graph;int) between vertices v1 and v2 of the graph  ret = 0;ret = (t_graph! = NULL) && (v1 >= 0) && (v1 < t_graph->count); ret = (ret) && (v1 >= 0) && (v1 < t_graph->count); ret = (ret) && (w >= 0); if (ret) {T_graph->matrix[v1][v2] = W ;} return ret;} /* Delete vertices v1 and v2 edges, return weights */int graph_remove_edge (mgraph* graph, int v1, int v2) {tm_graph* t_graph = (tm_graph*) graph;int ret = 0; RET = (t_graph! = NULL) && (v1 > 0) && (v1 < t_graph->count); ret = (ret) && (v1 > 0) & amp;& (V1 < T_graph->count); if (ret) {ret = t_GRAPH-&GT;MATRIX[V1][V2];T_GRAPH-&GT;MATRIX[V1][V2] = 0;}}  /* Get the weight of the edge between vertex v1 and v2 */int graph_get_edge (mgraph* graph,int v1, int v2) {tm_graph* t_graph = (tm_graph*) graph;int ret = 0;ret = (T_graph! = NULL) && (v1 > 0) && (v1 < t_graph->count); ret = (ret) && (v1 > 0) && Amp (V1 < T_graph->count); if (ret) {ret = t_graph->matrix[v1][v2];} return ret;}  /* Returns the degree of the vertex v */int graph_td (mgraph* graph, int v) {tm_graph* t_graph = (tm_graph*) graph;int ret = 0;if (t_graph! = NULL) {int i = 0;/* out degree */for (i=0; i<t_graph->count; i++) {if (t_graph->matrix[v][i]! = 0) {ret++;}} /* Enter degrees */for (i=0; i<t_graph->count; i++) {if (t_graph->matrix[i][v]! = 0) {ret++;}}} return ret;} /* Returns the number of vertices of the graph */int graph_vertex_count (mgraph* graph) {tm_graph* t_graph = (tm_graph*) graph;int ret = 0;if (t_graph! = NULL) { ret = T_graph->count;}} /* Returns the number of edges of vertices in the graph */int graph_edge_count (mgraph* graph) {tm_graph* t_graph = (tm_graph*) graph;int ret = 0;if (t_graph! = NULL) { int i = 0;int j = 0;for (i=0; i < t_graph->count; i++) {for (j=0; J < t_graph->count; J + +) {if (t_graph->matrix[i][j]! = 0) {ret++;}}} return ret;} void Graph_display (mgraph* graph, graph_printf* p_func) {tm_graph* t_graph = (tm_graph*) graph;int ret = 0;if ((t_graph! = NU LL) && (p_func! = NULL)) {int i = 0;int j = 0;/* Print node */for (i=0; i<t_graph->count; i++) {printf ("%d", i);p rintf (",");p _func (T_graph->v[i]);p rintf (""); /* Print Edge */for (i=0; i<t_graph->count; i++) {for (j=0; j<t_graph->count; J + +) {if (t_graph->matrix[i][j]! = 0) {printf ("<");p _func (T_graph->v[i]);p rintf (",");p _func (T_graph->v[j]);p rintf (",");p rintf ("%d", t_graph- &GT;MATRIX[I][J]);p rintf (">");p rintf ("");}}}}



Cons: For graphs with fewer edges relative to vertices, there is considerable waste of storage space.
second, adjacent linked list method(Avoiding the waste of space) The basic idea:? Edge links from the same vertex in the same linked list?Each linked table node represents an edge, and the subscript and weight of the other vertex that holds the edge in the node.

The head node of the adjacency list? Record the number of vertices
? Record the data description associated with the vertex ? Record a list of linked lists that describe the edge set
typedef struct {int count;    l_vertex** v; linklist** LA;}actions implemented:
#include <stdio.h> #include <malloc.h> #include "LinkList.h" #include "l_graph.h" typedef void lgraph;    typedef void L_VERTEX;TYPEDEF struct {int count;    l_vertex** v; linklist** LA;} tl_graph;typedef struct {linklistnode header;int v;int W;}  t_list_node;/* Create and return a graph structure of n vertices */lgraph* graph_creat (l_vertex** v, int n)//o (n) {tl_graph* ret = null;int OK = 1;if ((v! = NULL) && (n > 0)) {ret = (tl_graph*) malloc (sizeof (tl_graph)); if (ret! = NULL) {Ret->count = N;ret->v = (l_verte x**) calloc (n, sizeof (l_vertex*)), Ret->la = (linklist**) calloc (n, sizeof (linklist*)); OK = (ret->v! = NULL) && Amp (Ret->la! = NULL); if (OK) {int i = 0;for (i=0; i<n; i++) {ret->v[i] = v[i];} /* Note here the monitoring */for to create a linked list return value (i=0; (i<n) && OK; i++) {ok = OK && ((ret->la[i] = linklist_create ()) = NULL);}} /* Unsuccessful for each of the two cases 1, the space of the node data pointer, or the space of the pointer array that stores the linked list pointer did not apply successfully 2, the creation of the linked list was unsuccessful */if (!ok) {if (Ret->la! = NULL) {int i=0;for (i=0; i<n; i++) {Linklist_destroy (ret->la[i]);}} Free (ret->la); fRee (RET-&GT;V); free (ret); ret = NULL;} }}return ret;}  /* Destroy diagram Structure */void Graph_destroy (lgraph* graph)//o (n) {tl_graph* t_graph = (tl_graph*) graph;if (t_graph! = NULL) {int i = 0; for (i=0; i<t_graph->count; i++) {Linklist_destroy (t_graph->la[i]);} Free (T_graph->la), free (t_graph->v), free (t_graph);}} /* Empty graph structure */void Graph_clear (lgraph* graph) {tl_graph* t_graph = (tl_graph*) graph;if (t_graph! = NULL) {int i = 0; int j = 0;f or (i=0; i<t_graph->count; i++) {for (j=0; J<linklist_length (T_graph->la[i]); j + +) {free (Linklist_delete (t _graph->la[i], 0));}}} /* Add an edge */int Graph_add_edge (lgraph* graph, int v1, int v2, int w)//o (1) {tl_graph* t_graph = (tl_graph*) gra between vertices v1 and v2 of the graph ph;t_list_node* node = null;int ret = 0;ret = (t_graph! = NULL); ret = (ret) && (0 <= v1) && (V1 < T_  Graph->count); ret = (ret) && (0 <= v2) && (V2 < t_graph->count); ret = (ret) && (0 < W); ret = (ret) && (node = (t_list_node*) malloc (sizeof (t_list_node)); if (ret) {node->v = V2;node->w = W; Linklist_insert (T_graph->la[v1], (linklistnode*) node, 0); } return ret;} /* Delete vertices v1 and v2 edges, return weights */int graph_remove_edge (lgraph* graph, int v1, int v2)//o (n*n) {tl_graph* t_graph = (tl_graph*) graph;  int ret = 0;ret = (t_graph! = NULL); ret = (ret) && (0 <= v1) && (v1 < t_graph->count); ret = (ret) && (0 <= v2) && (V2 < T_graph->count); if (ret) {int i = 0;t_list_node* node = null;for (i=0; i<l Inklist_length (T_graph->la[v1]); i++) {node = (t_list_node*) linklist_get (T_graph->la[v1], i); if (node->v = = v2) {ret = node->w; Linklist_delete (T_graph->la[v1], i); free (node); break;}}} return ret;} /* Get the weight of the edge between vertex v1 and v2 */int graph_get_edge (lgraph* graph,int v1, int v2)//o (n*n) {tl_graph* t_graph = (tl_graph*) graph;int ret = 0;ret = (t_graph! = NULL); ret = (ret) && (0 <= v1) && (v1 < t_graph->count); ret = (ret) &am p;& (0 <= v2) && (V2 < T_graph->count); if (ret) {int i = 0;t_list_node* node = null;for (i=0; I<linklist_length (T_graph->la[v1]); i++) {node = (t_list_node*) LinkList _get (T_graph->la[v1], i); if (node->v = = v2) {ret = Node->w;break;}}}} /* Returns the degree of vertex v */int graph_td (lgraph* graph, int v)//o (n*n*n) {tl_graph* t_graph = (tl_graph*) graph;int ret = 0; if ((T_graph! = N ULL) && (0 <= v) && (v < t_graph->count)) {int i = 0;int J = 0;t_list_node* node = null;/* in degrees */for ( i=0; I < t_graph->count; i++) {for (j=0; j < Linklist_length (T_graph->la[i]); j + +) {node = (t_list_node*) linklist_get (T_graph->la[i], J) if (node->v = = v) {ret++;}}} /* Out of */for (i=0; i < Linklist_length (T_graph->la[v]); i++) {ret++;}} return ret;} /* Returns the number of vertices of the graph */int graph_vertex_count (lgraph* graph)//o (1) {tl_graph* t_graph = (tl_graph*) graph;int ret = 0; if (t_graph! = NULL) {ret = T_graph->count;} return ret;} /* Returns the number of sides of the graph */int graph_edge_count (lgraph* graph)//o (n) {tl_graph* t_graph = (tl_graph*) graph;int ret = 0;if (t_graph! = NULL) {int i = 0;inT j = 0;for (i=0; i < t_graph->count; i++) {ret + = Linklist_length (T_graph->la[i]);}} return ret;} void Graph_display (lgraph* graph, graph_printf* p_func)//o (n*n*n) {tl_graph* t_graph = (tl_graph*) graph;int ret = 0;if ((t _graph = null) && (P_func! = null)) {int i = 0;int J = 0;t_list_node* node = null;/* Print node */for (i=0; i<t_graph-& Gt;count; i++) {printf ("%d", i);p rintf (",");p _func (T_graph->v[i]);p rintf ("");} printf ("\ n");/* Print Edge */for (i=0; i<t_graph->count; i++) {for (j=0; J<linklist_length (T_graph->la[i]); j + +) { node = (t_list_node*) linklist_get (T_graph->la[i], j);p rintf ("<");p _func (T_graph->v[i]);p rintf (",");p _ Func (T_graph->v[node->v]);p rintf (",");p rintf ("%d", node->w);p rintf (">");p rintf ("");} printf ("\ n");}}



Although the Adjacency table method solves the problem of space wasting, some functions have increased time complexity. Equivalent to the use of time to convert space. The storage structure of the above two graphs can be selected according to the characteristics of the project.
Note:When requesting space for a linked list of vertices, be careful to check that the requested space is successful. If the Benking of a vertex does not apply successfully, the creation of the graph is unsuccessful, and the time-complexity analysis is needed to release the list of the application.
There are other ways to store the diagram: for example,Cross linked list (in fact, the cross-linked list is the adjacency linked list (easy to calculate the degree) and the inverse of the linked list (easy to statistics) combined): adjacency Multiple tables:array of Edge sets(two one-dimensional arrays, one storage vertex information, one storage edge information)



C language Knowledge Supplement:
1, two-dimensional array implementation principle

Two-dimensional arrays in memory in a one-dimensional arrangement of the first dimension of the two-dimensional array is a one-dimensional array of two-dimensional array of the second Vicay is the specific value of the two-dimensional array of array name can be seen as a constant pointer to a one-dimensional array int a[5], the array name a represents the first element of the array address,the type of a is int *;The same two-dimensional array name also represents the address of the first element of the array, and for int m[2][5],the type of the array name M is int (*) [5]2. Traverse the two-dimensional array in pointer mode A[I][J]  Parsing A[i] As an array name, accessed as a pointer subscript, can be expressed as* (A[i] + j), and then the A[i] is expanded, i.e.* (* (A + i) + j); implementation code: #include <stdio.h>
int main (int argc, char* argv[], char* env[]) {int a[3][3] = {{0, 1, 2}, {3, 4, 5}, {6, 7, 8}};    int i = 0;       int j = 0; For (i=0, i<3; i++) {for (j=0; j<3; J + +) {printf ("%d\n", * (* (a+i) + j));}    }}3, dynamic application of two-dimensional arrayThe two-dimensional array is also stored in memory in the linear way, thinking: How to dynamically create a two-dimensional array based on the number of vertices? ?Dynamic application of a one-dimensional array with level two pointers ?Request data space with a first-level pointer ?To connect a pointer in a one-dimensional pointer array to a data space


a summary of multidimensional arrays and multidimensional pointers:C inonly one-dimensional arrays, and the size of the array must be determined at compile time as a constant in C.an array element can be any type of data, that is, the element of the array can be another array Conly the size of the array and the address of the first element is the compiler directly determinesOf4. Use Calloc to apply for dynamic spaceCalloc prototype: void *calloc (size_t num_elements, size_t element_size);parameter Description:Num_elements: The number of required elements
Element_size: The number of bytes per element
Difference from malloc: calloc initializes it to 0 before returning a pointer to memory, and there is a different way of requesting the amount of memory.


Definition and storage structure of graphs

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.