/*
There are two main graph traversal methods: depth-first traversal and breadth-first traversal. The depth-first traversal of a graph is similar to the first root traversal of a tree, and the breadth-first traversal of a graph is the same as that of a tree.
1. depth-first Traversal Algorithm for Connected Graphs
The depth-first traversal algorithm of a graph is a time-last-depth-first algorithm, that is, in all the adjacent vertices of the graph, each time after accessing the current vertex, first, access the first adjacent vertex of the current vertex.
The depth-first traversal recursive algorithm for connected graphs is as follows:
1. Access vertex v and mark that vertex V has been accessed.
2. Find the first adjacent vertex W of vertex v.
3. If vertex v's adjacent vertex W exists, continue to execute. Otherwise, the algorithm ends.
4. If vertex W has not been accessed, the depth first traverses recursive access to vertex W.
5. Find the next adjacent W of the W vertex of vertex v and go to step 3.
2. The breadth-first Traversal Algorithm for Connected Graphs
The graph breadth-first traversal algorithm is a layered search process. The breadth-first traversal algorithm refers to accessing the graph from the specified vertex to the order in which the path length of the vertex ranges from short to long.
Other vertices in China and Germany.
The following is an algorithm to traverse the breadth-first of connected graphs:
1. Access the initial vertex v and mark the vertex v as accessed.
2. vertex v enters the queue.
3. If the queue is not empty, continue execution; otherwise, the algorithm ends.
4. The output queue obtains the vertex u of the queue header.
5. Find the first adjacent vertex W of vertex u.
6. If the adjacent vertex W of vertex u does not exist, go to step 3. Otherwise, run cyclically:
A. If vertex W has not been accessed, access vertex W and Mark vertex w as accessed;
B. vertex W enters the queue;
C. Find the next adjacent vertex w after W of vertex u and go to Step 6.
3. Traversal Algorithms for non-Connected Graphs
For a non-connected graph, the depth or breadth traversal from any vertex of the graph takes precedence over all vertices in the graph. However, for a non-connected graph,
Starting from any initial vertex of the graph, the depth or breadth first traverses, and cannot access all vertices in the graph. At this time, only those vertices connected to the initial vertex can be accessed.
However, for a non-connected graph, each vertex can be used as an initial vertex for depth-first traversal or breadth-first traversal.
To determine whether the vertex has been accessed. If the vertex has not been accessed, the vertex is accessed. Otherwise, the vertex is skipped. In this way, you can access multiple vertices in a non-connected graph.
*/
The implementation code is as follows:
// Implementation of the operations on the storage structure of the adjacent matrix # include <stdio. h> # include <malloc. h> # define maxsize 100 // define the size of the element typedef char datatype; // define a type # define maxvertices 10 // defines the maximum vertex # define maxweight 10000 // defines the specific value of infinity # define maxqueuesize 15 typedef int datatype1; typedef struct {datatype1 queue [maxqueuesize]; int rear; // queue pointer int front; // head pointer int count; // counter} seqcqueue; // initialize void queueinitiate (seqcqueue * q) {// initialize the sequential cyclic queue QQ-> COUNT = 0; // define the Initial counter Q-> rea R = 0; // define the initial team tail pointer subscript Q-> front = 0; // define the initial head pointer tag} // non-null int queuenotempty (seqcqueue q) {// judge whether the Q of the ordered cyclic queue is not empty or not. If the value is not empty, 1 is returned. Otherwise, 0if (Q. count! = 0) {return 1 ;}else {return 0 ;}// Input Queue int queueappend (seqcqueue * q, datatype1 X) {// Insert the data element value X to the end of the Q queue. If the result is successful, 1 is returned, 0 if (Q-> count> 0 & Q-> rear = Q-> front) {// when the queue is full, printf ("the queue is full and cannot be inserted !! \ N "); Return 0;} else {q-> queue [q-> rear] = X; // insert data element X to the end of the queue Q-> rear = (Q-> rear + 1) % maxqueuesize; // Add 1q-> count ++ to the end of the queue indicator; // Add 1 return 1 to the counter; // return 1} // output queue int queuedelete (seqcqueue * q, datatype1 * D) {// Delete the queue Header element of the ordered cyclic queue Q and assign it to D. If yes, 1 is returned. If no, 0 if (Q-> COUNT = 0) is returned) {// judge printf for null ("the queue is empty and no data elements are in the queue !! \ N "); Return 0;} else {* D = Q-> queue [q-> front]; // store the first element in D with Q-> front = (Q-> front + 1) % maxqueuesize; // Add 1q-> count to the first indicator --; // calculator minus return 1 ;}/// get the first data element int queueget (seqcqueue Q, datatype1 * D) {// obtain the current primary element of the ordered cyclic queue Q and assign it to D. If yes, 1 is returned. If no, 0 if (Q. count = 0) {printf ("the queue is empty. You can retrieve it without any data element !! \ N "); Return 0;} else {* D = Q. queue [q. front]; return 1 ;}}typedef struct {// define a struct datatype list [maxsize]; int size; // the size of the struct element} seqlist; // struct object typedef struct {seqlist vertices; // sequence table for storing vertices int edge [maxvertices] [maxvertices]; // The edge adjacent matrix int numofedges; // Number of edges} adjmgraph; typedef struct {int row; // The row subscript int Col; // The column subscript int weight; // weight} rowcolweight; // edge information struct // initialize void initiate (seqlist * l) {L-> size = 0; // defines the number of initialization elements} // calculates the number of current elements I NT getlength (seqlist L) {return L. size; // return length} // insert data element int insertdata (seqlist * l, int I, datatype X) {// Insert the data element x before the position I (0 <= I <= size) of the sequence table L // If the insertion is successful, 1 is returned. If the output fails, 0 Int J is returned; if (L-> size> = maxsize) {printf ("the sequence table is full and cannot be inserted !! \ N "); Return 0;} else if (I <0 | I> L-> size) {printf (" the inserted position is invalid and is not in the specified range, the parameter I is invalid! \ N "); Return 0;} else {// move data from the back to the forward in a consistent manner to prepare for insertion (j = L-> size; j> I; j --) {L-> list [J] = L-> list [J-1];} l-> list [I] = x; L-> size ++; return 1 ;}} // Delete int deletedata (seqlist * l, int I, datatype * X) {// Delete the data in the sequence table where I is located. I> = 0 & I <= size-1. Save the data to X. // If deletion is successful, 1 is returned, otherwise, the return value is 0int J; If (L-> size <= 0) {printf ("the sequence table is empty and no data elements can be deleted! \ N "); Return 0;} else if (I <0 | I> L-> size-1) {printf (" parameter I is invalid and cannot be deleted! \ N "); Return 0;} else {* x = L-> list [I]; for (j = I + 1; j <= L-> size-1; j ++) {// forward from the previous one L-> list [J-1] = L-> list [J];} l-> size --; // subtract one from the data element return 1 ;}// retrieve the data element int getdata (seqlist L, int I, datatype * X) {if (I <0 | I> L. size-1) {printf ("parameter I is invalid and cannot be deleted! \ N "); Return 0;} else {* x = L. list [I]; return 1 ;}/// initialize the sequence table with n vertices and the adjacent matrix void initiateg (adjmgraph * g, int N) {// initialize int I, j; for (I = 0; I <n; I ++) {for (j = 0; j <n; j ++) {if (I = J) {G-> edge [I] [J] = 0;} else {G-> edge [I] [J] = maxweight; // maxweight indicates infinity }}g-> numofedges = 0; // set the number of edges to 0 initiate (& G-> vertices ); // sequence table initialization} // insert vertex void insertvertex (adjmgraph * g, datatype vertex) {// insert vertex vertexinsertdata (& G-> vertices, g-> vertices. size, vertex); // sequence table End insert} // Insert the edge void insertedge (adjmgraph * g, int V1, int V2, int weight) {// Insert the edge <V1, V2>, and edge <V1, v2> permission: weightif (V1 <0 | V1> = G-> vertices. size | V2 <0 | V2> = G-> vertices. size) {printf ("An error occurred while out-of-bounds V1 or V2 parameter !!! \ N "); return;} G-> edge [V1] [V2] = weight; G-> numofedges ++;} // delete an edge void deleteedge (adjmgraph * G, int V1, int V2) {// delete an edge <V1, V2> If (V1 <0 | V1> = G-> vertices. size | V2 <0 | V2> = G-> vertices. size) {printf ("An error occurred while out-of-bounds V1 or V2 parameter !!! \ N "); return;} If (G-> edge [V1] [V2] = maxweight | V1 = V2) {printf (" this edge does not exist !!! \ N "); return;} G-> edge [V1] [V2] = maxweight; G-> numofedges --;} // obtain the first adjacent vertex int getfirstvex (adjmgraph g, int V) {// search for the first adjacent vertex of the vertex whose serial number is V in graph G // if such vertex exists, return the serial number of the adjacent vertex; otherwise, return-1int Col; if (v <0 | V> = G. vertices. size) {printf ("An error occurred while out-of-bounds V1 parameter !!! \ N "); Return-1 ;}for (COL = 0; Col <G. vertices. size; Col ++) {If (G. edge [v] [col]> 0 & G. edge [v] [col] <maxweight) {return Col ;}} return-1 ;}// obtain the next adjacent vertex int getnextvex (adjmgraph g, int V1, int V2) {// in the graph, find the next adjacent vertex of the adjacent vertex V2 of the V1 vertex. // if such an adjacent vertex exists, the serial number of the adjacent vertex is returned; otherwise,-1 // The numbers of vertices V1 and V2 are int col. If (V1 <0 | V1> G. vertices. size | V2 <0 | V2> = G. vertices. size) {printf ("An error occurred while out-of-bounds V1 or V2 parameter !!! \ N "); Return-1 ;}for (COL = V2 + 1; Col <G. vertices. size; Col ++) {If (G. edge [V1] [col]> 0 & G. edge [V1] [col] <maxweight) {return Col;} return-1;} void creatgraph (adjmgraph * g, datatype V [], int N, rowcolweight E [], int e) {// insert n vertex information in the graph V and e edge information Eint I, K; initiateg (G, N ); // D vertex sequence table initialization for (I = 0; I <n; I ++) {insertvertex (G, V [I]); // insert vertex} For (k = 0; k <E; k ++) {insertedge (G, E [K]. row, E [K]. col, E [K]. weight); // insert edge} void visit (datatype item) {// define access Operation Function printf ("% C", item);} // The depth priority function void depthfsearch (adjmgraph g, int V, int visited [], void visit (datatype item) {// access operation of the connected graph G with V as the initial vertex as visit () depth-first traversal // The array visited indicates whether the corresponding vertex has been accessed, 0 indicates not accessed, 1 indicates that the accessed int W; visit (G. vertices. list [v]); // access vertex vvisited [v] = 1; // set the accessed flag W = getfirstvex (G, V ); // obtain the first adjacent vertex while (W! =-1) {If (! Visited [w]) {depthfsearch (G, W, visited, visit); // recursion} W = getnextvex (G, V, W );}} // The depth-first traversal function void depthfirstsearch (adjmgraph g, void visit (datatype item) {// access operation of the unconnected graph G as visit () int I; int * visited = (int *) malloc (sizeof (INT) * g. vertices. size); for (I = 0; I <G. vertices. size; I ++) {visited [I] = 0; // The access flag is initially 0} for (I = 0; I <G. vertices. size; I ++) {If (! Visited [I]) {depthfsearch (G, I, visited, visit); // call with each vertex as the initial vertex} Free (visited );} // The breadth-first traversal function of a connected graph void brodfsearch (adjmgraph g, int V, int visited [], void visit (datatype item )) {// connected graph G uses V as the initial vertex access operation as the visit breadth first traversal // The array visited indicates whether the vertex has been accessed, and 0 indicates that the vertex has not been accessed, 1 indicates that datatype1 U, W; seqcqueue queue; visit (G. vertices. list [v]); // access vertex vvisited [v] = 1; // set the accessed flag queueinitiate (& Queue); // queue initialization queueappend (& queue, v); // The initial vertex v enters the queue while (queuenotem Pty (Queue) {queuedelete (& queue, & U); // output queue W = getfirstvex (G, U ); // obtain the first adjacent vertex of vertex u while (W! =-1) {// If (! Visited [w]) {// if you have not accessed visit (G. vertices. list [w]); // access vertex wvisited [w] = 1; // set the accessed flag queueappend (& queue, W ); // vertex W in the queue} W = getnextvex (G, U, W); // obtain the next adjacent vertex }}// the extended traversal function of the unconnected graph is as follows: void broadfirstsearch (adjmgraph g, void visit (datatype item) {// The breadth of the non-connected graph G access operation is visit () First traversing int I; int * visited = (int *) malloc (sizeof (INT) * g. vertices. size); for (I = 0; I <G. vertices. size; I ++) {visited [I] = 0; // The access flag is initially 0} for (I = 0; I <G. vertices. size; I ++) {If (! Visited [I]) {brodfsearch (G, I, visited, visit); // call with each vertex as the initial vertex} Free (visited);} void main () {adjmgraph g; datatype A [] = {'A', 'B', 'C', 'D', 'E'}; rowcolweight RCW [] = {0, 1, 10 },{, 20 },{, 30 },{, 40 },{, 50 }}; int n = 5, E = 5; int I, j; creatgraph (& G, A, N, RCW, e); // create a graph printf ("depth-first traversal sequence:"); depthfirstsearch (G, visit ); printf ("\ n breadth-first traversal sequence:"); broadfirstsearch (G, visit); printf ("\ n ");}
Graph breadth and depth