00001 00021 #include "UnionFindUniverse.hpp" 00022 00023 00024 #define UF_NIL -1 00025 00026 namespace OA { 00027 00028 //*********************************************************************************************** 00029 // internal class UnionFindElement 00030 //*********************************************************************************************** 00031 00032 class UnionFindElement { 00033 public: 00034 UnionFindElement() { }; 00035 00036 int &Count() { return count; }; 00037 int &Root() { return root; }; 00038 int &Parent() { return parent; } 00039 int &Name() { return name; } 00040 void Init(int i); 00041 private: 00042 int parent; 00043 int name; 00044 int count; 00045 int root; 00046 }; 00047 00048 00049 void UnionFindElement::Init(int i) 00050 { 00051 name = root = i; 00052 parent = UF_NIL; 00053 count = 1; 00054 } 00055 00056 00057 //*********************************************************************************************** 00058 // class UnionFindUniverse interface operations 00059 //*********************************************************************************************** 00060 00061 00062 UnionFindUniverse::UnionFindUniverse(unsigned int highWaterMark) 00063 { 00064 e = new UnionFindElement[highWaterMark]; 00065 00066 for (unsigned int i = 0; i < highWaterMark; i++) { 00067 e[i].Init(i); 00068 } 00069 } 00070 00071 UnionFindUniverse::~UnionFindUniverse() 00072 { 00073 if (e) 00074 delete [] e; 00075 } 00076 00077 00078 int UnionFindUniverse::Find(int v) 00079 { 00080 if (Parent(v) == UF_NIL) 00081 return Name(v); 00082 00083 Parent(v) = do_FIND(Parent(v)); 00084 00085 return Name(Parent(v)); 00086 } 00087 00088 00089 void UnionFindUniverse::Union(int i, int j, int k) 00090 { 00091 if ((i == j) && (j == k)) 00092 return; 00093 00094 int large, small; 00095 if (Count(Root(i)) > Count(Root(j))) { 00096 large = Root(i); 00097 small = Root(j); 00098 } else { 00099 large = Root(j); 00100 small = Root(i); 00101 } 00102 00103 Parent(small) = large; 00104 Count(large) += Count(small); 00105 Name(large) = k; 00106 Root(k) = large; 00107 } 00108 00109 00110 00111 //*********************************************************************************************** 00112 // class UnionFindUniverse private operations 00113 //*********************************************************************************************** 00114 00115 int UnionFindUniverse::do_FIND(int v) 00116 { 00117 if (Parent(v) == UF_NIL) 00118 return v; 00119 00120 Parent(v) = do_FIND(Parent(v)); 00121 00122 return Parent(v); 00123 } 00124 00125 int &UnionFindUniverse::Count(int i) 00126 { 00127 return e[i].Count(); 00128 } 00129 00130 int &UnionFindUniverse::Root(int i) 00131 { 00132 return e[i].Root(); 00133 } 00134 int &UnionFindUniverse::Parent(int i) 00135 { 00136 return e[i].Parent(); 00137 } 00138 00139 int &UnionFindUniverse::Name(int i) 00140 { 00141 return e[i].Name(); 00142 } 00143 00144 } // end of namespace OA
1.7.1