DSQSS
1.1
|
00001 00002 #ifndef LINK_H 00003 #define LINK_H 00004 00005 #include <stdio.h> 00006 00007 //###################################################################### 00008 00009 template <class C> class Linked; 00010 template <class C> class RingIterator; 00011 template <class C> class Ring; 00012 template <class C> class Pool; 00013 00014 //###################################################################### 00015 /* 00016 inline void abort() { 00017 printf("ERROR: Aborting...\n"); 00018 exit(0); 00019 }; 00020 */ 00021 //###################################################################### 00022 00023 template <class C> 00024 class Linked : public C { 00025 00026 private: 00027 00028 Linked<C>* p; 00029 Linked<C>* n; 00030 00031 public: 00032 00033 void init() { C::init(); p = this; n = this; }; 00034 00035 Linked() { init(); }; 00036 00037 ~Linked() {}; 00038 00039 Linked<C>& prev() { return *p; }; 00040 00041 Linked<C>& next() { return *n; }; 00042 00043 void set_prev(Linked<C>& x) { p = &x; }; 00044 00045 void set_next(Linked<C>& x) { n = &x; }; 00046 00047 void insert_after(Linked<C>& x); 00048 00049 void insert_before(Linked<C>& x); 00050 00051 void remove(); 00052 00053 void dump(); 00054 00055 }; 00056 00057 //###################################################################### 00058 00059 // The class C must have the following member functions 00060 // C& next() ... returns the reference to the next item 00061 // C& prev() ... returns the reference to the previous item 00062 // C& remove() ... connect prev() and next() and detatch 00063 // itself from the linked list 00064 00065 template <class C> 00066 class RingIterator { 00067 00068 private: 00069 00070 public: 00071 00072 C* org; 00073 C* cur; 00074 00075 void init(C& x) { 00076 org = &x; 00077 cur = org; 00078 }; 00079 00080 void init(Ring<C>& r) { 00081 org = &r.root(); 00082 cur = org; 00083 }; 00084 00085 RingIterator() {}; 00086 00087 RingIterator(const RingIterator& p) { 00088 org = p.org; 00089 cur = p.cur; 00090 }; 00091 00092 RingIterator(C& x) { init(x); }; 00093 00094 RingIterator(Ring<C>& r) { init(r); }; 00095 00096 bool atOrigin() {return cur == org;}; 00097 00098 RingIterator<C> operator +(int i) { 00099 RingIterator<C> p; 00100 p.org = org; 00101 p.cur = &(cur->next()); 00102 return p; 00103 }; 00104 00105 RingIterator<C>& operator ++() { 00106 cur = &(cur->next()); 00107 return *this; 00108 }; 00109 00110 RingIterator<C>& operator ++(int) { 00111 cur = &(cur->next()); 00112 return *this; 00113 }; 00114 00115 RingIterator<C>& operator --() { 00116 cur = &(cur->prev()); 00117 return *this; 00118 }; 00119 00120 RingIterator<C>& operator --(int) { 00121 cur = &(cur->prev()); 00122 return *this; 00123 }; 00124 00125 C* operator ->() { return cur; }; 00126 C& operator *() { return *cur; }; 00127 void operator =( const C* p ) { cur = p; }; 00128 bool operator ==( const C* p ) { return cur == p; }; 00129 bool operator !=( const C* p ) { return cur != p; }; 00130 00131 }; 00132 00133 //###################################################################### 00134 00135 // The class C must have the following member functions 00136 // C::C() ... A newly created object must form a ring by itself 00137 // (Its next (prev) object is itself.) 00138 // C& C::next() ... returns the reference to the next item 00139 // C& C::prev() ... returns the reference to the previous item 00140 // C& C::remove() ... connect prev() and next() and detatch 00141 // itself from the linked list 00142 00143 template <class C> 00144 class Ring { 00145 00146 friend class RingIterator<C>; 00147 00148 private: 00149 00150 // C ROOT; 00151 public: 00152 C ROOT; 00153 C& head() { return ROOT.next(); }; 00154 C& tail() { return ROOT.prev(); }; 00155 00156 00157 typedef RingIterator<C> iterator; 00158 00159 Ring() {}; 00160 00161 ~Ring() {}; 00162 00163 bool empty() { return ( &(ROOT.next()) == &ROOT ); }; 00164 00165 C& root() { return ROOT; }; 00166 00167 C& first() { return ROOT.next(); }; 00168 00169 void add_head(C& x) { 00170 ROOT.insert_after(x); 00171 }; 00172 00173 void add_tail(C& x) { 00174 ROOT.insert_before(x); 00175 }; 00176 00177 C& remove_head() { 00178 C& x = head(); 00179 x.remove(); 00180 return x; 00181 }; 00182 00183 C& remove_tail() { 00184 C& x = tail(); 00185 x.remove(); 00186 return x; 00187 }; 00188 00189 void push(C& x) { add_head(x); }; 00190 00191 C& pop() { return remove_head(); }; 00192 00193 int count(); 00194 00195 RingIterator<C> sort_min(); 00196 00197 void move_to_head(RingIterator<C>); 00198 00199 void dump() { 00200 RingIterator<C> p(*this); 00201 printf("Root: "); 00202 printf(" %8d -> %8d -> %8d\n", &(p->prev()), &(*p), &(p->next())); 00203 while ( ! (++p).atOrigin() ) p->dump(); 00204 } 00205 00206 }; 00207 00208 //###################################################################### 00209 00210 template <class C> 00211 class Pool : public Ring<C> { 00212 00213 private: 00214 00215 int size_max; 00216 int size_min; 00217 int size; 00218 00219 public: 00220 00221 Pool() : Ring<C>() { 00222 size = 0; 00223 }; 00224 00225 ~Pool(); 00226 00227 void init(int N); 00228 00229 void push(C& x) { 00230 size++; 00231 x.init(); 00232 Ring<C>::push(x); 00233 }; 00234 00235 C& pop() { 00236 if ( size == 0 ) { 00237 printf("Pool> ERROR. Attempt to extract from an empty pool.\n"); 00238 exit(0); 00239 } 00240 00241 size--; 00242 if (size < size_min ) size_min = size; 00243 C& x = Ring<C>::pop(); 00244 // x.init(); 00245 return x; 00246 }; 00247 00248 int number_of_used_elements() { return size_max - size_min; }; 00249 void set_n_of_used_elements(int s_used){ size_min = size_max - s_used; }; 00250 }; 00251 00252 //###################################################################### 00253 // Member Functions 00254 //###################################################################### 00255 00256 template <class C> 00257 inline void Linked<C>::insert_after(Linked<C>& x) { 00258 // *p -> *this -> x -> *n 00259 x.set_prev(*this); 00260 x.set_next(this->next()); 00261 next().set_prev(x); 00262 set_next(x); 00263 00264 } 00265 00266 template <class C> 00267 inline void Linked<C>::insert_before(Linked<C>& x) { 00268 x.set_prev(prev()); 00269 x.set_next(*this);//thisは、ROOTインスタンスを指す。 00270 prev().set_next(x); 00271 set_prev(x); 00272 } 00273 00274 template <class C> 00275 inline void Linked<C>::remove() { 00276 //if (ALERT) { 00277 // printf("\nLinked::remove> BEFORE\n"); 00278 // printf("Linked::remove> *this:\n"); 00279 // this->dump(); 00280 // printf("Linked::remove> prev():\n"); 00281 // prev().dump(); 00282 // printf("Linked::remove> next():\n"); 00283 // next().dump(); 00284 //} 00285 prev().set_next(next()); 00286 next().set_prev(prev()); 00287 //if (ALERT) { 00288 // printf("\nLinked::remove> AFTER\n"); 00289 // printf("Linked::remove> *this:\n"); 00290 // this->dump(); 00291 // printf("Linked::remove> prev():\n"); 00292 // prev().dump(); 00293 // printf("Linked::remove> next():\n"); 00294 // next().dump(); 00295 //} 00296 } 00297 00298 template <class C> 00299 inline void Linked<C>::dump() { 00300 printf(" %10d ->%10d ->%10d : ", &prev(), this, &next() ); 00301 C::dump(); 00302 } 00303 00304 //###################################################################### 00305 00306 template <class C> 00307 inline int Ring<C>::count() { 00308 int c = 0; 00309 RingIterator<C> p(*this); 00310 while ( ! (++p).atOrigin() ) c++; 00311 return c; 00312 } 00313 00314 //###################################################################### 00315 // C requre operation < 00316 00317 template <class C> 00318 RingIterator<C> Ring<C>::sort_min(){ 00319 RingIterator<C> p1(*this); 00320 RingIterator<C> p2(*this); 00321 ++p1;++p1; 00322 ++p2; 00323 while ( ! p1.atOrigin() ){ 00324 if( ( (*p1) < (*p2) ) || ((*p1).V_x == (*p2).V_x ) ){ 00325 p2 = p1; 00326 ++p1; 00327 move_to_head(p2) ; 00328 }else{ 00329 ++p1; 00330 } 00331 } 00332 return p2; 00333 } 00334 00335 template <class C> 00336 void Ring<C>::move_to_head(RingIterator<C> it) { 00337 C& Cmin = (*it); 00338 it->remove(); 00339 add_head(Cmin); 00340 } 00341 00342 //###################################################################### 00343 00344 template <class C> 00345 inline void Pool<C>::init(int N) { 00346 00347 // +++ edit sakakura +++ 00348 //if ( ! Ring<C>::empty() ) { 00349 // printf("Pool: ERROR. Attempt to initialize the pool twice.\n"); 00350 // exit(0); 00351 //} 00352 // +++ edit sakakura +++ 00353 00354 for (int i=0; i<N; i++) { 00355 C& x = *(new C); 00356 add_tail(x); 00357 } 00358 size = N; 00359 size_max = N; 00360 size_min = N; 00361 } 00362 00363 //====================================================================== 00364 00365 template <class C> 00366 inline Pool<C>::~Pool() { 00367 // printf("*** Destroying Pool\n"); 00368 while ( ! Ring<C>::empty() ) { 00369 C& x = pop(); 00370 delete &x; 00371 } 00372 } 00373 00374 #endif