There are two pieces of code here:
One
This code is more comprehensive, which refers to the relevant source on GitHub. Can say powerful.
Dijkstra (Dijkstra algorithm) #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX 100 Matrix Maximum Capacity # define INF 65535//maximum 65535#define Isletter (a) (((a) >= ' a ') && ((a) <= ' Z ') ) || (((a) >= ' a ') && ((a) <= ' Z '))) #define LENGTH (a) (sizeof (a)/sizeof (a[0))//The adjacency matrix of the graph stores typedef struct _graph{char Vexs[max]; vertex set int vexnum; Vertex number int edgnum; Number of sides int Matrix[max][max]; Adjacency matrix}graph, structure of *pgraph;//side typedef struct _edgedata{char start;//edge start char end; End of edge int weight; The weight of the edge}edata;/* * Returns the position of ch in matrix matrices */static int get_position (Graph G, char ch) {int i; for (i=0; i<g.vexnum; i++) if (g.vexs[i]==ch) return i; return-1;} /* * Read an input character */static char Read_char () {char ch; do {ch = getchar (); } while (!isletter (CH)); return ch;} /* * Create diagram (own input) */graph* create_graph () {char C1, C2; int V, E; int I, J, WeigHT, p1, p2; graph* PG; Enter the number of vertices and the number of sides printf (Please enter the number of vertices: \ n); scanf ("%d", &v); printf ("Please enter the number of sides: \ n"); scanf ("%d", &e); if (V < 1 | | E < 1 | | (E > (v * (V-1)))) {printf ("Input error!!!\n"); return NULL; } if ((Pg= (graph*) malloc (sizeof)) = = null) return null; memset (PG, 0, sizeof);//Initialize//Initialize "vertex number" and "number of sides" pg->vexnum = V; Pg->edgnum = e; Initialize "vertex" for (i = 0; i < pg->vexnum; i++) {printf ("Vertex (%d):", I); Pg->vexs[i] = Read_char (); }//1. Initialize the "Edge" weights for (i = 0; i < pg->vexnum; i++) {for (j = 0; J < pg->vexnum; J + +) { if (i==j) pg->matrix[i][j] = 0; else pg->matrix[i][j] = INF; }}//2. Initialize the weight of the "edge": Initialize for (i = 0; i < pg->edgnum; i++) {//Read the starting vertex of the edge, end vertex, weight printf ("Edge (%d)") according to the user's input: ", i); C1 = Read_char (); C2 = Read_char (); scanf ("%d", &weight); P1 = Get_position (*PG, C1); P2 = get_position (*pg, C2); if (P1==-1 | | p2==-1) {printf ("Input error!!! \ n "); Free (PG); return NULL; } PG->MATRIX[P1][P2] = weight; PG->MATRIX[P2][P1] = weight; } return PG;} /* * Create diagram (with provided matrix) */graph* Create_example_graph () {char vexs[] = {' A ', ' B ', ' C ', ' D ', ' E ', ' F ', ' G '}; int matrix[][9] = {/*a*//*b*//*c*//*d*//*e*//*f*//*g*//*a*/{0, 14, INF, INF, INF, 16,}, /*b*/{0, INF, INF, 7, INF},/*c*/{inf, 0, 3, 5, 6, INF},/*d*/{INF, INF, 3, 0, 4, INF, INF},/*e*/{INF, INF, 5, 4, 0, 2, 8},/*f*/{7, 6, INF, 2, 0, 9}, /*g*/{+, INF, INF, INF, 8, 9, 0}}; int vlen = LENGTH (Vexs); int I, J; graph* PG; Enter the number of vertices and the number of edges if (pg= (graph*) malloc (sizeof) = = NULL)return NULL; memset (PG, 0, sizeof (Graph)); Initialize "vertex count" pg->vexnum = Vlen; Initialize "vertex" for (i = 0; i < pg->vexnum; i++) pg->vexs[i] = vexs[i]; Initialize "Edge" for (i = 0; i < pg->vexnum; i++) for (j = 0; J < pg->vexnum; J + +) Pg->matrix I [j] = matrix[i][j]; Count the number of edges for (i = 0; i < pg->vexnum; i++) for (j = 0; J < pg->vexnum; J + +) if (i!=j & ;& Pg->matrix[i][j]!=inf) pg->edgnum++; Pg->edgnum/= 2; return PG;} /* * Returns the index of the first adjacency vertex of vertex V, failure returns 1 */static int First_vertex (Graph G, int v) {int i; if (v<0 | | v> (G.VEXNUM-1)) return-1; for (i = 0; i < g.vexnum; i++) if (g.matrix[v][i]!=0 && g.matrix[v][i]!=inf) return i; return-1;} /* * Returns the index of vertex v relative to the next adjacency vertex of W, and fails returns 1 */static int Next_vertix (Graph G, int v, int w) {int i; if (v<0 | | v> (g.vexnum-1) | | w<0 | | w> (G.VEXNUM-1)) return-1; for (i = w + 1; i < g.vexnum; i++) if (g.matrix[v][i]!=0 && g.matrix[v][i]!=inf) return i; return-1;} /* * Depth-First search traversal graph recursive implementation */static void DFS (graph G, int i, int *visited) {int w; Visited[i] = 1; printf ("%c", G.vexs[i]); Iterates through all the adjacency vertices of the vertex. If you have not visited, then continue to go down for (w = First_vertex (g, I); w >= 0; w = Next_vertix (G, I, W)) {if (!visited[w]) DFS (G, W, visited); }}/* * Depth First search traverse graph */void dfstraverse (graph G) {int i; int Visited[max]; Vertex access mark//Initialize all vertices are not accessed for (i = 0; i < g.vexnum; i++) visited[i] = 0; printf ("DFS:"); for (i = 0; i < G.vexnum; i++) {//printf ("\n== LOOP (%d) \ n", i); if (!visited[i]) DFS (G, I, visited); } printf ("\ n");} /* Breadth-first search (similar to tree-level traversal) */void BFS (Graph G) {int head = 0; int rear = 0; int Queue[max]; Auxiliary Group queue int Visited[max]; Vertex access Tag int I, j, K; for (i = 0; I &lT G.vexnum; i++) Visited[i] = 0; printf ("BFS:"); for (i = 0; i < G.vexnum; i++) {if (!visited[i]) {visited[i] = 1; printf ("%c", G.vexs[i]); queue[rear++] = i; into the queue} while (head! = rear) {j = queue[head++]; Out queue for (k = First_vertex (g, j); k >= 0; k = Next_vertix (g, J, K))//k is the adjacency vertex for access { if (!visited[k]) {visited[k] = 1; printf ("%c", G.vexs[k]); queue[rear++] = k; }}}} printf ("\ n");} /* * Print Matrix queue graph */void print_graph (graph G) {int i,j; printf ("Martix graph:\n"); for (i = 0; i < G.vexnum; i++) {for (j = 0; J < G.vexnum; J + +) printf ("%10d", G.matrix[i][j]) ; printf ("\ n"); }}/* * Prim minimum spanning Tree * * Parameter Description: * G--adjacency Matrix * Start--starts with the first element of the start, generating the minimum tree */void Prim (Graph G, int start) { int min,i,j,k,m,n,sum; int index=0; Prim index of the smallest tree, which is the index of the prims array char Prims[max]; Prim of the smallest tree result array int Weights[max]; The weights of the edges between vertices//prim the first number in the spanning tree is "start of the first vertex in the graph" because it starts with start. prims[index++] = G.vexs[start]; Initialize the weights array for vertices, and//to initialize the weights of each vertex to the weight of "start vertex" to "vertex". for (i = 0; i < g.vexnum; i++) weights[i] = G.matrix[start][i]; Initializes the weight value of the first vertex to 0. It can be understood as "the distance of the first vertex to itself is 0". Weights[start] = 0; for (i = 0; i < G.vexnum; i++) {//Because starting from start, there is no need to process the first vertex. if (start = = i) continue; j = 0; k = 0; min = INF; In vertices that are not joined to the minimum spanning tree, find the vertex with the least weight. while (J < G.vexnum) {//If weights[j]=0, means "J-nodes have been sorted" (or has been added to the minimum spanning tree). if (weights[j]! = 0 && weights[j] < min) {min = weights[j]; K = J; } j + +; }//After processing above, the least-weighted vertex is the K-vertex in the vertices that are not added to the minimum spanning tree. The firstK vertices are added to the result array of the smallest spanning tree prims[index++] = g.vexs[k]; Marking the weight of the K vertex as 0 means that the K vertex has been sorted (or has been added to the minimum tree result). Weights[k] = 0; When the K-vertex is added to the result array of the smallest spanning tree, the weights of the other vertices are updated. for (j = 0; J < G.vexnum; J + +) {//When the J node is not processed and needs to be updated. if (weights[j]! = 0 && G.matrix[k][j] < weights[j]) weights[j] = G.matrix[k][j]; }}//Calculate the weight of the minimum spanning tree sum = 0; for (i = 1; i < index; i++) {min = INF; Get prims[i] position in G n = get_position (G, prims[i]); In vexs[0...i], find the vertex with the smallest weight of J. for (j = 0; J < i; J + +) {m = Get_position (G, prims[j]); if (g.matrix[m][n]<min) min = g.matrix[m][n]; } sum + = min; }//print minimum spanning tree printf ("PRIM (%c) =%d:", G.vexs[start], sum); for (i = 0; i < index; i++) printf ("%c", Prims[i]); printf ("\ n");} /* * Get the Edge */edata* get_edges (graph G) {int i,j in the graph; int index=0; EData *edges; edges = (edata*) malloc (g.edgnum*sizeof (EData)); For (I=0;i < g.vexnum;i++) {for (J=i+1;j < g.vexnum;j++) {if (G.matrix[i][j]!=inf) {Edges[index].start = g.vexs[i]; Edges[index].end = G.vexs[j]; Edges[index].weight = G.matrix[i][j]; index++; }}} return edges;} /* * Sort the edges by weight (from small to Large) */void sorted_edges (edata* edges, int elen) {int i,j; For (i=0, i<elen; i++) {for (j=i+1; j<elen; J + +) {if (Edges[i].weight > Edges[j].we ight) {//Exchange "I-Edge" and "J-side" EData tmp = edges[i]; Edges[i] = Edges[j]; EDGES[J] = tmp; }}}}/* * Gets the end of I */int get_end (int vends[], int i) {while (vends[i]! = 0) i = vends[i]; return i;} /* * Kruskal (Kruskal) minimum spanning tree */void Kruskal (Graph G) {int i,m,n,p1,p2; int length; int index = 0; Index of the rets array int vends[max]={0}; Used to save the end point of each vertex in the existing minimum spanning tree in the smallest tree. EData Rets[max]; The result array, preserving the edge EData *edges of the Kruskal minimum spanning tree; All sides of the graph corresponding//get "all sides in the graph" edges = get_edges (G); The edge is sorted by the size of "weight" (from small to large) sorted_edges (edges, g.edgnum); for (i=0; i<g.edgnum; i++) {p1 = Get_position (G, Edges[i].start); Gets the ordinal number of the "start" of the edge of the P2 = get_position (G, edges[i].end); Gets the ordinal number M = Get_end (Vends, p1) of the "end point" of the section I edge; Gets the end point of P1 in the "Existing minimum spanning tree" n = get_end (vends, p2); Gets the end point of the P2 in the "Existing minimum spanning tree"//if m!=n, means "Edge i" and "vertices that have been added to the minimum spanning tree" do not form a loop if (m! = N) {Vends[m] = n ; Set m at the end of "existing minimum spanning tree" to n rets[index++] = edges[i]; Save Results}} free (edges); Statistics and printing of "Kruskal minimum spanning tree" information length = 0; for (i = 0; i < index; i++) length + = Rets[i].weight; printf ("kruskal=%d:", length); for (i = 0; i < Index i++) printf ("(%c,%c)", Rets[i].start, Rets[i].end); printf ("\ n");} /* * Dijkstra Shortest path. * That is, the shortest path of the "Vertex vs" to each of the other vertices in the chart (G). * * Parameter Description: * G--figure * vs--start vertex (start vertex). That is, the shortest path of vertex vs to other vertices is computed. * Prev--the predecessor vertex array. That is, Prev[i] is the value of "Vertex vs" to "vertex i" in all vertices experienced by the shortest path, at the vertex before "vertex i". * Dist--length array. That is, Dist[i] is the length of the shortest path of "Vertex vs" to "vertex i". */void Dijkstra (Graph G, int vs, int prev[], int dist[]) {int i,j,k; int min; int tmp; int Flag[max]; Flag[i]=1 indicates that the shortest path to vertex vs to Vertex I has been successfully obtained. Initialize for (i = 0; i < G.vexnum; i++) {flag[i] = 0; The shortest path to vertex i is not yet available. Prev[i] = 0; The predecessor vertex of vertex i is 0. Dist[i] = g.matrix[vs][i];//The shortest path to vertex i is the right of "Vertex vs" to "vertex i". }//Initialize "Vertex vs" itself flag[vs] = 1; Dist[vs] = 0; Traverse g.vexnum-1 times, and find the shortest path of a vertex at a time. for (i = 1; i < G.vexnum; i++) {//search for the current smallest path,//i.e., in vertices that do not get the shortest path, find the closest vertex (k) to vs. min = INF; for (j = 0; J < G.vexnum; J + +) {if (flag[J]==0 && dist[j]<min) {min = dist[j]; K = J; }}//Mark "Vertex K" for already acquired to shortest path flag[k] = 1; Fix the current shortest path and precursor vertex//i.e., update the shortest path and precursor vertex for vertices that do not get the shortest path, when the shortest path to vertex K is already. for (j = 0; J < G.vexnum; J + +) {tmp = (g.matrix[k][j]==inf? INF: (min + g.matrix[k][j])); Prevent overflow if (flag[j] = = 0 && (tmp < DIST[J])) {dist[j] = tmp; PREV[J] = k; }}}//Print the result of Dijkstra shortest path printf ("Dijkstra (%c): \ n", G.vexs[vs]); for (i = 0; i < g.vexnum; i++) printf ("Shortest (%c,%c) =%d\n", G.vexs[vs], g.vexs[i], dist[i]);} int main () {int Prev[max] = {0}; int Dist[max] = {0}; graph* PG; Custom "graph" (Input matrix queue)//PG = Create_graph (); Using the existing "figure" PG = Create_example_graph ();p rint_graph (*PG); Print Figure//dfstraverse (*PG); Depth-first traversal of//BFS (*PG); Breadth-First traversal//prim (*PG, 0); The prim algorithm generates the minimum spanning tree//kruskal (*PG); The Kruskal algorithm generates a minimum spanning tree//Dijkstra algorithm to obtain the shortest distance from "4th vertex" to each other vertex Dijkstra (*PG, 3, prev, dist); return 0;}
Result diagram:
Two
This paragraph is relatively simple, comparatively good to understand.
#include <stdio.h> #include <stdlib.h> #define MAX 1000000int arcs[10][10];//adjacency matrix int d[10];//Save Shortest path length int p[ 10][10];//path int final[10];//if final[i] = 1 indicates that vertex VI is already in the set S int n = 0;//vertex number int v0 = 0;//source point int v,w;void shortestpath_dij () {int i = 0, min = 0; for (v = 0; v < n; v++)//cyclic initialization {Final[v] = 0; D[V] = Arcs[v0][v]; for (w = 0; w < n; w++) p[v][w] = 0;//Set Empty path if (D[v] < MAX) {p[v][v0] = 1; p[v][v] = 1;} } D[v0] = 0; final[v0]=0; Initializes the v0 vertex that belongs to the set S//start main loop each time the shortest path to a vertex v is v0 and adds v to the set S for (i = 1; i < n; i++) {min = MAX; for (w = 0; w < n; w++) {//I think the core process--The selected point if (!final[w])//If the W vertex is in v-s {//The final point of this process should be to select the vertex in the current v-s that is associated with S//and the least weighted value is described as the nearest point of the current distance to V0 if ( D[w] < min) {v = w; min = d[w];} }} Final[v] = 1; Select the point to add to the collection s for (w = 0; w < n; w++)//update the current shortestPath and distance {/* * in this loop V is the point in the collection s that is currently selected to see if the D0V+DVW is less than d[w] if it is less than the dot V as the midpoint. Add point 3 to see if D[5] is to be updated to determine whether D (V0-V3) + D (V3-V5) is less than d[5] */if (!final[w] && (min+ar Cs[v][w]<d[w]) {D[w] = min + arcs[v][w]; P[W] = P[v]; P[W][W] = 1; P[W] = P[v] + [W]}}}} int main () {int i, J; scanf ("%d", &n);//vertex number for (i = 0; i < n; i++) {for (j = 0; J < N; j + +) {SC ANF ("%d", &arcs[i][j]);//used to store adjacency matrix}} shortestpath_dij (); for (i = 0; i < n; i++) printf ("d[%d] =%d\n", i,d[i]); return 0;}
Results:
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
The Dijkstra (Dijkstra) algorithm of the shortest path for the---C language of data structure