Grafalgo
Library of useful data structures and algorithms
|
00001 00009 #include "Partition.h" 00010 00011 #define p(x) node[x].p 00012 #define rank(x) node[x].rank 00013 00014 namespace grafalgo { 00015 00019 Partition::Partition(int nn, int noOpt1) : Adt(nn) { 00020 makeSpace(n()); 00021 } 00022 00024 Partition::~Partition() { freeSpace(); } 00025 00029 void Partition::makeSpace(int size) { 00030 try { node = new pnode[size+1]; } catch (std::bad_alloc e) { 00031 stringstream ss; 00032 ss << "Partition::makeSpace: insufficient space for " 00033 << size << "elements"; 00034 string s = ss.str(); 00035 throw OutOfSpaceException(s); 00036 } 00037 nn = size; clear(); 00038 } 00039 00041 void Partition::freeSpace() { delete [] node; } 00042 00047 void Partition::resize(int size) { 00048 freeSpace(); 00049 try { makeSpace(size); } catch(OutOfSpaceException e) { 00050 string s; s = "Partition::resize:" + e.toString(s); 00051 throw OutOfSpaceException(s); 00052 } 00053 } 00054 00059 void Partition::expand(int size) { 00060 if (size <= n()) return; 00061 Partition old(this->n()); 00062 old.copyFrom(*this); 00063 resize(size); 00064 this->copyFrom(old); 00065 } 00066 00068 void Partition::clear() { 00069 for (index x = 0; x <= n(); x++) { p(x) = x; rank(x) = 0; } 00070 } 00071 00073 void Partition::copyFrom(const Partition& source) { 00074 if (&source == this) return; 00075 if (source.n() > n()) resize(source.n()); 00076 else clear(); 00077 for (index x = 1; x <= source.n(); x++) { 00078 p(x) = source.node[x].p; rank(x) = source.node[x].rank; 00079 } 00080 } 00081 00086 index Partition::find(index x) { 00087 index root; 00088 for (root = x; p(root) != root; root = p(root)) ; 00089 while (x != root) { int px = p(x); p(x) = root; x = px; } 00090 return p(x); 00091 } 00092 00099 index Partition::link(index x, index y) { 00100 if (rank(x) > rank(y)) { 00101 index t = x; x = y; y = t; 00102 } else if (rank(x) == rank(y)) 00103 rank(y)++; 00104 return p(x) = y; 00105 } 00106 00111 int Partition::findroot(int x) const { 00112 if (x == p(x)) return(x); 00113 else return findroot(p(x)); 00114 } 00115 00120 string& Partition::toString(string& s) const { 00121 s = "{"; 00122 int *size = new int[n()+1]; 00123 int *root = new int[n()+1]; 00124 for (int i = 1; i <= n(); i++) { root[i] = findroot(i); size[i] = 0; } 00125 for (int i = 1; i <= n(); i++) size[root[i]]++; 00126 // for root nodes x, size[x] is number of nodes in tree 00127 bool isFirst = true; 00128 for (int i = 1; i <= n(); i++) { 00129 if (size[i] > 1) { // i is a root of non-trivial block 00130 int j; 00131 for (j = 1; root[j] != i; j++) {} 00132 string s1; 00133 if (isFirst) isFirst = false; 00134 else s += " "; 00135 s += "[" + Adt::item2string(j,s1); 00136 if (j == i) s += "*"; 00137 for (j++; j <= n(); j++) { 00138 if (root[j] == i) { 00139 s += " " + Adt::item2string(j,s1); 00140 if (j == i) s += "*"; 00141 } 00142 } 00143 s += "]"; 00144 } 00145 } 00146 s += "}"; 00147 delete [] size; delete [] root; 00148 return s; 00149 } 00150 00151 } // ends namespace