Grafalgo
Library of useful data structures and algorithms
/Users/jst/src/grafalgo/cpp/dataStructures/basic/Partition.cpp
Go to the documentation of this file.
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
 All Classes Files Functions Variables Typedefs Friends