Close
Register
Close Window

F17 OpenDSA entire modules

Chapter 19 Graphs

Show Source |    | About   «  19.6. Minimal Cost Spanning Trees   ::   Contents   ::   19.8. All-Pairs Shortest Paths  »

19.7. Kruskal's Algorithm

19.7.1. Kruskal's Algorithm

Our next MCST algorithm is commonly referred to as Kruskal's algorithm. Kruskal's algorithm is also a simple, greedy algorithm. First partition the set of vertices into \(|\mathbf{V}|\) disjoint sets, each consisting of one vertex. Then process the edges in order of weight. An edge is added to the MCST, and two disjoint sets combined, if the edge connects two vertices in different disjoint sets. This process is repeated until only one disjoint set remains.

The edges can be processed in order of weight by using a min-heap. This is generally faster than sorting the edges first, because in practice we need only visit a small fraction of the edges before completing the MCST. This is an example of finding only a few smallest elements in a list.

The only tricky part to this algorithm is determining if two vertices belong to the same equivalence class. Fortunately, the ideal algorithm is available for the purpose --- the UNION/FIND. Here is an implementation for Kruskal's algorithm. Class KruskalElem is used to store the edges on the min-heap.

// Kruskal's MST algorithm
void Kruskal(Graph G) {
  ParPtrTree A = new ParPtrTree(G.nodeCount()); // Equivalence array
  KVPair[] E = new KVPair[G.edgeCount()];       // Minheap array
  int edgecnt = 0; // Count of edges

  for (int i=0; i<G.nodeCount(); i++) {         // Put edges in the array
    int[] nList = G.neighbors(i);
    for (int w=0; w<nList.length; w++)
      E[edgecnt++] = new KVPair(G.weight(i, nList[w]), new int[]{i,nList[w]});
  }
  MinHeap H = new MinHeap(E, edgecnt, edgecnt);
  int numMST = G.nodeCount();                   // Initially n disjoint classes
  for (int i=0; numMST>1; i++) {        // Combine equivalence classes
    KVPair temp = H.removemin();        // Next cheapest edge
    if (temp == null) return;           // Must have disconnected vertices
    int v = ((int[])temp.value())[0];
    int u = ((int[])temp.value())[1];
    if (A.differ(v, u)) {               // If in different classes
      A.UNION(v, u);                    // Combine equiv classes
      AddEdgetoMST(v, u);               // Add this edge to MST
      numMST--;                         // One less MST
    }
  }
}

Kruskal's algorithm is dominated by the time required to process the edges. The differ and UNION functions are nearly constant in time if path compression and weighted union is used. Thus, the total cost of the algorithm is \(\Theta(|\mathbf{E}| \log |\mathbf{E}|)\) in the worst case, when nearly all edges must be processed before all the edges of the spanning tree are found and the algorithm can stop. More often the edges of the spanning tree are the shorter ones,and only about \(|\mathbf{V}|\) edges must be processed. If so, the cost is often close to \(\Theta(|\mathbf{V}| \log |\mathbf{E}|)\) in the average case.

   «  19.6. Minimal Cost Spanning Trees   ::   Contents   ::   19.8. All-Pairs Shortest Paths  »

nsf
Close Window