00001 /**************************************************** 00002 * Bachelor Project: * 00003 * External Memory Minimum Spanning Trees * 00004 * by Dominik Schultes <mail@dominik-schultes.de> * 00005 * * 00006 * kruskal.h * 00007 * * 00008 * April 13, 2003 * 00009 ****************************************************/ 00010 00011 #ifndef KRUSKAL_H 00012 #define KRUSKAL_H 00013 00014 #include <vector> 00015 00016 #include "../data_structures/edgeVector.h" 00017 #include "../data_structures/mst.h" 00018 00023 template < typename EdgeType = Edge > 00024 class Kruskal 00025 { 00026 public: 00032 Kruskal(EdgeVector<EdgeType> &graph, MST &result) 00033 : _graph( graph ), _result( result ) 00034 { 00035 computeMST(); 00036 } 00037 00042 ~Kruskal() {delete &_graph;} 00043 00044 private: 00046 void computeMST(); 00047 00049 void initUnionFind(); 00050 00051 00059 NodeID find(NodeID node); 00060 00065 bool unite(NodeID node1, NodeID node2); 00066 00067 00069 EdgeVector<EdgeType> &_graph; 00070 00072 MST &_result; 00073 00078 std::vector<NodeID> _parent; 00079 00084 std::vector<char> _height; 00085 00087 EdgeCount edgesAddedToResult; 00088 00089 }; 00090 00091 00099 template < typename EdgeType > 00100 inline NodeID Kruskal<EdgeType>::find(NodeID node) 00101 { 00102 // find the root 00103 NodeID root = node; 00104 while (_parent[root] != root) root = _parent[root]; 00105 00106 // apply path compression 00107 NodeID tmp; 00108 while (_parent[node] != node) { 00109 tmp = _parent[node]; 00110 _parent[node] = root; 00111 node = tmp; 00112 } 00113 00114 return root; 00115 } 00116 00121 template < typename EdgeType > 00122 inline bool Kruskal<EdgeType>::unite(NodeID node1, NodeID node2) 00123 { 00124 NodeID root1 = find(node1); 00125 NodeID root2 = find(node2); 00126 00127 // A cycle would be produced. Therefore the union operation is cancelled. 00128 if (root1 == root2) return false; 00129 00130 // Add the smaller tree to the bigger tree 00131 if (_height[root1] < _height[root2]) { 00132 _parent[root1] = root2; 00133 } 00134 else { 00135 _parent[root2] = root1; 00136 00137 // Increment the height of the resulting tree if both trees have 00138 // the same height 00139 if (_height[root1] == _height[root2]) _height[root1]++; 00140 } 00141 return true; 00142 } 00143 00144 00145 #endif // KRUSKAL_H