Data structure (C implementation) ------- Prim algorithm of the Minimum Spanning Tree
Algorithm Description
If a connected graph is a network, the spanning tree with the smallest sum of weights in all spanning trees in the network is the smallest spanning tree, or the least cost Spanning Tree. The idea of the minimal spanning tree method constructed using the Prim algorithm is as follows:
Assume that G = (V, E) is a connected network with n vertices. vertex set V = {v1, v2 ,..., vn }. set the minimum spanning tree T = (U, TE), where U is the vertex set of T, TE is the edge set of T, and the initial values of U and TE are empty sets.
The basic idea of the Prim algorithm is as follows: first, take a vertex from V (assuming v1) and set the spanning tree T to a tree with only one node v1, that is, U = {v1 }; then, as long as U is the true subset of V, find the shortest (minimum weight) edge in all the endpoints in T and the other endpoints outside T. If the shortest edge meeting the condition is (vi, vj), the vertex vj of the edge and its vertex not in T is merged into the edge set TE and vertex set U of T respectively. In this way, every time a tree is generated, a vertex and an edge are merged until all vertices are included in the tree T. In this case, U = V is required, and TE has n-1 edges. T = (U, TE) is a minimum spanning tree of G.
Algorithm Implementation
Sets an edge array that records the smallest cost edge from the vertex U set to the V-U. Information about each edge includes the start point and end point and weight of the edge. The following describes how to use the prim algorithm to calculate the Minimum Spanning Tree from vertex u:
(1) initialize the edge array and record the n-1 edge with the smallest cost of the vertex u to the remaining nodes in the graph.
(2) Add vertex u to U.
(3) When U is not equal to V, do the following.
1) Select an edge with the minimum cost from the edge array.
2) Add the end point of the edge to the U.
3) Adjust the edges array so that it always records vertex U to the smallest side of the V-U cost.
Algorithm code
// Define the Edge struct typedef struct {int start; int end; int cost;} Edge;/** Prim algorithm for Minimum Spanning Tree **/void Prim_MG (MGraph MG, char vs) {Edge [MAX_VEX_NUM]; int I, j, k, v, min; int s = getIndexOfVexs (vs, & MG ); // initialize the edge for (I = 1; I <= MG. vexnum; I ++) {if (s! = I) {edge [I]. start = s; edge [I]. end = I; edge [I]. cost = MG. arcs [s] [I] ;}// first add s to edge [s] in the Spanning Tree. cost = 0; for (I = 2; I <= MG. vexnum; I ++) {min = 1000; for (j = 1; j <= MG. vexnum; j ++) {if (edge [j]. cost! = 0 & edge [j]. cost <min) {min = edge [j]. cost; k = j ;}} v = edge [k]. end; edge [v]. cost = 0; // Add to new node // output edge printf (% c % d, MG. vexs [edge [v]. start], MG. vexs [edge [v]. end], MG. arcs [edge [v]. start] [edge [v]. end]); // re-adjust the array for (j = 1; j <= MG. vexnum; j ++) {if (edge [j]. cost! = 0 & MG. arcs [v] [j]! = 0 & MG. arcs [v] [j] <edge [j]. cost) {edge [j]. start = k; edge [j]. end = j; edge [j]. cost = MG. arcs [v] [j] ;}}}
Algorithm Description
Assume that there are n vertices in the graph, the frequency of the first cyclic statement to be initialized is n, and the frequency of the second cyclic statement is n-1. There are two inner loops. One is to find the edge with the smallest weight value in the edge array. The frequency is n-1, and the other is to re-adjust the edge of the edge array. The frequency is n, therefore, the time complexity of the Prim algorithm is O (n ^ 2), which is independent of the number of edges in the graph. Therefore, it is suitable for finding the dense Minimum Spanning Tree.
Complete code
/** =================================================== ========================================================== =========** Filename: prim. c ** Description: Prim algorithm of the Minimum Spanning Tree Algorithm ** Version: 1.0 * Created: March 11, 2015 * Revision: none * Compiler: gcc ** Author: jesson20121020 (), 997287955@qq.com * Organization: ** ===================================================== ========================================================== =======*/# include
# Include
# Define limit 50 # define UN_REACH 1000 typedef char VertexType; typedef enum {DG, UDG} GraphType; typedef struct {VertexType vexs [MAX_VEX_NUM]; int arcs [MAX_VEX_NUM] [limit]; int vexnum, arcnum; GraphType type;} MGraph;/*** obtain the subscript of the specified vertex in the vertex set by name * vex vertex * return if it is found, the subscript is returned; otherwise, returns 0 */int getIndexOfVexs (char vex, MGraph * MG) {int I; for (I = 1; I <= MG-> vexnum; I ++) {if (MG-> vexs [I] = vex) {return I ;}} return 0;}/*** create an adjacent matrix */void create_MG (MGraph * MG) {int I, j, k, weight; int v1, v2, type; char c1, c2; printf (Please input graph type DG (0) or UDG (1) :); scanf (% d, & type); if (type = 0) MG-> type = DG; else if (type = 1) MG-> type = UDG; else {printf (Please input correct graph type DG (0) or UDG (1 )!); Return;} printf (Please input vexmun:); scanf (% d, & MG-> vexnum); printf (Please input arcnum:); scanf (% d, & MG-> arcnum); getchar (); for (I = 1; I <= MG-> vexnum; I ++) {printf (Please input % dth vex (char) :, I); scanf (% c, & MG-> vexs [I]); getchar () ;}// initialize the adjacent matrix for (I = 1; I <= MG-> vexnum; I ++) {for (j = 1; j <= MG-> vexnum; j ++) {if (I = j) MG-> arcs [I] [j] = 0; elseMG-> arcs [I] [j] = UN_REACH ;}// enter the edge information, create an adjacent matrix for (k = 1; K <= MG-> arcnum; k ++) {printf (Please input % dth arc v1 (char) v2 (char) weight (int):, k ); scanf (% c % d, & c1, & c2, & weight); v1 = getIndexOfVexs (c1, MG); v2 = getIndexOfVexs (c2, MG ); if (MG-> type = 1) MG-> arcs [v1] [v2] = MG-> arcs [v2] [v1] = weight; elseMG-> arcs [v1] [v2] = weight; getchar () ;}/ *** print the adjacent matrix and vertex information */void print_MG (MGraph MG) {int I, j; if (MG. type = DG) {printf (Graph type: Direct graph);} else {pri Ntf (Graph type: Undirect graph);} printf (Graph vertex number: % d, MG. vexnum); printf (Graph arc number: % d, MG. arcnum); printf (Vertex set:); for (I = 1; I <= MG. vexnum; I ++) printf (% c, MG. vexs [I]); printf (Adjacency Matrix :); for (I = 1; I <= MG. vexnum; I ++) {j = 1; for (; j <MG. vexnum; j ++) {printf (% d, MG. arcs [I] [j]);} printf (% d, MG. arcs [I] [j]) ;}// defines the Edge structure typedef struct {int start; int end; int cost;} Edge ;/** Prim algorithm for least Spanning Tree **/void Prim_MG (MGraph MG, char vs) {Edge edge [MAX_VEX_NUM]; int I, j, k, v, min; int s = getIndexOfVexs (vs, & MG); // initialize the edge for (I = 1; I <= MG. vexnum; I ++) {if (s! = I) {edge [I]. start = s; edge [I]. end = I; edge [I]. cost = MG. arcs [s] [I] ;}// first add s to edge [s] in the Spanning Tree. cost = 0; for (I = 2; I <= MG. vexnum; I ++) {min = 1000; for (j = 1; j <= MG. vexnum; j ++) {if (edge [j]. cost! = 0 & edge [j]. cost <min) {min = edge [j]. cost; k = j ;}} v = edge [k]. end; edge [v]. cost = 0; // Add to new node // output edge printf (% c % d, MG. vexs [edge [v]. start], MG. vexs [edge [v]. end], MG. arcs [edge [v]. start] [edge [v]. end]); // re-adjust the array for (j = 1; j <= MG. vexnum; j ++) {if (edge [j]. cost! = 0 & MG. arcs [v] [j]! = 0 & MG. arcs [v] [j] <edge [j]. cost) {edge [j]. start = k; edge [j]. end = j; edge [j]. cost = MG. arcs [v] [j] ;}}}/*** main function */int main (void) {MGraph MG; char startVex; create_MG (& MG ); print_MG (MG); printf (Please input the start vex (char) :); scanf (% c, & startVex); printf (The result of Prim :); Prim_MG (MG, startVex); return EXIT_SUCCESS ;}
Run demo
jesson@jesson-HP:~/develop/workspace/c_learning/csdn/Prim$ gcc -o Prim Prim.cjesson@jesson-HP:~/develop/workspace/c_learning/csdn/Prim$ ./Prim Please input graph type DG(0) or UDG(1) :1Please input vexmun : 4Please input arcnum : 5Please input 1th vex(char):aPlease input 2th vex(char):bPlease input 3th vex(char):cPlease input 4th vex(char):dPlease input 1th arc v1(char) v2(char) weight(int): a b 1Please input 2th arc v1(char) v2(char) weight(int): a c 3Please input 3th arc v1(char) v2(char) weight(int): a d 4Please input 4th arc v1(char) v2(char) weight(int): b c 2Please input 5th arc v1(char) v2(char) weight(int): c d 3Please input the start vex(char):aThe result of Prim:a b 1b c 2c d 3