Grafalgo
Library of useful data structures and algorithms
|
00001 00008 #include "LheapSet.h" 00009 00010 #define kee(x) node[x].kee 00011 #define rank(x) node[x].rank 00012 #define left(x) node[x].left 00013 #define right(x) node[x].right 00014 00015 namespace grafalgo { 00016 00020 LheapSet::LheapSet(int size) : Adt(size) { 00021 makeSpace(size); 00022 } 00023 00025 LheapSet::~LheapSet() { freeSpace(); } 00026 00030 void LheapSet::makeSpace(int size) { 00031 try { 00032 node = new hnode[size+1]; 00033 } catch (std::bad_alloc e) { 00034 stringstream ss; 00035 ss << "makeSpace:: insufficient space for " 00036 << size << "index values"; 00037 string s = ss.str(); 00038 throw OutOfSpaceException(s); 00039 } 00040 nn = size; clear(); 00041 } 00042 00044 void LheapSet::freeSpace() { delete [] node; } 00045 00047 void LheapSet::copyFrom(const LheapSet& source) { 00048 if (&source == this) return; 00049 if (source.n() > n()) resize(source.n()); 00050 else clear(); 00051 for (int i = 1; i <= source.n(); i++) { 00052 node[i] = source.node[i]; 00053 } 00054 } 00055 00060 void LheapSet::resize(int size) { 00061 freeSpace(); 00062 try { makeSpace(size); } catch(OutOfSpaceException e) { 00063 string s; s = "LheapSet::resize::" + e.toString(s); 00064 throw OutOfSpaceException(s); 00065 } 00066 } 00067 00072 void LheapSet::expand(int size) { 00073 if (size <= n()) return; 00074 LheapSet old(n()); old.copyFrom(*this); 00075 resize(size); this->copyFrom(old); 00076 } 00077 00079 void LheapSet::clear() { 00080 for (int i = 1; i <= n(); i++) { 00081 left(i) = right(i) = 0; rank(i) = 1; kee(i) = 0; 00082 } 00083 rank(0) = 0; left(0) = right(0) = 0; 00084 } 00085 00092 lheap LheapSet::meld(lheap h1, lheap h2) { 00093 assert(0 <= h1 && h1 <= n() && 0 <= h2 && h2 <= n()); 00094 if (h1 == 0) return h2; 00095 else if (h2 == 0) return h1; 00096 if (kee(h1) > kee(h2)) { 00097 lheap t = h1; h1 = h2; h2 = t; 00098 } 00099 right(h1) = meld(right(h1),h2); 00100 if (rank(left(h1)) < rank(right(h1))) { 00101 lheap t = left(h1); left(h1) = right(h1); right(h1) = t; 00102 } 00103 rank(h1) = rank(right(h1)) + 1; 00104 return h1; 00105 } 00106 00114 lheap LheapSet::insert(index i, lheap h) { 00115 assert(0 <= i && i <= n() && 0 <= h && h <= n()); 00116 assert(left(i) == 0 && right(i) == 0 && rank(i) ==1); 00117 return meld(i,h); 00118 } 00119 00124 index LheapSet::deletemin(lheap h) { 00125 lheap h1 = meld(left(h),right(h)); 00126 left(h) = right(h) = 0; rank(h) = 1; 00127 return h1; 00128 } 00129 00134 string& LheapSet::toString(string& s) const { 00135 s = ""; 00136 int i; bool *isroot = new bool[n()+1]; 00137 for (i = 1; i <= n(); i++) isroot[i] = true; 00138 for (i = 1; i <= n(); i++) 00139 isroot[left(i)] = isroot[right(i)] = false; 00140 for (i = 1; i <= n(); i++) { 00141 if (isroot[i] && (left(i) != 0 || right(i) != 0)) { 00142 string s1; s += heap2string(i,s1) + "\n"; 00143 } 00144 } 00145 delete [] isroot; 00146 return s; 00147 } 00148 00155 string& LheapSet::heap2string(lheap h, bool isroot, string& s) const { 00156 s = ""; 00157 if (h == 0) return s; 00158 stringstream ss; 00159 if (left(h) == 0 && right(h) == 0) { 00160 ss << item2string(h,s) << ":" << kee(h) << "," << rank(h); 00161 } else { 00162 ss << "("; 00163 if (left(h) != 0) ss << heap2string(left(h),false,s) << " "; 00164 ss << item2string(h,s) << ":" << kee(h) << "," << rank(h); 00165 if (isroot) ss << "*"; 00166 if (right(h) != 0) ss << " " << heap2string(right(h),false,s); 00167 ss << ")"; 00168 } 00169 s = ss.str(); 00170 return s; 00171 } 00172 00173 } // ends namespace