Grafalgo
Library of useful data structures and algorithms
/Users/jst/src/grafalgo/cpp/dataStructures/heaps/LlheapSet.cpp
Go to the documentation of this file.
00001 
00009 #include "LlheapSet.h"
00010 
00011 #define kee(x) node[x].kee
00012 #define rank(x) node[x].rank
00013 #define left(x) node[x].left
00014 #define right(x) node[x].right
00015 
00016 #define deleted(x)((x > n()) || (delf != 0 && (*delf)(x)))
00017 
00018 namespace grafalgo {
00019 
00027 LlheapSet::LlheapSet(int size, delftyp f) : LheapSet(2*size) {
00028         makeSpace(size); delf = f;
00029 }
00030 
00032 LlheapSet::~LlheapSet() { freeSpace(); }
00033 
00037 void LlheapSet::makeSpace(int size) {
00038         try {
00039                 tmplst = new List(size);
00040         } catch (std::bad_alloc e) {
00041                 stringstream ss;
00042                 ss << "makeSpace:: insufficient space for "
00043                    << size << "index values";
00044                 string s = ss.str();
00045                 throw OutOfSpaceException(s);
00046         }
00047         nn = size; clear();
00048 }
00049 
00051 void LlheapSet::freeSpace() { delete tmplst; }
00052 
00054 void LlheapSet::copyFrom(const LlheapSet& source) {
00055         if (&source == this) return;
00056         if (source.n() > n()) resize(source.n());
00057         else clear();
00058         for (index i = n()+1; i <= 2*n() ; i++)
00059                 node[i] = source.node[i];
00060         dummy = source.dummy; delf = source.delf;
00061 }
00062 
00067 void LlheapSet::resize(int size) {
00068         freeSpace(); LheapSet::resize(size);
00069         try { makeSpace(size); } catch(OutOfSpaceException e) {
00070                 string s; s = "LlheapSet::resize::" + e.toString(s);
00071                 throw OutOfSpaceException(s);
00072         }
00073 }
00074 
00079 void LlheapSet::expand(int size) {
00080         if (size <= n()) return;
00081         LlheapSet old(this->n()); old.copyFrom(*this);
00082         resize(size); this->copyFrom(old);
00083 }
00084 
00086 void LlheapSet::clear() {
00087         // build list of dummy nodes linked using left pointers
00088         LheapSet::clear(); tmplst->clear();
00089         for (index i = n()+1; i <= 2*n() ; i++) left(i) = i+1;
00090         dummy = n()+1; left(2*n()) = 0;
00091         rank(0) = 0; left(0) = right(0) = 0;
00092 }
00093 
00100 lheap LlheapSet::lmeld(lheap h1, lheap h2) {
00101         assert(0 <= h1 && h1 <= 2*n() && 0 <= h2 && h2 <= 2*n() && dummy != 0);
00102         int i = dummy; dummy = left(dummy);
00103         left(i) = h1; right(i) = h2;
00104         return i;
00105 }
00106 
00112 lheap LlheapSet::insert(index i, lheap h) {
00113         assert(0 <= i && i <= n() && 0 <= h && h <= 2*n());
00114         assert(left(i) == 0 && right(i) == 0 && rank(i) ==1);
00115         tmplst->clear(); purge(h,*tmplst); h = heapify(*tmplst);
00116         return meld(i,h);
00117 }
00118 
00123 index LlheapSet::findmin(lheap h) {
00124         assert(0 <= h && h <= 2*n());
00125         tmplst->clear(); purge(h,*tmplst); return heapify(*tmplst);
00126 }
00127 
00133 lheap LlheapSet::heapify(List& hlst) {
00134         if (hlst.empty()) return 0;
00135         while (hlst.get(2) != 0) {
00136                 lheap h = meld(hlst.get(1), hlst.get(2));
00137                 hlst.removeFirst(); hlst.removeFirst(); hlst.addLast(h);
00138         }
00139         return hlst.first();
00140 }
00141 
00150 void LlheapSet::purge(lheap h, List& hlst) {
00151         if (h == 0) return;
00152         if (!deleted(h)) {
00153                 hlst.addLast(h);
00154         } else {
00155                 purge(left(h),hlst); purge(right(h),hlst);
00156                 if (h > n()) {
00157                         left(h) = dummy; dummy = h; right(h) = 0;
00158                 } else {
00159                         left(h) = right(h) = 0; rank(h) = 1;
00160                 }
00161         }
00162 }
00163 
00168 lheap LlheapSet::makeheap(List& hlst) {
00169         assert(hlst.n() <= tmplst->n());
00170         tmplst->clear();
00171         for (int i = hlst.first(); i != 0; i = hlst.next(i))
00172                 tmplst->addLast(i);
00173         return heapify(*tmplst);
00174 }
00175 
00180 string& LlheapSet::toString(string& s) const {
00181         s = "";
00182         int i; bool *isroot = new bool[n()+1];
00183         for (i = 1; i <= n(); i++) isroot[i] = true;
00184         for (i = 1; i <= n(); i++)
00185                 isroot[left(i)] = isroot[right(i)] = false;
00186         for (i = 1; i <= n(); i++) {
00187                 if (isroot[i] && (left(i) != 0 || right(i) != 0)) {
00188                         string s1; s += heap2string(i,s1) + "\n";
00189                 }
00190         }
00191         delete [] isroot;
00192         return s;
00193 }
00194 
00201 string& LlheapSet::heap2string(lheap h, bool isroot, string& s) const {
00202         s = "";
00203         if (h == 0) return s;
00204         stringstream ss;
00205         if (left(h) == 0 && right(h) == 0) {
00206                 if (deleted(h)) ss << "- ";
00207                 else ss << item2string(h,s) << ":" << kee(h) << "," << rank(h);
00208         } else {
00209                 ss << "(";
00210                 if (left(h) != 0) ss << heap2string(left(h),false,s) << " ";
00211                 if (deleted(h)) {
00212                         ss << "- ";
00213                 } else {
00214                         ss << item2string(h,s) << ":" << kee(h) << ","
00215                            << rank(h);
00216                         if (isroot) ss << "*";
00217                 }
00218                 if (right(h) != 0) ss << " " << heap2string(right(h),false,s);
00219                 ss << ")";
00220         }
00221         s = ss.str();
00222         return s;
00223 }
00224 
00225 } // ends namespace
 All Classes Files Functions Variables Typedefs Friends