Introduction
According to Wikipedia:"Kruskal's algorithm is an algorithm in graph theory that finds a minimum spanning tree for a connectedweighted graph. This means it finds a subset of the edges that forms a tree that includes every vertex, where the total weight of all the edges in the tree is minimized. If the graph is not connected, then it finds a minimum spanning forest (a minimum spanning tree for each connected component). Kruskal's algorithm is an example of a greedy algorithm."
In short, Kruskal's algorithm is used to connect all nodes in a graph, using the least cost possible.
Example
A cable TV company is laying a cable in a new neighborhood. An internet cafe is connecting all PCs via network.
Using the Demo
Click anywhere to plot the vertices. Hold down ctrl and select two vertices to create an edge. A popup window appears to enter edge cost. Having finished plotting the graph, click Solve.
High Level Design

Low Level Design

Using the Code
private List<Edge> SolveGraph(ref int nTotalCost)
{
Edge.QuickSort(m_lstEdgesInitial, 0, m_lstEdgesInitial.Count - 1);
List<Edge> lstEdgesReturn = new List<Edge>(m_lstEdgesInitial.Count);
foreach (Edge ed in m_lstEdgesInitial)
{
Vertex vRoot1, vRoot2;
vRoot1 = ed.V1.GetRoot();
vRoot2 = ed.V2.GetRoot();
if (vRoot1.Name != vRoot2.Name)
{
nTotalCost += ed.Cost;
Vertex.Join(vRoot1, vRoot2);
lstEdgesReturn.Add
(new Edge(ed.V1, ed.V2, ed.Cost, ed.StringPosition));
}
}
return lstEdgesReturn;
}
How the Graph is formed with GDI is not covered as it is irrelevant.
Classes
Typically, our graph consists of two components, Vertices, and Edges connecting these vertices.
Each Edge is marked by a value or weight, which is the Cost of connecting the two vertices.
Vertex
Holds:
- Vertex Name (which must be unique within Graph) and its Drawing Point
- Rank and Root (we'll get to those later)
class Vertex
{
#region Members
int nName;
public int nRank;
public Vertex vRoot;
public System.Drawing.Point pPosition;
#endregion
#region Properties
public int Name
{
get
{
return nName;
}
}
#endregion
public Vertex(int nName, System.Drawing.Point pPosition)
{
this.nName = nName;
nRank = 0;
this.vRoot = this;
this.pPosition = pPosition;
}
#region Methods
internal Vertex GetRoot()
{
if (this.vRoot != this) {
this.vRoot = this.vRoot.GetRoot(); }
return this.vRoot;
}
internal static void Join(Vertex vRoot1, Vertex vRoot2)
{
if (vRoot2.nRank < vRoot1.nRank) {
vRoot2.vRoot = vRoot1; }
else {
vRoot1.vRoot = vRoot2; if (vRoot1.nRank == vRoot2.nRank) {
vRoot1.nRank++; }
}
}
#endregion
}
Edge
Holds two Vertices, Cost of connection between them, and CostDrawing Point.
Note that it implements IComparable, we'll need it to sort Edges by Cost later on.
class Edge : IComparable
{
#region Members
Vertex v1, v2;
int nCost;
System.Drawing.Point pStringPosition;
#endregion
#region Properties
public Vertex V1
{
get
{
return v1;
}
}
public Vertex V2
{
get
{
return v2;
}
}
public int Cost
{
get
{
return nCost;
}
}
public System.Drawing.Point StringPosition
{
get
{
return pStringPosition;
}
}
#endregion
public Edge(Vertex v1, Vertex v2, int nCost, System.Drawing.Point pStringPosition)
{
this.v1 = v1;
this.v2 = v2;
this.nCost = nCost;
this.pStringPosition = pStringPosition;
}
#region IComparable Members
public int CompareTo(object obj)
{
Edge e = (Edge)obj;
return this.nCost.CompareTo(e.nCost);
}
#endregion
internal static void QuickSort
(List<Edge> m_lstEdgesInitial, int nLeft, int nRight)
{
int i, j, x;
i = nLeft; j = nRight;
x = m_lstEdgesInitial[(nLeft + nRight) / 2].Cost;
do
{
while ((m_lstEdgesInitial[i].Cost < x) && (i < nRight)) i++;
while ((x < m_lstEdgesInitial[j].Cost) && (j > nLeft)) j--;
if (i <= j)
{
Edge y = m_lstEdgesInitial[i];
m_lstEdgesInitial[i] = m_lstEdgesInitial[j];
m_lstEdgesInitial[j] = y;
i++; j--;
}
} while (i <= j);
if (nLeft < j) QuickSort(m_lstEdgesInitial, nLeft, j);
if (i < nRight) QuickSort(m_lstEdgesInitial, i, nRight);
}
}
Algorithm Implementation
Sorting Edges
Edges are sorted in ascending order according to Cost using Quick Sort.
Making Sets
Initially, every Vertex is its own Root and has rank zero.
public Vertex(int nName, System.Drawing.Point pPosition)
{
this.nName = nName;
nRank = 0;
this.vRoot = this;
this.pPosition = pPosition;
}
Why This Step?
We need it to ensure that, on adding our Vertices, we are not forming a loop.
Consider this example:

The Edge BD was not considered, because B,D are already connected through B,A,D.
Thus, for every Edge we examine, we must inspect that its two Vertices belong to different sets (trees).
How To Find Out If Two Vertices Are In Different Sets?
Using the recursive function GetRoot().
internal Vertex GetRoot()
{
if (this.vRoot != this) {
this.vRoot = this.vRoot.GetRoot(); }
return this.vRoot;
}
If roots are indeed different, (each Vertex is in a different set), Join() the two Vertices.
internal static void Join(Vertex vRoot1, Vertex vRoot2)
{
if (vRoot2.nRank < vRoot1.nRank) {
vRoot2.vRoot = vRoot1; }
else {
vRoot1.vRoot = vRoot2; if (vRoot1.nRank == vRoot2.nRank) {
vRoot1.nRank++; }
}
}
Conclusion
Hope I delivered a clear explanation.