1) Kruskal algorithm
Prim's algorithm starts from a vertex and gradually finds the edge with the smallest weight on each vertex to construct the minimum spanning tree.
Kruskal's algorithm is built directly with the edge as the goal.
Because the weight is on the edge, it is also a natural idea to directly find the edge with the smallest weight to construct a spanning tree, but it is only necessary to consider whether a loop will be formed when constructing.
At this point, we used the edge set array structure in the storage structure of the graph.
The following is the definition code of the edge set array structure:
1 typedef struct 2 { 3 int begin; // The subscript of the start point of the edge 4 int end; // The subscript of the end point of the edge 5 int weight; // The weight of the edge 6 }Edge;
This algorithm uses the same instance of Prim's algorithm, we directly create the edge set array of the graph.
After sorting the weights of the edges from small to large, the following figure is shown:
Key Analysis:
Kruskal's algorithm is mainly for edge expansion, and the efficiency is very high when the number of edges is small, so it has advantages for sparse graphs
The Prim algorithm is better for dense graphs, that is, the number of edges is very large.
The code is implemented as follows:
1 #include " stdafx.h " 2 #include<iostream> 3 #include< string > 4 using namespace std; 5 typedef struct MGraph 6 { 7 string vexs[ 60 ]; // Store vertex 8 int arcs[ 100 ][ 100 ]; // Store the adjacency matrix matrix 9 int vexnum, arcum; // The total number of vertices and the total number of edges 10 }MGraph; 11 typedef struct 12 { 13 int begin; // The subscript of the start point of the edge 14 int end; // The subscript of the end point of the edge 15 int weight; // The weight of the edge 16 }Edge; 17 18 int locateVex(MGraph G , string u) // return i if found, otherwise return -1 19 { 20 for ( int i = 0 ; i < G.vexnum; i++ ) 21 if (G.vexs[i] ==u) 22 return i; 23 return - 1 ; 24 } 25 26 void CreateGraphUDG(MGraph &G) // construct undirected graph 27 { 28 string v1, v2; // two vertex information 29 int w; // between two vertices Edge weight 30 int i, j, k; 31 cout << " Please enter the number of vertices and edges: " ; 32 cin >> G.vexnum >> G.arcum; 33 34 cout <<" Please enter a vertex: " ; 35 for (i = 0 ; i < G.vexnum; i++ ) 36 cin >> G.vexs[i]; 37 38 for (i = 0 ; i < G.vexnum; i++) / / First set all elements in the adjacency matrix to infinity, here the default 10000 is infinity 39 for (j = 0 ; j < G.vexnum; j++ ) 40 G.arcs[i][j] = 10000 ; 41 42 cout < < " Please enter edges and weights: " << endl; 43 for (k = 0; k < G.arcum; k++ ) 44 { 45 cin >> v1 >> v2 >> w; 46 i = locateVex(G, v1); 47 j = locateVex(G, v2); 48 G.arcs[i] [j] = G.arcs[j][i] = w; // Elements symmetrical about the main diagonal are equal 49 } 50 51 } 52 53 int cmp( const void * a, const void * b) 54 { 55 return (*(Edge*)a).weight - (*(Edge* )b).weight; 56 } 57 58 int Find( int *parent, int f) // find the trailing subscript of connected vertices 59 { 60 while (parent[f] > 0 ) 61 f = parent[f]; 62 return f; 63 } 64 65 void MiniSpanTree_Kruskal(MGraph G) 66 { 67 int i, j, n, m; 68 int k = 0 ; 69 int parent[ 100 ]; //Array for finding the root node 70 Edge edges[ 100 ]; // Define the edge set array, the structure of edge is begin, end, weight, all of which are integers 71 for (i = 0 ; i < G.vexnum - 1 ; i++) // Used to build and sort the edge set array (store the right part of the diagonal of the adjacency matrix into the edge set array) 72 { 73 for (j = i + 1 ; j < G.vexnum; j++ ) 74 { 75 if (G.arcs[i][j] < 10000 ) 76 { 77 edges[k].begin = i; // The node with the smaller number is the first 78 edges[k].end = j; // The larger node is the end 79 edges[k].weight = G.arcs[i][j]; 80 k++ ; 81 } 82 } 83 } 84 qsort(edges , G.arcum, sizeof (Edge), cmp); // sort the edge set array Edge 85 86 for (i = 0 ; i < G.vexnum; i++ ) 87 parent[i] = 0 ; 88 89 cout << " Print minimum spanning tree: " << endl; 90 for (i = 0 ; i < G.arcum; i++ ) 91 { 92 n = Find(parent, edges[i].begin); // find the root of the tree where the "first node" of edge[i] is located 93 m = Find(parent, edges[i].end); // find the root of the tree where the "tail node" of edge[i] is located 94 if (n != m) // if n is not equal to m, It means that the two vertices are not in a tree, so the addition of this edge will not cause the selected edge set to generate a loop 95 { 96 parent[n] = m; // put the end vertex of this edge into the subscript as the starting point In the parent of , indicating that this vertex is already in the spanning tree set 97 cout << G.vexs[edges[i].begin] << " - " <<G.vexs[ edges[i].end] << " " << edges[i].weight << endl; 98 } 99 } 100 } 101 102 int main() 103 { 104 MGraph G; 105 CreateGraphUDG(G); 106 MiniSpanTree_Kruskal(G); 107 cout << endl; 108 return 0; 109 }
Output result: