Data structure (C implementation) ------- Kruskal algorithm of the minimal spanning tree
Algorithm Description:
The Kruskal algorithm constructs the Minimum Spanning Tree in the order of increasing weights.
Assume that G (V, E) is the most connected network with n vertices. vertex set V = {v1, v2,..., vn }. Set the Minimum Spanning Tree to 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 Kruskal algorithm is as follows: Initialize the Minimum Spanning Tree to T = (V, TE), which only contains all vertices of G and does not contain any edge of G, T is composed of n connected components, each of which has only one vertex. the edge in the graph G is sorted by weight from small to large, and the cost is the smallest edge, if the vertex points attached to the edge belong to different connected components in T, the edge is added to the TE. Otherwise, the edge is discarded and the next edge with the minimum cost is selected. And so on until TE contains n-1 edges (that is, all vertices in T are on the same connected component.
Algorithm Implementation:
Set an edge array to store all edges in the connected network. To facilitate selection of edges with the smallest current weight value, you need to sort the edges in the edge from small to large.
In the merge of connected components, you can use the merge method of the set. For connected networks with n vertices, set an array father [0... n-1]. The initial value is-1, indicating that n vertices are connected to different components. Then, Scan each edge in the edge array in sequence and find the connected component of the two associated vertices. Assume that vf1 and vf2 are the root node numbers of the tree where the two vertices are located, if vf1 is not equal to vf2, it indicates that the two vertices of this edge do not belong to the same connected component. This edge is used as the edge of the minimal spanning tree and output, then merge the two connected components to which they belong.
Algorithm code:
Int findFather (int father [], int v) {int t = v; while (father [t]! =-1) t = father [t]; return t;}/*** Kruskal Algorithm for Minimum Spanning Tree **/void Kruskal_MG (MGraph MG, Edge edge []) {int father [MAX_VEX_NUM]; int I, count, vf1, vf2; // initialize the father array for (I = 0; I <MAX_VEX_NUM; I ++) {father [I] =-1;} I = 0; count = 0; // count the number of edges added to the minimum tree // traverse the edge while (I <MG. arcnum & count <MG. arcnum) {vf1 = findFather (father, edge [I]. start); vf2 = findFather (father, edge [I]. end); // if the two nodes do not belong to the same connected component, add the same connected component if (v F1! = Vf2) {father [vf2] = vf1; count ++; printf (% c, % c, % d, MG. vexs [edge [I]. start], MG. vexs [edge [I]. end], edge [I]. cost) ;} I ++ ;}}
Among them, the function findFather is used to find the connected component of the specified node, where it is the serial number of the root node of the tree in the array.
Algorithm Description:
There are many sorting methods for the weight values of e edge in a weight graph G. Here we use the simplest Bubble sorting method, with the time complexity of O (n ^ 2 ). Determine whether the two vertices of the newly selected edge are in the same connected component, this problem is equivalent to the existence of two nodes in the spanning tree with a maximum of n vertices traversing the newly selected edge, therefore, the worst case for this algorithm is O (n ^ 2 ).
Note: Generally, the time complexity of the Prim algorithm is O (n ^ 2), so it is suitable for dense graphs. the Kruskal algorithm needs to sort the e-edge, in the fastest case, the complexity is O (elog2e). Therefore, it is more appropriate to use the Kruskal Algorithm for sparse graphs.
Complete code:
/** =================================================== ========================================================== =========** Filename: kruskal. c ** Description: Kruskal algorithm of the Minimum Spanning Tree ** Version: 1.0 * Created: July 22, May 06, 2015 * Revision: none * Compiler: gcc ** Author: jesson20121020 (), 997287955@qq.com * Organization: ** ===================================================== ========================================================== =======*/# include
# Include
# Define MAX_VEX_NUM 50 # define MAX_ARC_NUM 100 # define UN_REACH 1000 typedef char VertexType; typedef enum {DG, UDG} GraphType; typedef struct {VertexType vexs [MAX_VEX_NUM]; int arcs [MAX_VEX_NUM] [MAX_VEX_NUM]; int vexnum, arcnum; GraphType type;} MGraph; /*** obtain the subscript * vex vertex * return of the specified vertex in the vertex set based on the name. If the subscript * vex vertex * is found, the subscript is returned. Otherwise, 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 ;/** * Obtain Edge information from the adjacent matrix **/void init_edge (MGraph MG, edge Edge []) {int I, j; int count = 0; if (MG. type = 0) {for (I = 1; I <= MG. vexnum; I ++) {for (j = 1; j <= MG. vexnum; j ++) {if (MG. arcs [I] [j]! = 0 & MG. arcs [I] [j]! = UN_REACH) {edge [count]. start = I; edge [count]. end = j; edge [count]. cost = MG. arcs [I] [j]; count ++ ;}}} else {for (I = 1; I <= MG. vexnum; I ++) {for (j = I; j <= MG. vexnum; j ++) {if (MG. arcs [I] [j]! = 0 & MG. arcs [I] [j]! = UN_REACH) {edge [count]. start = I; edge [count]. end = j; edge [count]. cost = MG. arcs [I] [j]; count ++ ;}}}}} /*** sort edges by weight from large to small **/void sort_edge (Edge edge [], int arcnum) {int I, j; Edge temp; for (I = 0; I <arcnum-1; I ++) {for (j = I + 1; j <arcnum; j ++) {if (edge [I]. cost> edge [j]. cost) {temp = edge [I]; edge [I] = edge [j]; edge [j] = temp ;}}}} /*** output Edge information **/void print_edge (edge Edge [], int arcnum) {int I = 0; while (I <Arcnum) {printf (% d, edge [I]. start, edge [I]. end, edge [I]. cost); I ++ ;}}/*** find the connected component of the specified node. Here, find the subscript of its root node in the father array. **/Int findFather (int father [], int v) {int t = v; while (father [t]! =-1) t = father [t]; return t;}/*** Kruskal Algorithm for Minimum Spanning Tree **/void Kruskal_MG (MGraph MG, Edge edge []) {int father [MAX_VEX_NUM]; int I, count, vf1, vf2; // initialize the father array for (I = 0; I <MAX_VEX_NUM; I ++) {father [I] =-1;} I = 0; count = 0; // count the number of edges added to the minimum tree // traverse the edge while (I <MG. arcnum & count <MG. arcnum) {vf1 = findFather (father, edge [I]. start); vf2 = findFather (father, edge [I]. end); // if the two nodes do not belong to the same connected component, add the same connected component if (v F1! = Vf2) {father [vf2] = vf1; count ++; printf (% c, % c, % d, MG. vexs [edge [I]. start], MG. vexs [edge [I]. end], edge [I]. cost);} I ++;}/*** main function */int main (void) {MGraph MG; Edge edge Edge [MAX_ARC_NUM]; create_MG (& MG ); print_MG (MG); init_edge (MG, edge); sort_edge (edge, MG. arcnum); printf (the result of Kruskal :); Kruskal_MG (MG, edge); return EXIT_SUCCESS ;}
Run the demo:
Jesson @ jesson-K43SV :~ /Develop/worksapce/c_learning/minimal spanning tree $ gcc-o Kruskal. cjesson @ jesson-K43SV :~ /Develop/worksapce/c_learning/Minimum Spanning Tree $. /Kruskal Please input graph type DG (0) or UDG (1): 0 Please input vexmun: 4 Please input arcnum: 5 Please input 1th vex (char ): a Please 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 1 Please input 2th arc v1 (char) v2 (char) weight (int): a c 3 Please input 3th arc v1 (char) v2 (char) weight (int): a d 4 Please input 4th arc v1 (char) v2 (char) weight (int): B c 2 Please input 5th arc v1 (char) v2 (char) weight (int): c d 3 Graph type: Direct graphGraph vertex number: 4 Graph arc number: 5 Vertex set: abcdAdjacency Matrix: 0134425210001000%31000%the result of Kruskal: a, B, 1b, c, 2c, d, 3