The Dijkstra (dijkstra) algorithm of the shortest path for the---c language of data structure

Source: Internet
Author: User

There are two pieces of code together Here:

One

This piece of code is comprehensive, and it's a reference to the relevant source code on GITHUB.

able to 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 ("wrong input!!

!\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 "edge" weights: 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 &amp ;& Pg->matrix[i][j]!=inf) pg->edgnum++; Pg->edgnum/= 2; Return pG;} /* returns the index of the first adjacency vertex of the vertex v. Failure is returned-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 haven't interviewed Me. So keep going 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 interviewed 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 Mark int i, j, k; For (i = 0; i < 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 an access adjacency vertex { 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-the start element begins. Generate 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 weight of the edge between Vertices//prim the first number in the minimum spanning tree is "start of the first vertex in the graph", because it starts from Start. prims[index++] = G.vexs[start]; Initialize the weights array for vertices,//to initialize the weights of each vertex to the "start vertex" to "the vertex" weight.

For (i = 0; i < g.vexnum; i++) weights[i] = g.matrix[start][i]; Initializes the weight value of the first vertex to 0. 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 have not been added to the minimum spanning tree. Find the vertex with the least weight.

While (j < G.vexnum) {//if weights[j]=0. means that the "J node has 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. Add the K vertex to the result array of the smallest spanning tree prims[index++] = g.vexs[k]; Mark 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 according to the weights (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 of the graph" edges = get_edges (G); Sort the edges according to 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"//assumes m!=n, meaning that "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).

* * parameters: * 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 The value of prev[i] is the vertex in all vertices experienced by the shortest path of vertex vs to Vertex i, which is before Vertex I. * Dist--length Array. That Dist[i] is the length of the shortest path for 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++) {//find the current smallest path;//. In the vertices that do not get the shortest path, find the closest to vs recent Vertex (k).

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; Define yourself "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 Of//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 is a simpler, relatively good understanding.

#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;          Initialize the V0 vertex belongs to the set S//start main loop each time v0 to a vertex v the shortest path and add V to the set S for (i = 1; i < n; i++) {min = MAX;               For (w = 0; W < n; W++) {//i think the core process--point if (!final[w])//assuming w vertex in V-s  {//the point at which this process is finally chosen should be to select the vertex in the current v-s that is associated with S//and the least weighted value in the book describing the current point if it is near V0. (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 currentShortest path 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 the point v is the Midpoint. For example, add point 3 to investigate whether d[5] is to be updated to infer that D (v0-v3) + D (v3-v5) and whether it is less than d[5] */if (!final[w] && (min+                   Arcs[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:


The Dijkstra (dijkstra) algorithm of the shortest path for the---c language of data structure

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.