UnionFindUniverse.cpp

Go to the documentation of this file.
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