Kruskal's algorithm is a simple understanding of the two classic least Spanning Tree algorithms. This fully embodies the essence of greedy algorithms. The general process can be expressed in a diagram. The figure here is the one on Wikipedia. It is clear and intuitive.
First, we have a graph with vertices and edges.
As shown in the following figure:
The first step is to sort the length of all edges and use the sorting result as the basis for edge selection. The greedy algorithm is embodied here again. Sort resources to select the local optimal resources.
After sorting, we chose edge ad. In this way, our graph becomes
Step 2: search for the remaining changes. We found ce. The weight here is also 5
And so on, we found 6, 7, and 7. The figure is changed to this.
The next step is the key. Which side is selected below? BC or Ef? None of them, although the side with a length of 8 is the smallest unselected side. But now they are connected (for BC, CE and EB can be connected, similar EF can be connected through EB, Ba, AD, DF ). Therefore, we do not need to select them. Similar BD has been connected (the connection line here is marked in red ). So at last we had to leave EG and Fg. Of course we chose eg. The final success figure is:
All edge points are connected here, and a minimal spanning tree is built.
To briefly describe this algorithm, we first sort the edge weights. (From small to large) Do we need to select the edge here for the cycle inference. It is inferred that the two vertices of the edge are connected, and the next vertex is connected. If it is not connected, connect it. This process is clear and clear.
However, in implementation, the difficulty lies in how to describe that two points have been connected? The query set is used as an aid.HereGo and have a look.
The code of the query set and the C ++ Implementation of kruscal are posted here:
/*** Disjoint_set_forest.h -- an implementation for disjoint Set Data Structure *** created by GE chunyuan on 04/09/2009. ** version: 0.1 */# pragma once # ifndef _ disjoint_set_h _ # DEFINE _ disjoint_set_h _ # include <vector> template <typename T> class disjointset {public: disjointset ();~ Disjointset (); void makeset (const STD: vector <t> & S); boolfindset (const T & S, T & parent); voidunion (const T & S1, const T & S2); protected: struct node {intrank; tdata; node * parent;}; int m_nelementcnt; int m_nsetcnt; STD: vector <node *> m_nodes ;}; template <class T> disjointset <t>: disjointset () {m_nelementcnt = 0; m_nsetcnt = 0;} template <class T> disjointset <t> ::~ Disjointset () {for (INT I = 0; I <m_nelementcnt; I ++) delete m_nodes [I];} template <class T> void disjointset <t> :: makeset (const STD: vector <t> & S) {m_nelementcnt + = (INT) s. size (); m_nsetcnt + = (INT) s. size (); STD: vector <t >:: const_iterator it = S. begin (); For (; it! = S. end (); ++ it) {node * pnode = new node; pnode-> DATA = * it; pnode-> parent = NULL; pnode-> Rank = 0; m_nodes.push_back (pnode) ;}} template <class T> bool disjointset <t>: findset (const T & S, T & parent) {node * curnode = NULL; bool find = false; For (INT I = 0; I <(INT) m_nodes.size (); I ++) {curnode = m_nodes [I]; if (curnode-> DATA = s) {find = true; break ;}} if (! Find) return false; // find the root node * proot = curnode; while (proot-> parent! = NULL) {proot = proot-> parent;} // update all curnode's parent to rootwhile (curnode! = Proot) {node * pnext = curnode-> parent; curnode-> parent = proot; curnode = pnext;} parent = proot-> data; return true ;} template <class T> voiddisjointset <t>: Union (const T & S1, const T & S2) {node * pnode1 = NULL; node * pnode2 = NULL; int find = 0; For (INT I = 0; I <(INT) m_nodes.size (); ++ I) {If (m_nodes [I]-> DATA = S1 | m_nodes [I]-> DATA = S2) {find ++; if (m_nodes [I]-> DATA = S1) pnode1 = m_nodes [I]; elsepnode2 = M_nodes [I] ;}// not found if (find! = 2) return; If (pnode1-> rank> pnode2-> rank) pnode2-> parent = pnode1; else if (pnode1-> rank <pnode2-> rank) pnode1-> parent = pnode2; else {pnode2-> parent = pnode1; ++ pnode1-> rank;} -- m_nsetcnt;} # endif // _ disjoint_set_h _
// Kruscal_algorithm.cpp: defines the entry point for the console application. // # include "stdafx. H "# include <string> # include <vector> # include <algorithm> # include <iostream> # include" disjoint_set_forest.h "struct vertex {vertex () {} vertex (STD :: string N) {name = N;} bool operator = (const vertex & RHs) {return name = RHS. name;} bool Operator! = (Const vertex & RHs) {return name! = RHS. name ;}std: string name ;}; struct edge {edge () {}edge (vertex V1, vertex V2, int W) {This-> V1 = V1; this-> v2 = V2; this-> W = W;} vertex V1; vertex V2; int W ;}; struct edgesort {bool operator () (const edge & E1, const edge & E2) {return e1.w <e2.w ;}}; struct printedge {void operator () (edge e) {STD :: cout <"edge start from" <E. v1.name <"to" <E. v2.name <"with length =" <E. W <STD: Endl ;}}; class graph {Public: void appendvertex (const vertex & V1) {m_vertexs.push_back (V1);} void appendedge (const vertex & V1, const vertex & V2, int W) {m_edges.push_back (edge (V1, v2, W);} void minimumspanningkruskal () {STD: vector <edge> result; STD: Sort (m_edges.begin (), m_edges.end (), edgesort ()); disjointset <vertex> DV; DV. makeset (m_vertexs); STD: vector <edge >:: iterator it = m_edges.begin (); For (; it! = M_edges.end (); ++ it) {vertex P1; vertex P2; bool b1 = DV. findset (IT-> V1, P1); bool b2 = DV. findset (IT-> V2, P2); If (B1 & B2 & (P1! = P2) {DV. union (P1, P2); result. push_back (* It) ;}} for_each (result. begin (), result. end (), printedge ();} protected: STD: vector <vertex> m_vertexs; STD: vector <edge> m_edges;}; int _ tmain (INT argc, _ tchar * argv []) {graph gr; Vertex a ("A"); vertex B ("B"); vertex C ("C "); vertex D ("D"); vertex E ("e"); vertex F ("F"); vertex g ("G"); gr. appendvertex (a); gr. appendvertex (B); gr. appendvertex (c); gr. appendvertex (d); gr. appendvertex (E); gr. appendvertex (f); gr. appendvertex (g); gr. appendedge (a, B, 7); gr. appendedge (a, d, 5); gr. appendedge (B, c, 8); gr. appendedge (B, d, 9); gr. appendedge (B, E, 7); gr. appendedge (C, E, 5); gr. appendedge (D, E, 15); gr. appendedge (D, F, 6); gr. appendedge (E, F, 8); gr. appendedge (E, G, 9); gr. appendedge (f, g, 11); gr. minimumspanningkruskal (); System ("pause"); Return 0 ;}
Greedy Algorithm (Greedy Algorithm) based on the Minimum Spanning Tree Kruskal (Kruskal & #39; s Algorithm)