Implement Kruskals Algorithm in Golang


In this article we are going to understand how to develop a golang program to implement kruskals Algorithm with the help of union-find Algorithm and priority queue approach. Kruskal's Algorithm is used to find the minimum spanning tree of a graph.

Algorithm

  • Step 1 − First, we need to import the fmt and sort packages. Then create structures called Edge, graph and subset and assign properties to it.

  • Step 2 − Then sort all the edges of the graph in non-decreasing order of their weight.

  • Step 3 − Create a disjoint set data structure, where each set contains only one vertex.

  • Step 4 − For each edge in the sorted graph. If the edge connects two disjoint sets then we need to add it to the minimum spanning tree and merge the two sets. At last return the minimum spanning tree.

  • Step 5 − Now, start the main() function. Inside the main() function initialize a graph and assign edges to it. Further call the kruskals() function by passing the edge as argument to it.

  • Step 6 − Store the result obtained by the function in a variable and print them on the screen.

Example 1

In this Example we will write a go language program to implement Kruskals Algorithm by using union-find Algorithm.

package main

import (
   "fmt"
   "sort"
)

type Edge struct {
   Src, Dest, Weight int
}

type Graph struct {
   Edges    []Edge
   Vertices int
}

type Subset struct {
   Parent int
   Rank   int
}

func find(subsets []Subset, i int) int {
   if subsets[i].Parent != i {
      subsets[i].Parent = find(subsets, subsets[i].Parent)
   }
   return subsets[i].Parent
}

func union(subsets []Subset, x, y int) {
   rootX := find(subsets, x)
   rootY := find(subsets, y)
   if subsets[rootX].Rank < subsets[rootY].Rank {
      subsets[rootX].Parent = rootY
   } else if subsets[rootX].Rank > subsets[rootY].Rank {
      subsets[rootY].Parent = rootX
   } else {
      subsets[rootY].Parent = rootX
      subsets[rootX].Rank++
   }
}

func kruskals(graph Graph) []Edge {
   sortedEdges := make([]Edge, len(graph.Edges))
   copy(sortedEdges, graph.Edges)
   sort.Slice(sortedEdges, func(i, j int) bool {
      return sortedEdges[i].Weight < sortedEdges[j].Weight
   })
   subsets := make([]Subset, graph.Vertices)
   for i := range subsets {
      subsets[i].Parent = i
      subsets[i].Rank = 0
   }
   result := make([]Edge, 0, graph.Vertices-1)
   for _, edge := range sortedEdges {
      srcRoot := find(subsets, edge.Src)
      destRoot := find(subsets, edge.Dest)
      if srcRoot != destRoot {
         result = append(result, edge)
         union(subsets, srcRoot, destRoot)
      }
   }
   return result
}

func main() {
   graph := Graph{
      Edges: []Edge{
         {0, 1, 10},
         {0, 2, 6},
         {0, 3, 5},
         {1, 3, 15},
         {2, 3, 4},
      },
      Vertices: 4,
   }
   fmt.Println("The given input is:", graph)
   fmt.Println()
   mst := kruskals(graph)
   fmt.Println("Minimum Spanning Tree:")
   for _, edge := range mst {
      fmt.Printf("(%d, %d) with weight %d\n", edge.Src, edge.Dest, edge.Weight)
   }
}

Output

The given input is: {[{0 1 10} {0 2 6} {0 3 5} {1 3 15} {2 3 4}] 4}

Minimum Spanning Tree:
(2, 3) with weight 4
(0, 3) with weight 5
(0, 1) with weight 10

Example 2

In this Example we will write a go language program to implement the kruskals Algorithm by using the priority queue Algorithm.

package main

import (
   "container/heap"
   "fmt"
)

type Edge struct {
   Src    int
   Dest   int
   Weight int
}

type Graph struct {
   Edges    []Edge
   Vertices int
}

type PriorityQueue []*Item

type Item struct {
   value    Edge
   priority int
   index    int
}

func (pq PriorityQueue) Len() int { return len(pq) }
func (pq PriorityQueue) Less(i, j int) bool {
   return pq[i].priority < pq[j].priority
}
func (pq PriorityQueue) Swap(i, j int) {
   pq[i], pq[j] = pq[j], pq[i]
   pq[i].index = i
   pq[j].index = j
}
func (pq *PriorityQueue) Push(x interface{}) {
   n := len(*pq)
   item := x.(*Item)
   item.index = n
   *pq = append(*pq, item)
}
func (pq *PriorityQueue) Pop() interface{} {
   old := *pq
   n := len(old)
   item := old[n-1]
   item.index = -1 // for safety
   *pq = old[0 : n-1]
   return item
}

func find(subsets []int, i int) int {
   if subsets[i] != i {
      subsets[i] = find(subsets, subsets[i])
   }
   return subsets[i]
}

func union(subsets []int, x int, y int) {
   xroot := find(subsets, x)
   yroot := find(subsets, y)
   subsets[yroot] = xroot
}

func kruskals(graph Graph) []Edge {
   pq := make(PriorityQueue, len(graph.Edges))
   for i, edge := range graph.Edges {
      pq[i] = &Item{
         value:    edge,
         priority: edge.Weight,
         index:    i,
      }
   }
   heap.Init(&pq)
   subsets := make([]int, graph.Vertices)
   for i := range subsets {
      subsets[i] = i
   }
   result := make([]Edge, 0, graph.Vertices-1)
   for pq.Len() > 0 {
      item := heap.Pop(&pq).(*Item)
      edge := item.value
      srcRoot := find(subsets, edge.Src)
      destRoot := find(subsets, edge.Dest)
      if srcRoot != destRoot {
         result = append(result, edge)
         
         // Update the parent node of the subset containing the src vertex
         union(subsets, edge.Src, edge.Dest) 
      }
   }
   return result
}

func main() {
   graph := Graph{
      Edges: []Edge{
         {0, 1, 10},
         {0, 2, 6},
         {0, 3, 5},
         {1, 3, 15},
         {2, 3, 4},
      },
      Vertices: 4,
   }
   fmt.Println("The given input is:", graph)
   mst := kruskals(graph)
   fmt.Println()
   fmt.Println("Minimum Spanning Tree:")
   for _, edge := range mst {
      fmt.Printf("(%d, %d) with weight %d\n", edge.Src, edge.Dest, edge.Weight)
   }
}

Output

The given input is: {[{0 1 10} {0 2 6} {0 3 5} {1 3 15} {2 3 4}] 4}

Minimum Spanning Tree:
(2, 3) with weight 4
(0, 3) with weight 5
(0, 1) with weight 10

Conclusion

We have successfully compiled and executed a go language program to implement the Kruskal's Algorithm along with Examples.

Updated on: 05-Apr-2023

199 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements