category. We loop through the process of picking the smallest weighted edge connecting a tree node with a fringe node, adding the new node to the tree, and then updating the nodes in the fringe category. When all the nodes have been added to the tree, we are done.
Our general algorithm for this process is as follows
select a starting node
build the initial fringe from nodes connected to the starting node while there are nodes left do
choose the edge to the fringe of the smallest weight add the associated node to the tree
update the fringe by:
adding nodes to the fringe connected to the new node
updating the edges to the fringe so that they are the smallest end while
Figure 6.5 gives an example of this algorithm in operation. We have arbi- trarily chosen node A to begin the process. As we said, a different choice for the starting node will not change the result, unless there is more than one MST.
The original graph is shown in Fig. 6.5(a), and as was mentioned, we choose to start the construction of the MST at node A. All of the nodes directly connected to node A become the starting fringe set. We see that the
A B
F G
D
C E
4 7
7 6
2
6 6 6
1
5 8
3
F D C B
A
2 4 7 5
■ FIGURE 6.5A The original graph
■ FIGURE 6.5B First node added. (Dashed lines show edges to fringe nodes.)
edge with the smallest weight connects nodes A and B, so B is added to the MST along with the edge AB.
When node B is added to the tree (Fig. 6.5(c)), we need to determine if there are any nodes that need to be added to the fringe set, and we find that nodes E and G must be added. Because the only tree node they are connected to is node B, we add those edges to the ones we will consider next. At this time, we also need to check to see if the edges from node A to nodes C, D, and F are still the shortest or if there are better edges from node B to these three nodes. In the original graph, there are no direct connections from node B to nodes C and F, so those will not change. But the edge from node B to node D has a smaller weight than the one from node A, and so the edge BD now replaces the edge AD.
Of the five edges to fringe nodes, we see that BE has the smallest weight, and so it and node E are added to the tree (Fig. 6.5(d)). The edge EG has a smaller weight than the edge BG, so it is now used. Of the four current edges to the fringe, we see that AC has the smallest weight and so it is added next.
4 5
6 3 8
B D
E F C
G A
5
6
7 4 A
B D
F C
E G
■ FIGURE 6.5C Second node added.
Edges to nodes D, E, and G updated. (Solid lines show edges in the MST.)
■ FIGURE 6.5D Third node added. Edge to node G updated.
The addition of node C and edge AC to the spanning tree (Fig. 6.5(e)) did not cause any edges to be updated. We next choose the edge AF, so it and the node F are added to the tree. We also update the links because the edge FD has a smaller weight than BD and edge FG has a smaller weight than EG. In the resulting fringe (Fig. 6.5(f )), we see that the edge FD is now the remaining edge with the smallest weight, so it is added next.
We now just have one node that has not been added to the tree (Fig. 6.5(g)).
When it is added, the process is complete, and we have determined the MST rooted at node A (Fig. 6.5(h)).
5
6
7 A
B D
G F
E
C 1
6
B
G D
E F
A C
■ FIGURE 6.5E Node C added to the tree
■ FIGURE 6.5F Node F added to the tree and edges to nodes D and G are updated
6
B
G
E F D
A C
B
E A
D F
C 4 5 6 G
2 1
3
■ FIGURE 6.5G Only one node is left in the fringe
■ FIGURE 6.5H The complete minimum spanning tree rooted at node A
■ 6.4.2 The Kruskal Algorithm
Where the Dijkstra-Prim algorithm began at a particular node and built the minimum spanning tree outward, Kruskal’s algorithm concentrates instead on the edges of the graph.
In this algorithm, we begin with an empty spanning tree and add edges in order of increasing weight until all nodes are connected to the graph. If we run out of edges before all of the nodes are connected, the original graph wasn’t connected, and the result we have generated is the MSTs of each of the con- nected components of the original graph.
We begin in Fig. 6.6(a) with the same graph that we used for the Dijkstra- Prim algorithm. In this case, we first add the edge with the lowest weight, which is the one between nodes D and F, giving the partial results in Fig.
6.6(b).
The edge with weight 2 is added next (Fig. 6.6(c)) between the nodes A and B, and then the edge with weight three is added, giving us Fig. 6.6(d).
The edges with weights of 4 and 5 are next added to our result, as you can see in Figs. 6.6(e) and 6.6(f). Only node G is still unconnected. The next edges to consider are those with a weight of 6.
Of the four edges with a weight of 6, two are discarded because they would form a cycle with edges already part of the MST. The edge between nodes C and F would form a cycle that includes node A, and the edge between node B and D would form a cycle that includes nodes A and F. The other two nodes are both good alternatives, and depending on the one chosen, we get the MST in either Fig. 6.6(g) or Fig. 6.6(h).
A B
F G
D
C E
4 7
7 6
2
6 6 6
1
5 8
3
A B
F G
D
C E
1
■ FIGURE 6.6A The original graph
■ FIGURE 6.6B First edge added
A B
F G
D
C E
1
2 A B
F G
D
C E
1 2
3
■ FIGURE 6.6C Second edge added
■ FIGURE 6.6D Third edge added
A B
F G
D
C E
1 2
3 4
A B
F G
D
C E
1 2
3 5
4
■ FIGURE 6.6E Fourth edge added
■ FIGURE 6.6F Fifth edge added
A B
F G
D
C E
1 6
2
3 5
4
A B
F G
D
C E
1 6 2
3 5
4
■ FIGURE 6.6G A minimum spanning tree
■ FIGURE 6.6H An alternative minimum spanning tree
The general algorithm that will accomplish this is (where E represents the number of edges and N the number of vertices)
sort the edges in nondecreasing order by weight initialize partition structure
edgeCount = 1 includedCount = 0
while edgeCount ≤ E and includedCount ≤ N-1 do parent1 = FindRoot( edge[edgeCount].start ) parent2 = FindRoot( edge[edgeCount].end ) if parent1 ≠ parent2 then
add edge[edgeCount] to spanning tree includedCount = includedCount + 1 Union( parent1, parent2 )
end if
edgeCount = edgeCount + 1 end while
Our main loop will continue until the edgeCount variable indicates that we have looked at all of the edges or the includedCount indicates that we have added enough edges to create the spanning tree. You should see that if we have N nodes in the graph, a spanning tree would have one less edge than nodes.
Inside the loop, we first find the parents of the two nodes that are connected by the next edge we are considering. If those nodes are in partitions with dif- ferent roots, adding an edge between them will not create a cycle, so this cur- rent edge can be added to the MST and those two pieces can be joined so that they now have the same root. The details of the FindRoot and Union rou- tines will be given in Section 6.7.
The complexity of this algorithm will be the complexity of the sort algo- rithm used because the while loop is linearly related to the number of edges.
This makes the complexity of Kruskal’s MST algorithm O(E lg E).
6.4.3
1. Find the minimum spanning tree using the Dijkstra-Prim algorithm for the following graphs starting at node A. Show all steps.
2. Find the minimum spanning tree using the Kruskal algorithm for the graphs in question 1. Show all steps.
3. Do an analysis of the Dijkstra-Prim minimum spanning tree algorithm, counting the number of times that an edge is considered for nodes added to the fringe, for updating edges to the fringe nodes, or to pick the node to move from the fringe to the minimum spanning tree.
4. Prove that if there is one edge with a weight smaller than all of the other edges, that edge will be part of every minimum spanning tree.
5. Prove that if a connected graph has edge weights that are all distinct (in other words, no two edges have the same weight), there is only one mini- mum spanning tree.
6.4.3 EXERCISES
■
A B C
F G H
D E
4
1 1
1 2
2 2
5 4
4
4
4 2 2
2 3
3 3
3 5
6 6
3
a. b. A B
D E
F G
C
A B C
H
F G
D E
4 5
4 1
2 2
5 2 4
1
1 4
2 1
3
2 2
3 5
5
2 3
2
c. d. A
B
D E
G H C
F 2
6. Prove whether it is always, never, or sometimes true that the order in which the nodes are added to the MST by the Dijkstra–Prim algorithm is the same as the order in which they are encountered in a breadth-first traversal.
7. Prove whether it is always, never, or sometimes true that the order in which the nodes are added to the MST by the Dijkstra–Prim algorithm is the same as the order in which they are encountered in a depth-first traversal.