Data structure code - Chart
From the beginning of this blog, we have come to the code part of graph structure. For graph related code, we mainly focus on depth first and breadth first traversal algorithms. Let's first introduce the breadth first traversal algorithm.
Introduction to breadth first algorithm
1. Diagram structure representation
- Before introducing the code related to the diagram, the graphical representation method of the diagram is introduced,
- The graph is mainly represented by adjacency matrix and adjacency table.
- The following is an example diagram, mainly implemented in the form of adjacency matrix:
The drawing method of adjacency matrix mainly includes the following steps: - Observe whether there is a loop pointing to itself in the graph, that is, 1 - > 1, such a self cyclic node;
- If it exists, set 1 at the corresponding position of the diagonal of the matrix; if not, set 0;
- According to the design principle of undirected graph in the graph, set 1 at the corresponding symmetrical position in the adjacency matrix;
- Repeating the above process will realize the adjacency matrix of the above figure;
After the above graph structure is represented, we design the structure code to facilitate the subsequent design of breadth first traversal.
2. Figure structure
The structure of the graph mainly consists of vertex set, weight declaration, adjacency matrix representation and other elements. The following is the code of the structure:
typedef int EdgeType;//statement //Figure structure typedef struct { int adj;//Represents whether the weight exists. Here, the integer data is used instead of the values of 0 and 1 char * info;//Specific value of weight int vexnum; //Represents the number of vertices int arcnum;//Represents the number of edges of a graph //adjacency matrix EdgeType arc[MAXSIZE][MAXSIZE]; }Graph;
After completing the declaration of the graph structure, the last preparation is to review the non recursive implementation of the binary tree hierarchical traversal algorithm.
3. Non recursive implementation of sequence traversal algorithm for binary tree (review)
As for why we should review the non recursive hierarchical traversal algorithm of binary tree, it is because the breadth first traversal of graph structure is based on the hierarchical traversal implementation of binary tree, and also needs the help of a data structure - queue. Hierarchical traversal of non recursive code - last question
The following is a review of the hierarchical traversal algorithm of binary tree:
typedef struct TNode{ ElemType data; struct TNode* lchild, *rchild; }TNODE,*BiTree; //Hierarchical traversal code void BehindTraverse(BiTree root){ if(root == NULL){ return ; } InitQueue(Q);//Initialize queue TNODE *p; //Root node such as queue EnterQueue(Q,root); while(!isEmpty(Q)){ DeQueue(Q,p);//Out of queue visit(p->data);//Access data //Left subtree in queue if(p->lchild != NULL){ EnterQueue(Q,p->lchild); } //Right subtree in queue if(p->rchild != NULL){ EnterQueue(Q,p->rchild); } } }
The current preparations are ready. Let's introduce the breadth first traversal algorithm in the figure below
4. Introduction to breadth first traversal algorithm
main points:
- A data structure queue is required;
- Find the vertex adjacent to the first vertex;
- Mark which vertices have been accessed;
- The basic operations of the diagram need to be declared:
1. FirstAdjVex (g, v) represents the first critical point of the vertex in graph G. if it exists, it returns the sequence number of the vertex. If it does not exist or does not exist in the graph, it returns - 1;
2. NextAdjvex(G,v,w): except v, if the next adjacency point W exists, the serial number is returned; if it does not exist, the - 1 is returned;
The first function FirstAdjVex can be understood as finding the serial number of the first adjacent node to the current incoming node. As for how to implement this function, first look at the following figure:
Here, for example, taking vertex 2 as an example, we can see that the value of the second row of the matrix in the figure is
1 0 1 0 1. After calling the FirstAdjVex function, the returned value must look backward from a column. The first location node with 1 appears, so 1 is returned. Here represents the serial number of the first node connected to node 2.
After understanding the implementation principle of the FirstAdjVex function above, it is not difficult to write the code
//The FirstAdjVex function finds the first node of the current incoming node and returns void FirstAdjVex(Graph G,int v){//Represents the first node passed in int i; //i here represents columns 1 to 5 for(i = 1;i<=G.vexnum;i++){//Perform column loop if(G.arc[v][i].adj != 0){ //Find the first node that is not 0 in the matrix return i; } } return -1;//If not found, - 1 is returned }
After the algorithm implementation of FirstAdjVex function, the following is the implementation of NextAdjvex(G,V, W) function. See the following figure for its implementation:
The implementation method is to find the first connected node behind the current incoming coordinate. The operation code is as follows:
//Find the next first connected node void NextAdjvex(Graph G,int v,int w){ int i; //Because the subscript node transmitted is (v,w), //To find the first connected node after w, you need to start from w+1 for(i = w+1;i<=G.vexnum;i++){ //If connected, return if(G.arc[v][i].adj == 1){ return i; } } return -1;//If not found, - 1 is returned }
After the preparation of the above code is completed, the algorithm idea of BFS code is expressed:
- Apply for an array to mark whether the access node has been accessed;
- Apply for a queue to store access elements;
- The incoming node is accessed first and incorporated into the queue;
- Judge the queue:
- If it is not empty, it will exit the queue and find the connected nodes of the current outgoing node;
- After searching, the searched nodes are queued in turn;
- Repeat the above process.
Combined with the above ideas, the logic execution diagram is as follows:
Combined with the above analysis ideas, the implementation code of BFS is given:
//breadth-first search #define MAXSIZE 5 int visit[MAXSIZE];//New tag array InitQueue(Q);//Initialize queue void BFS(Graph G,int v){ int w; visit(v);//Mark the v node for access visit[v] = 1; EnQueue(Q,v);//Queue while(! isEmpty(Q)){ DeQueue(Q,v);//Out of queue //Starting from FirstAdjVex(G,v), find the first connected node, //Find the last connected node until the NextAdjvex function for(w = FirstAdjVex(G,v); w >= 0; w = NextAdjvex(G,v,w)){ if(visit[w] == 0){//If the currently found node has not been accessed, it is set to 1 visit(w);//Access to discovered nodes visit[w] = 1;//Visit EnQueue(Q,w);//Queue } } } }
For the above BFS analysis code, code integration is carried out, and the complete implementation of breadth first traversal algorithm is as follows:
Complete code
#define MAXSIZE 5 int visit[MAXSIZE];//New tag array InitQueue(Q);//Initialize queue //structural morphology typedef int EdgeType;//statement //Figure structure typedef struct { int adj;//Represents whether the weight exists. Here, the integer data is used instead of the values of 0 and 1 char * info;//Specific value of weight int vexnum; //Represents the number of vertices int arcnum;//Represents the number of edges of a graph //adjacency matrix EdgeType arc[MAXSIZE][MAXSIZE]; }Graph; //The FirstAdjVex function finds the first node of the current incoming node and returns void FirstAdjVex(Graph G,int v){//Represents the first node passed in int i; //i here represents columns 1 to 5 for(i = 1;i<=G.vexnum;i++){//Perform column loop if(G.arc[v][i].adj != 0){ //Find the first node that is not 0 in the matrix return i; } } return -1;//If not found, - 1 is returned } //Find the next first connected node void NextAdjvex(Graph G,int v,int w){ int i; //Because the subscript node transmitted is (v,w), //To find the first connected node after w, you need to start from w+1 for(i = w+1;i<=G.vexnum;i++){ //If connected, return if(G.arc[v][i].adj == 1){ return i; } } return -1;//If not found, - 1 is returned } //breadth-first search void BFS(Graph G,int v){ int w; visit(v);//Mark the v node for access visit[v] = 1; EnQueue(Q,v);//Queue while(! isEmpty(Q)){ DeQueue(Q,v);//Out of queue //Starting from FirstAdjVex(G,v), find the first connected node, //Find the last connected node until the NextAdjvex function for(w = FirstAdjVex(G,v); w >= 0; w = NextAdjvex(G,v,w)){ //The limiting condition of W > = 0 here is the processing that the return value of the above two functions is - 1, if(visit[w] == 0){//If the currently found node has not been accessed, it is set to 1 visit(w);//Access to discovered nodes visit[w] = 1;//Visit EnQueue(Q,w);//Queue } } } }
The above is the explanation of BFS. If there are shortcomings, please point out in the comment area, hey, thanks, learn together!