Data structure (Glossary, storage structure, and traversal)

Source: Internet
Author: User
1. Related Terms

Vertex, arc, arc header (initial point), arc tail (end point), edge, directed graph, undigraph), complete graph, directed graph, sparse graph, dense graph, weight, Network), undirected network, Directed Network, subgraph, adjacent, degree, indegree, outdegree, and Path), loop, simple path, simple loop, connected graph, and connected component), strongly connected graph, strongly connected component (extremely large strongly connected subgraph in a directed graph), spanning tree, extremely small connected subgraph, and directed tree.

Undirected graph: g = (V, {e}), 0 ≤ edge ≤ n (n-1)/2

Directed Graph: g = (V, {A}), 0 ≤ arc ≤ n (n-1)

Connected Graph: In an undirected graph G, if two vertices, VI, and vj, are connected, then graph G is connected.

Connected Component: A maximum connected subgraph in an undirected graph

Legend:


Strongly Connected Graph: In directed graph G, if each pair of vertex VI and vj belong to V and VI is not equal to vj, and there are paths from VI to vj and from VJ to VI, graph G is a connected graph.

Strongly Connected Component: extremely large strongly connected subgraph of a directed graph.


Spanning Tree: The spanning tree of a connected graph is a very small connected subgraph. It contains all vertices in the graph, but only has n-1 edges that constitute a tree.

If an edge is added to the generation tree, it must constitute a ring: Because this edge makes the two vertices that it is attached to have a second path between them.

A spanning tree with n vertices has only n-1 edges. Assume that a graph has n and vertices and edges smaller than n-1, then it is a non-connected graph. Assume that there are n-1 extra edges, then there must be loops. However, a graph with n-1 edges is not necessarily a spanning tree.

2. Storage Structure 2.1 (array representation)

(Undirected graph, directed graph, undirected network, and directed Network)

Two arrays are used to represent graphs. A one-dimensional array stores the information of data elements (vertices) in the graph, and a two-dimensional array (Adjacent matrix) stores the relationship (edge or arc) between data elements in the graph.

IfGraph G is an undirected graphWith n vertices, the adjacent matrix is a matrix of N * n, which is defined:


Is an undirected graph:


As shown above, the edge array of an undirected graph is a symmetric matrix. The so-called symmetric matrix is that the element of the N-level matrix satisfies AIJ = Aji. That is, from the upper left corner of the Matrix to the lower right corner of the main diagonal line is the axis, the upper right corner and the lower left corner of the corresponding elements are all equal.
It is easy to know the information in the graph from this matrix.
(1) It is very easy to infer whether two random vertices have boundless edges;
(2) to calculate the degree of a vertex, it is actually the sum of the elements of the vertex VI in the I row or (I column) of the adjacent matrix;
(3) Finding All adjacent points of vertex VI is to scan the elements in line I in the matrix. The VJ of arc [I] [J] = 1 is the adjacent point;
A directed graph has two types of values: Inbound and Outbound. The inbound degree of vertex VI is the sum of the numbers in column I, and the outbound degree of vertex VI is the sum of the numbers in row I.

IfFigure G is a network chartWith n vertices, the adjacent matrix is a matrix of N * n, which is defined:


Wij indicates (Vi, vj) or <VI, VJ>. An infinite number indicates the value agreed by a computer that is greater than the value of all edge values, that is, an impossible limit value. Is a directed graph and Its Adjacent matrix:

Note: The diagonal line of this edge array (Adjacent matrix) should be infinite.

We can see that:

(1) line I has a weight greater than 0, less than an infinite number, and is the outdegree of vertex VI (OD (VI ));

(2) The sum of column J weights greater than 0 and smaller than the infinite number and the entry level of vertex VJ (ID (VJ ));

(3) The sum of the weights of row I and column I is greater than 0 and smaller than the infinite number, that is, the degree of vertex VI (TD (vi) = OD (VI) + ID (VJ )).


The following figure shows the proportion of the code used to store the graph and create the graph using the adjacent matrix:

Typedef char vertextype; // The vertex type. You can customize the typedef int edgetype. // The weight type on the edge. The value type is customized by the user. # define max_vex 20 // The maximum number of vertices, defined by the user # defineinfinity 65535 // represents an infinite typedef struct {vertextype vexs [max_vex]; // vertex array edgetype arc [max_vex] [max_vex]; // adjacent matrix int vexnum, arcnum; // current number of points and number of arcs in the graph} graph;

// Locate the subscript position of vertex v in the vertex array. the return value is-1int locatevex (graph * g, vertextype v) {int I = 0; for (I = 0; I <G-> vexnum; I ++) {If (G-> vexs [I] = V) break;} if (I> G-> vexnum) {fprintf (stderr, "No such vertex. \ n "); Return-1;} return I;} // uses the adjacent matrix representation to construct a/undirected network gvoid createudn (graph * g) {int I, J; edgetype W; printf ("Number of input vertices and edges: \ n"); scanf ("% d, % d", & (g-> vexnum ), & (g-> arcnum); // input vertex for (I = 0; I <G-> vexnum; I ++) {printf ("vertex % d :", I + 1); G-> V Exs [I] = getchar (); While (G-> vexs [I] = '\ n') {G-> vexs [I] = getchar ();}} getchar (); // initialize the adjacent matrix for (I = 0; I <G-> arcnum; I ++) {for (j = 0; j <G-> arcnum; j ++) {G-> arc [I] [J] = infinity ;}} printf ("input edge (Vi, vj) vertex vi vj and weight w \ n "); for (I = 0; I <G-> arcnum; I ++) {char V1, V2; // V1 = getchar (); // while (V1 = '\ n') // {// V1 = getchar (); ///} // v2 = getchar (); // while (V2 = '\ n') // {// v2 = getchar (); /// scanf ("% d", & W); s CANF ("% C % d", & V1, & V2, & W); getchar (); int M = locatevex (G, V1 ); int n = locatevex (G, V2); If (M =-1 | n =-1) {fprintf (stderr, "No This vertex! \ N "); return;} G-> arc [m] [N] = W; # If 0g-> arc [N] [m] = G-> arc [m] [N]; // undirected graph's Adjacent matrix symmetry # endif} void printgrapth (graph * g) {for (INT I = 0; I <G-> vexnum; I ++) {for (Int J = 0; j <G-> vexnum; j ++) {printf ("% 6D", G-> arc [I] [J]);} putchar ('\ n ');}}

int main(){Graph g;CreateUDN(&g);PrintGrapth(&g);return 0;}

Create a directed network diagram in the previous section. The sample code is as follows:

Create an undirected network chart and run the following command:


Create an undirected network graph with n vertices and e edges. the time complexity is O (n + N ^ 2 + E·N) = O (N ^ 2 + E·N), where the first n is the input n vertices, the initialization of the adjacent matrix consumes O (N ^ 2) time; for each edge, it takes O (n) to locate the subscript of two vertices, so it is O (E·N ).

2.2 When the number of edges is smaller than the number of vertices in an adjacent table, the structure of the adjacent matrix will cause a great waste of storage space. The adjacency list is a chained storage structure of graphs. It is a combination of arrays and linked lists to store graphs. The Processing Method of the adjacent table is as follows:
(1) vertices in the graph are stored in a one-dimensional array. Of course, the vertex can be stored with a single-chain table, but the array can easily read the vertex information, which is more convenient.
(2) In the graph, all the neighboring points of each vertex VI form a linear table. Because the number of adjacent points is not fixed, a single-chain table is used for storage. an undirected graph is called the edge table of vertex VI, and a directed graph is called the vertex VI as the output edge table of the arc tail.
For example, it is the structure of an undirected graph adjacent table.
We can see that, Vertex tableEach node of the table is represented by data and firstedge. Data is a data domain and stores vertex information. firstedge is a pointer domain that points to the first node of the edge table, that is, the first adjacent point of the vertex. Edge table nodes are composed of adjvex and next. adjvex is the adjacent vertex domain, which stores the subscript of the adjacent vertex of a vertex in the vertex table. Next stores the pointer pointing to the next node in the edge table. For Network DiagramYou can add a weight data field in the edge table node definition to store the weight information. For example, see.

The following figure shows the code proportions of creating a network chart using an adjacent table:

Typedef char vertextype; // The vertex type. You can customize the typedef int edgetype. // The weight type on the edge. The value type is customized by the user. # define max_vex 20 // The maximum number of vertices, user-Defined typedef struct edgenode // edge table node {int adjvex; // The adjacent vertex field stores the subscript edgetype weight of the vertex in the vertex table; // net graph Weight Value struct edgenode * Next; // link domain, pointing to the next adjacent vertex} edgenode; typedef struct vertexnode // vertex table node {vertextype data; // vertex domain, store vertex information edgenode * firstedge; // edge header pointer} vertexnode, adjlist [max_vex]; typedef struct {adjlist; int vexnum, arcnum; // Number of vertices and arcs in the graph} graphlist;

// Locate the subscript position of vertex v in the top table. The return value is-1int locatevex (graphlist * g, vertextype v) {int I; for (I = 0; I <G-> vexnum; I ++) {If (V = G-> adjlist [I]. data) break;} if (I> G-> vexnum) {fprintf (stderr, "No This vertex. \ n "); Return-1;} return I;} // uses the adjacent table notation to construct a/undirected network gvoid creategraph (graphlist * g) {int I, J; edgetype W; edgenode * E, * F; printf ("Number of input vertices and edges: \ n"); scanf ("% d, % d ", & (g-> vexnum), & (g-> arcnum); // input vertex for (I = 0; I <G-> vexnum; I ++) {Printf ("vertex % d:", I); G-> adjlist [I]. data = getchar (); G-> adjlist [I]. firstedge = NULL; while (G-> adjlist [I]. data = '\ n') {G-> adjlist [I]. data = getchar () ;}} getchar (); // creates an edge table printf ("input edge (Vi, vj) vertex vi vj and weight w \ n "); for (I = 0; I <G-> arcnum; I ++) {char V1, V2; scanf ("% C % d", & V1, & V2, & W); getchar (); int M = locatevex (G, V1 ); int n = locatevex (G, V2); If (M =-1 | n =-1) {fprintf (stderr, "No This vertex! \ N "); return;} // request a space from the memory and generate the edge table node E = (edgenode *) malloc (sizeof (edgenode); If (E = NULL) {fprintf (stderr, "malloc () error. \ n "); return;} e-> adjvex = N; // The adjacent serial number is Ne-> Weight = W; // weight e-> next = G-> adjlist [M]. firstedge; // The method for inserting the header of a single-chain table G-> adjlist [M]. firstedge = E; # If 0 // because it is a undirected network graph F = (edgenode *) malloc (sizeof (edgenode); If (E = NULL) {fprintf (stderr, "malloc () error. \ n "); return;} f-> adjvex = m; F-> Weight = W; F-> next = G-> adjlist [N]. firstedge; G-> adjlist [N]. firstedge = f; # endif} void printgrapth (graphlist * g) {int I; for (I = 0; I <G-> vexnum; I ++) {printf ("vertex % C", G-> adjlist [I]. data); edgenode * E = G-> adjlist [I]. firstedge; while (E! = NULL) {printf ("-> <% C, % C> % d", G-> adjlist [I]. data, G-> adjlist [E-> adjvex]. data, e-> weight); E = e-> next;} putchar ('\ n ');}}

int main(){GraphList g;CreateGraph(&g);PrintGrapth(&g);return 0;}

Create a directed network diagram in the previous section. The sample code is as follows:


If you create an undirected network chart, run the following command:


For the e-edge of N vertices, the time complexity of this algorithm is O (n + E·N) because the input vertex information is not the vertex number, you need to find the vertex position in the graph. Assuming that the vertex number is input, only the time complexity of O (N + E) is required.

For directed graphs, the adjacent table can easily calculate the degree of output of a vertex, but it is not convenient to calculate the degree of input. It is necessary to traverse the entire edge table. The inverse adjacent table can be used to conveniently calculate the inbound degree, but it is not convenient to obtain the degree.

In addition, the storage structure of graphs includes cross-linked lists and multiple adjacent tables.

3. Graph Traversal

Traverse graph: a vertex is directed to the other vertices in the graph, and each vertex is asked only once. Graph Traversal Algorithms are the basis for solving graph connectivity problems, Topology Sorting, and key paths.

3.1 deep Priority Search

Depth first search (DFS) is used to traverse a tree-like forward traversal.
Starting from a node v, vertex asks this vertex, and then goes through the graph preferentially from the adjacent contacts that V has not been asked, until all vertices in the graph that have the same path with V are asked by vertex. If there are still vertices in the graph that have not been asked by the vertex, select another vertex in the graph that has not been asked by the vertex as the starting point and repeat the above process until all vertices in the graph are asked by the vertex.

DFS code for the storage structure of the adjacent matrix:

Bool visited [max_vex]; // The depth-first recursive algorithm void DFS (graph * g, int I) {Int J; visited [I] = true; printf ("% C", G-> vexs [I]); // print the vertex. It can also be another operation for (j = 0; j <G-> vexnum; j ++) if (G-> arc [I] [J]> 0 & G-> arc [I] [J]! = Infinity &&! Visited [J]) DFS (G, J);} // void dfstraverse (graph * g) {int I; for (I = 0; I <G-> vexnum; I ++) visited [I] = false; // Initialize all vertices. The status is not submitted. For (I = 0; I <G-> vexnum; I ++) if (! Visited [I]) DFS (G, I); // call DFS for vertices that are not yet asked. If it is a connected graph, it will only run once}

DFS code of the storage structure of the adjacent table:

// Deep-first recursive algorithm of the adjacent matrix void DFS (graphlist * g, int I) {edgenode * E; visited [I] = true; printf ("% C ", g-> adjlist [I]. data); // print the vertex. It can also be another operation for (E = G-> adjlist [I]. firstedge; e! = NULL; E = e-> next) if (! Visited [E-> adjvex]) DFS (G, e-> adjvex);} // void dfstraverse (graphlist * g) {int I; for (I = 0; I <G-> vexnum; I ++) visited [I] = false; // Initialize all vertex states in the for (I = 0; I <G-> vexnum; I ++) if (! Visited [I]) DFS (G, I); // call DFS for vertices that are not yet asked. If it is a connected graph, it will only run once}

For an e-edge graph with n vertices, the adjacent matrix is a two-dimensional array. To find the adjacent contacts of a vertex, we need to explain all the elements in the matrix, because O (N ^ 2) is required. When an adjacent table is used as a storage structure, the time required to find the adjacent contact depends on the number of vertices and edges, so it is O (n + E ). Obviously, for a sparse graph with few vertices, the structure of the adjacent table greatly improves the time efficiency of the algorithm.

3.2 breadth-first search

Breadth First search (DFS) traverses layers similar to trees.

If a vertex v is set out, the vertex v is followed by the vertex v and then the neighbor contacts of the vertex v that have not been asked in sequence, then, they start from these neighboring contacts and ask their neighboring contacts in sequence, and the "Neighbor Contact of the vertex first asked by the hacker" is asked by the hacker before the "Neighbor Contact of the vertex subsequently asked by the hacker, until the neighboring points of all vertices in the graph that have been asked by the vertex are asked by the vertex. If there are still vertices in the graph that have not been asked by vertex, select a vertex in the graph that has not been asked by vertex as the starting point, and repeat the above process until all vertices in the graph are asked by vertex.

// Bfsvoid bfstraverse (graph * g) {sqqueue Q; int V; For (V = 0; v <G-> vexnum; V ++) of the adjacent matrix) visited [v] = false; initqueue (Q); // secondary queue for (V = 0; v <G-> vexnum; V ++) if (! Visited [v]) // The V vertex has not been submitted {visited [v] = true; printf ("% C", G-> vexs [v]); // print the vertex, which can also be other operations enqueue (Q, V); // The V vertex is entered into the queue while (! Queueempty (q) {int I; dequeue (Q, I); For (Int J = 0; j <G-> vexnum; j ++) // deduce if other vertices have edges with the current vertex and if (G-> arc [I] [J]> 0 & G-> arc [I] [J] ]! = Infinity &&! Visited [J]) {visited [J] = true; // J is the adjacent vertex printf ("% C ", g-> vexs [J]); enqueue (Q, J);} // If} // while} // If}

// Bfsvoid bfstraverse (graphlist * g) {sqqueue Q; int I; for (I = 0; I <G-> vexnum; I ++) visited [I] = false; initqueue (Q); for (I = 0; I <G-> vexnum; I ++) if (! Visited [I]) {visited [I] = true; printf ("% C", G-> adjlist [I]. data); enqueue (Q, I); While (! Queueempty (q) {Int J; dequeue (Q, J); // locate the header pointer of the current vertex edge table chain for (edgenode * E = G-> adjlist [J]. firstedge; e! = NULL; E = e-> next) if (! Visited [E-> adjvex]) {visited [E-> adjvex] = true; printf ("% C", G-> adjlist [E-> adjvex]. data); enqueue (Q, e-> adjvex);} // If} // while} // If}

The depth-first traversal and breadth-first Traversal Algorithms are the same in terms of time complexity. The difference is that they have different sequence of attention queries for vertices.

Exam: Data Structure (c)

All the pilot code in this article: http://download.csdn.net/detail/u013071074/7445893

Blue mengmo

Further study: classical algorithm research series: 4. How to thoroughly understand: BFS and DFS priority search algorithms (this blog series is well written by the author)

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.