Graph Algorithm (7) --- use the query set to find the Minimum Spanning Tree
The most typical algorithm is the prim algorithm and the kruskal algorithm. In terms of time efficiency, kruskal is superior. For the implementation of kruskal, here we use the idea of querying sets.
That is to say, we first sort the edge by weight from small to large, and then traverse each edge.
When traversing each edge, we determine whether the two nodes of the edge are connected:
(1) skip this edge if it is connected;
(2) If the edge is not connected, the edge must be the smallest side in the tree and be added to the result set;
After traversing all the edges, all the edges in the result set constitute the minimal spanning tree of the undirected graph.
The purpose of the query set is to determine whether the two points on the edge are connected. If you are not familiar with the query set, we recommend that you first learn the relevant knowledge. This is very simple and will not be explained here.
The code is attached below. The key points of the Code are annotated. If you do not understand the code, leave a message.
Package test; import java. io. bufferedReader; import java. io. fileReader; import java. io. IOException; import java. util. arrayList; import java. util. comparator; import java. util. hashMap; import java. util. map; import java. util. priorityQueue; import java. util. queue; public class MinSpanningTree {class Edge {// internal class defines Edge data result int u, v, weight;} ArrayList
Edges = new ArrayList
(); Map
NodeFather = new HashMap
(); Int cnt = 0, nodeCnt = 0; public MinSpanningTree (String path) {try {BufferedReader br = new BufferedReader (new FileReader (path); String str; string [] strArray; while (str = br. readLine ())! = Null) {strArray = str. split ("\ s"); Edges. add (cnt, new Edge (); Edges. get (cnt ). u = Integer. parseInt (strArray [0]); Edges. get (cnt ). v = Integer. parseInt (strArray [1]); Edges. get (cnt ). weight = Integer. parseInt (strArray [2]); if (! NodeFather. containsKey (Edges. get (cnt ). u) {nodeFather. put (Edges. get (cnt ). u, Edges. get (cnt ). u); // initialization, father [I] = I; ++ nodeCnt;} if (! NodeFather. containsKey (Edges. get (cnt ). v) {nodeFather. put (Edges. get (cnt ). v, Edges. get (cnt ). v); ++ nodeCnt ;}++ cnt ;}br. close ();} catch (IOException e) {e. printStackTrace () ;}} public boolean union (int u, int v) {// and operate int a = find (u); int B = find (v ); if (! = B) {nodeFather. put (a, B); return true;} return false;} public int find (int x) {// query if (x! = NodeFather. get (x) {nodeFather. put (x, find (nodeFather. get (x);} return nodeFather. get (x);} public ArrayList
GetMinSpanningTree () {ArrayList
Result = new ArrayList
(); Queue
FsQueue = new PriorityQueue
(1000, // set the priority queue to sort by edge weight from small to large new Comparator
() {Public int compare (Edge EdgeOne, Edge EdgeTwo) {if (EdgeOne. weight> EdgeTwo. weight) return 1; else if (EdgeOne. weight <EdgeTwo. weight) return-1; elsereturn 0 ;}}); for (int I = 0; I <cnt; ++ I) {FsQueue. add (Edges. get (I);} while (! FsQueue. isEmpty () {// traverse each Edge = FsQueue. poll (); if (union (Edge. u, Edge. v) {result. add (Edge) ;}else {continue ;}} return result ;}public static void main (String [] args) {MinSpanningTree mstree = new MinSpanningTree ("c: /treedata.txt "); ArrayList
Result = mstree. getMinSpanningTree (); for (int I = 0; I <result. size (); ++ I) {System. out. println (result. get (I ). u + "" + result. get (I ). v + "" + result. get (I ). weight );}}}