Header file:
# Include <memory. h>
# Include <stdlib. h>
# Include <malloc. h>
# Include <string. h>
# Include ". \ source \ common. H"
# Include "lxbasic. H"
# Define max_vex_num 20
# Define max_str_len 20
# Define infinity 999 // infinity
// Vertex Structure
Typedef struct tagvextype
{
Int index;
Char name [max_str_len];
} Vextype;
// Arc structure
Typedef struct tagarctype
{
Int adj; // weight
} Arctype;
// Graph Structure
Typedef struct taggraphic
{
Vextype vexs [max_vex_num];
Arctype arcs [max_vex_num] [max_vex_num];
Int vexnum;
Int arcnum; // temporarily useless
} Graphic;
// Save the Shortest Path weight from vertex V0 to other vertices and the passing Node path
Typedef struct tagpathfinal
{
Int V0; // start vertex number
Int d [max_vex_num]; // The value of the shortest path (d [v])
Int P [max_vex_num] [max_vex_num]; // path of the shortest path (P [v])
} Pathfinal;
// Function declaration
// Create and initialize the Graph
Graphic * creategraphic ();
// Graphic printing
Void printgraphic (Graphic * pgraphic );
// Set the drawing Value
Void setgraphic (Graphic * pgraphic );
// Destroy the Graph
Void destroygraphic (Graphic ** ppgraphic );
// Print the Shortest Path
Void printshortestpath (Graphic * pgraphic, pathfinal * path );
// Find the shortest path
Void shortestpath_dij (Graphic * pgraphic, pathfinal * path );
// Test the program
Void testcaseforgraphic ();
Source file: //////////////////////////////////////// //////////////////////////////////////// //////////////////////////////////////// //////////////////////////////////////// //////////////////////////////////////// ////////////////////////////////////
# Include "dc_graph.h"
/*
Summary of returned local pointer variables:
A pointer to a local variable cannot be returned, but a local pointer variable can be returned.
1. the pointer and local pointer variables of local variables are two different concepts.
2. the life cycle of a local variable also ends after the function body ends. Its pointer (that is, its address) is the address of an invalid variable, so the function cannot return this address value.
3. the life cycle of a local pointer variable also ends after the function ends. However, if the life cycle of the variable or function or any storage object that it points to is not completed, the pointer (Address) returned by the function is valid.
*/
// Create and initialize the Graph
Graphic * creategraphic ()
{
Graphic * pgraphic = (Graphic *) malloc (sizeof (graphic ));
Null_ptr_ret_null (pgraphic)
Pgraphic-> vexnum = 0;
Pgraphic-> arcnum = 0;
Memset (pgraphic-> vexs, 0, sizeof (vextype) * max_vex_num );
Memset (pgraphic-> arcs, 0, sizeof (arctype) * max_vex_num );
Return pgraphic;
}
// Draw
Void printgraphic (Graphic * pgraphic)
{
Int I, J;
For (I = 0; I <pgraphic-> vexnum; I ++)
{
Printf ("% s [% d]", pgraphic-> vexs [I]. Name, pgraphic-> vexs [I]. Index );
}
Printf ("\ n ");
For (I = 0; I <pgraphic-> vexnum; I ++)
{
Printf ("% s [% d]:", pgraphic-> vexs [I]. Name, pgraphic-> vexs [I]. Index );
For (j = 0; j <pgraphic-> vexnum; j ++)
{
Printf ("% d", pgraphic-> arcs [I] [J]);
}
Printf ("\ n ");
}
}
// Set the vertex and Adjacent matrix information of the graph (Data Structure: 187 pp. 7.34, figure)
/*
Vex0 [0] vex1 [1] vex2 [0] vex3 [0] vex4 [0] vex5 [0]
Vex0 [0]: 0*10*30 100
Vex1 [1]: * 0 5 ***
Vex2 [0]: 10 5 0 50 **
Vex3 [0]: ** 50 0 20 10
Vex4 [0]: 30 ** 20 0 60
Vex5 [0]: 100 ** 10 60 0
*/
Void setgraphic (Graphic * pgraphic)
{
Int I, J;
Null_ptr_ret (pgraphic)
Pgraphic-> vexnum = 6;
Pgraphic-> arcnum = 8;
Pgraphic-> vexs [0]. Index = 0;
Strncpy (pgraphic-> vexs [0]. Name, "vex0", max_str_len );
Pgraphic-> vexs [1]. Index = 1;
Strncpy (pgraphic-> vexs [1]. Name, "vex1", max_str_len );
Pgraphic-> vexs [2]. Index = 0;
Strncpy (pgraphic-> vexs [2]. Name, "vex2", max_str_len );
Pgraphic-> vexs [3]. Index = 0;
Strncpy (pgraphic-> vexs [3]. Name, "vex3", max_str_len );
Pgraphic-> vexs [4]. Index = 0;
Strncpy (pgraphic-> vexs [4]. Name, "vex4", max_str_len );
Pgraphic-> vexs [5]. Index = 0;
Strncpy (pgraphic-> vexs [5]. Name, "vex5", max_str_len );
Pgraphic-> arcs [0] [0]. adj = 0;
Pgraphic-> arcs [0] [1]. adj = infinity;
Pgraphic-> arcs [0] [2]. adj = 10;
Pgraphic-> arcs [0] [3]. adj = infinity;
Pgraphic-> arcs [0] [4]. adj = 30;
Pgraphic-> arcs [0] [5]. adj = 100;
Pgraphic-> arcs [1] [1]. adj = 0;
Pgraphic-> arcs [1] [2]. adj = 5;
Pgraphic-> arcs [1] [3]. adj = infinity;
Pgraphic-> arcs [1] [4]. adj = infinity;
Pgraphic-> arcs [1] [5]. adj = infinity;
Pgraphic-> arcs [2] [2]. adj = 0;
Pgraphic-> arcs [2] [3]. adj = 50;
Pgraphic-> arcs [2] [4]. adj = infinity;
Pgraphic-> arcs [2] [5]. adj = infinity;
Pgraphic-> arcs [3] [3]. adj = 0;
Pgraphic-> arcs [3] [4]. adj = 20;
Pgraphic-> arcs [3] [5]. adj = 10;
Pgraphic-> arcs [4] [4]. adj = 0;
Pgraphic-> arcs [4] [5]. adj = 60;
Pgraphic-> arcs [5] [5]. adj = 0;
For (I = 0; I <6; I ++)
{
For (j = 0; j <6; j ++)
{
Pgraphic-> arcs [J] [I] = pgraphic-> arcs [I] [J];
}
}
Printgraphic (pgraphic );
}
// Release the image space
Void destroygraphic (Graphic ** ppgraphic)
{
Null_ptr_ret (ppgraphic)
If (null! = * Ppgraphic)
{
Free (* ppgraphic );
* Ppgraphic = NULL;
}
Return;
}
// Print the Shortest Path
Void printshortestpath (Graphic * pgraphic, pathfinal * path)
{
Int V, W;
Null_ptr_ret (PATH)
Null_ptr_ret (pgraphic)
Printf ("src: Vex [% d] \ n", path-> V0 );
For (V = 0; v <pgraphic-> vexnum; V ++)
{
If (path-> P [v] [0] <infinity)
{// The shortest path exists.
Printf ("DEST: Vex [% d]:", V );
For (W = 0; W <pgraphic-> vexnum; W ++)
{
If (path-> P [v] [W] <infinity)
{
Printf ("% d->", path-> P [v] [W]);
}
}
Printf ("shortest [% d]", path-> d [v]);
Printf ("\ n ");
}
}
}
/*************************************** *****************************
Function Name: shortestpath_dij
Function: Find the shortest path by dijela
P [v]: records the vertex numbers in the path in the coordinate sequence, indicating the shortest path (node set) from V0 to v ), P [v] [W] indicates the number of the W vertex in the V0 to V path.
D [v]: the shortest path of the v0-v
Final [v] is true. if and only if v belongs to S, the shortest path from V0 to V has been obtained. If it is set to false, V still belongs to the V set and no Shortest Path is found.
Yan Weimin's algorithm: If V0 to V has the shortest path v0, Vi, VJ, and VK, P [v] [V0], p [V] [VI], p [v] [VJ], p [v] [VK], p [v] [v]] true, only corresponding vertices can be listed when the path is output in the order of coordinates. The path order cannot be guaranteed.
Modify the strict algorithm to obtain the specific path.
Input parameter: graphic * pgraphic, path-> V0
Output parameter: pathfinal * path ()
Return Value: None
**************************************** *****************************/
Void shortestpath_dij (Graphic * pgraphic, pathfinal * path)
{
Int v, k, I, W, Min, final [max_vex_num];
/* Legality judgment */
Null_ptr_ret (pgraphic)
Null_ptr_ret (PATH)
/* Begin *********************************** *****/
For (V = 0; v <pgraphic-> vexnum; V ++)
{
Final [v] = lx_false;
// Weight Initialization
Path-> d [v] = pgraphic-> arcs [path-> V0] [v]. adj; // The initial value of D is the weight of the direct arc from V0 to other vertices.
// Initialize the path (empty all paths)
For (W = 0; W <pgraphic-> vexnum; W ++)
{
Path-> P [v] [W] = infinity;
}
// The shortest path from V0 obtained for the first time to other vertices
If (path-> d [v] <infinity)
{
Path-> P [v] [0] = path-> V0; // V0 indicates that the 0th nodes from V0 to V are V0.
Path-> P [v] [1] = V; // initialize the 1st nodes from V0 to V as V (which will be changed later)
}
}
Path-> d [path-> V0] = 0; // V0 to v0, of course, 0
Final [path-> V0] = lx_true; // initialization. V0 belongs to the s set.
/* End *********************************** *****/
/* Find the shortest path begin ********************************** ******/
V = path-> V0; // use v to remember the closest vertex and initialize it to V0.
For (I = 1; I <pgraphic-> vexnum; I ++) // here the loop starts from 1, and the remaining G. vexnum-1 vertices
{
// Seek the shortest result directly: select a vertex W whose distance value is the smallest from V and not in S, and add s
Min = infinity; // Min is the closest distance to the V0 vertex.
For (W = 0; W <pgraphic-> vexnum; W ++)
{
If (! Final [w]) // W vertices in V-S
{
If (path-> d [w] <min)
{
Min = path-> d [w];
V = W; // W is closer to V0. Use V to remember the closest vertex.
}
}
}
Final [v] = lx_true; // locate the shortest and add V to S.
// Note: the shortest of the direct operation is not necessarily the shortest, but it may be the shortest if it is transmitted from the vertex in S. The final mark is set to true in advance.
// Non-direct shortest: Modify the distance value of vertices in V. If W is added as the intermediate vertex, the distance value from V0 to V is shorter than the path without W, modify the distance value.
For (W = 0; W <pgraphic-> vexnum; W ++)
{
If (! Final [w] & (min + pgraphic-> arcs [v] [W]. adj <path-> d [w])
{
Path-> d [w] = min + pgraphic-> arcs [v] [W]. adj; // refresh the Shortest Path
// Copy the shortest path, which is different from Yan Shu.
// Initial: P [v] = {v0,..., V, infinity, infinity ,......}
// P [w] = {infinity,..., infinity ,......}
For (k = 0; k <pgraphic-> vexnum; k ++)
{
If (path-> P [v] [k] <infinity)
{
Path-> P [w] [k] = path-> P [v] [k]; // copy the path of the v0-v to the v0-w
// P [w] = {v0,..., V, infinity, infinity ,......}
}
Else
{
Path-> P [w] [k] = W; // Add W to the v0-w (V to W is direct)
// P [w] = {v0,..., V, W, infinity, infinity ,......}
Break; // break is required here
}
}
// Final result: P [w] = {v0,..., V, W, infinity, infinity ,......}
}
}
}
/* Find the shortest path end ********************************** ******/
}
// Test the program
Graphic * gpgraphic;
Pathfinal gpath;
Void testcaseforgraphic ()
{
Gpgraphic = creategraphic ();
Setgraphic (gpgraphic );
Gpath. V0 = 5;
// Find the shortest path
Shortestpath_dij (gpgraphic, & gpath );
// Print
Printshortestpath (gpgraphic, & gpath );
Destroygraphic (& gpgraphic );
}