00001 // Tree_V.h (c) 2004 adolfo@di-mare.com 00002 00003 /** \file Tree_V.h 00004 \brief Declaraciones y definiciones para la clase \c Tree 00005 00006 \author Adolfo Di Mare <adolfo@di-mare.com> 00007 \date 2004 00008 00009 - Why English names??? ==> http://www.di-mare.com/adolfo/binder/c01.htm#sc04 00010 */ 00011 00012 #ifndef Tree_V_h 00013 #define Tree_V_h 00014 00015 #ifndef Tdef_h_incluido 00016 #include "Tdef.h" // truco que evita que el programador necesariamente debe crear el archivo Tdef.h 00017 #endif 00018 00019 #ifndef NDEBUG // ==> Overview of File Translation ==> C++ 00020 #define USE_v_Alive 00021 #undef USE_v_Alive 00022 #endif 00023 00024 #include <cassert> // para usar assert() 00025 00026 /// Arboles de adolfo@di-mare.com cuyos nodos contienen un vector de punteros a sus hijos 00027 namespace TV { 00028 00029 /** \brief Los métodos para trabajar con árboles regresan "referencias" que son sub-árboles 00030 00031 - Un sub-árbol es parte del árbol, por lo que al modificar los valores del 00032 sub-árbol también el árbol original queda cambiado. 00033 - Para evitar este tipo de modificación indirecta, es necesario trabajar 00034 con una "copia profunda" del árbol orignal, la que se puede obtener con 00035 \c Tree::Copy_Deep(). 00036 - Aún si el árbol original es eliminado, el sub-árbol continúa existiendo 00037 - Debido a que los árboles y sub-árboles son referencias, en C++ es necesario mantener 00038 internamente "cuentas de referencia" que impiden que métodos como \c Father() o \c Root() 00039 sean métodos <code>const</code>. 00040 - Muchos métodos retornan referencias \c Tree& porque es más eficiente, pues cada 00041 vez que un \c Tree es copiado hay que actualizar la "cuenta de referencia" de 00042 la raíz del sub-árbol. 00043 */ 00044 class Tree { 00045 public: 00046 typedef Elem_Tree value_type; ///< Nombre estándar del tipo de elemento contenido 00047 private: 00048 static const unsigned N = 15; ///< Cantidad máxima de hijos por nodo 00049 /// Nodos almacenados en el árbol 00050 class Node { 00051 friend class Tree; friend class Tree; 00052 private: 00053 Node( const value_type& d ) : _data( d ), _refCount(1), _n_child(0), _father(0) {} ///< Constructor de vector 00054 static Node* Get_New(const value_type& d); 00055 void No_Children() { for (unsigned i=0; i < N; ++i) { _Lchild[i]= 0; } } ///< Pone en nulo todos los punteros a los hijos porque ni \c Get_New() ni el constructor lo hacen 00056 private: 00057 value_type _data; ///< Valor almacenado en el nodo 00058 unsigned _refCount; ///< Cantidad de punteros hacia mi 00059 int _n_child; ///< Soy el el hijo número \c "_n_child" de mi padre 00060 Node * _father; ///< Puntero al nodo padre 00061 Node * _Lchild[N]; ///< Punteros a cada uno de los hijos 00062 private: 00063 #ifdef USE_v_Alive // ==> NDEBUG ==> Overview of File Translation ==> C++ 00064 static const unsigned N_Alive = 1033; ///< Cantidad máxima posible de punteros en uso 00065 static Node * _v_Alive[N_Alive]; ///< Punteros en uso 00066 static unsigned _n_Alive; ///< Cantidad de punteros en uso 00067 #endif 00068 }; // Node 00069 00070 /// \name Constructores y destructor 00071 //@{ 00072 public: 00073 Tree() : _root(0) {} ///< Constructor de vector 00074 Tree(Tree& o); 00075 Tree(const value_type & d); 00076 ~Tree(); 00077 private: 00078 /// Constructor a partir de un nodo 00079 Tree(Node* p) : _root(p) { if (p!=0) { p->_refCount++; } } 00080 /// Truco para usar el constructor que no verifica <code> (p != 0) </code> 00081 typedef void NOT_null_pointer; 00082 /// Constructor a partir de un nodo [ requiere <code> p != 0 </code> ] 00083 Tree(NOT_null_pointer* p) : _root( (Node*)p) { // assert( p != 0 ); 00084 ((Node*)p)->_refCount++; } 00085 //@} 00086 00087 /// \name Operaciones básicas 00088 //@{ 00089 public: 00090 bool Empty() const { return (_root == 0); } ///< Retorna \c "true" si el sub-árbol está vacío 00091 unsigned Count() const ; 00092 unsigned Count_Children() const ; 00093 unsigned Size () const { return Count(); } ///< Usa \c Count() para retornar la cantidad de valores almacenados en el sub-árbol 00094 friend bool Check_Ok(Tree& T); 00095 bool Ok() { return Check_Ok(*this); } ///< Usa \c Check_Ok(Tree& T) para verificar la invariante de \c Tree 00096 //@} 00097 00098 /// \name Operaciones de borrado 00099 //@{ 00100 public: 00101 void Erase(); 00102 void Erase_Son(unsigned n) { Graft(n, Tree()); } 00103 //@} 00104 00105 /// \name Operaciones de copiado 00106 //@{ 00107 public: 00108 Tree& operator= (Tree &o) { return Copy(o); } ///< Sinónimo de \c this->Copy(o) 00109 Tree& Copy (Tree &o); 00110 Tree& Move (Tree &o); 00111 Tree& Swap (Tree &o); 00112 Tree& Copy_Deep( const Tree &o ); 00113 /// Usa \c Change_Root() para sustituir por "d" el valor almacenado en la raíz del árbol 00114 Tree& operator=( const value_type & d) { Change_Root(d); return *this; } 00115 //@} 00116 00117 /// \name Métodos para cambiar los valores almacenados en el árbol 00118 //@{ 00119 public: 00120 Tree Change_Root(const value_type &d); 00121 Tree Change_Child( unsigned n, const value_type &d ); 00122 Tree Change_Left_Sibling_Inmediate( const value_type &d ); 00123 Tree Change_Right_Sibling_Inmediate( const value_type &d ); 00124 Tree Graft( unsigned n, Tree &o ); 00125 //@} 00126 00127 /// \name Operaciones para usar los valores almacenados 00128 //@{ 00129 public: 00130 value_type& Data () { return _root->_data; } ///< Valor almacenado en la raíz del sub-árbol 00131 value_type& operator * () { return Data(); } ///< Valor almacenado en la raíz del sub-árbol 00132 value_type* operator -> () { return &(_root->_data); } ///< Puntero al valor almacenado en la raíz del sub-árbol 00133 //@} 00134 00135 /// \name Operaciones de comparación 00136 //@{ 00137 public: 00138 friend bool operator == (const Tree &p, const Tree &q); ///< ¿¿¿ (p == q) ??? 00139 friend bool operator != (const Tree &p, const Tree &q); ///< ¿¿¿ (p != q) ??? 00140 bool Equals( const Tree & o ) const { return (*this)==o; } ///< ¿¿¿ (*this==o) ??? 00141 /// Retorna \c true si \c "o" comparte la raíz con \c "*this" 00142 bool Same( const Tree & o ) const { return _root == o._root; } 00143 //@} 00144 00145 /// \name Métodos para recorrer el árbol 00146 //@{ 00147 public: 00148 Tree Root() { return Tree( _root ); } ///< Raíz del sub-árbol 00149 Tree Father(); 00150 Tree Child(unsigned n); 00151 Tree Left(); 00152 Tree Right(); 00153 Tree Leftmost(); 00154 Tree Rightmost(); 00155 Tree Sibling(int n); 00156 Tree Left_Sibling(); 00157 Tree Right_Sibling(); 00158 Tree Previous_Sibling() { return Left_Sibling(); } ///< Sinónimo de \c Left_Sibling() 00159 Tree Prev_Sibling() { return Left_Sibling(); } ///< Sinónimo de \c Left_Sibling() 00160 Tree Next_Sibling() { return Right_Sibling(); } ///< Sinónimo de \c Right_Sibling() 00161 Tree Right_Sibling_Inmediate(); 00162 Tree Left_Sibling_Inmediate(); 00163 //@} 00164 00165 /// \name Propiedades del árbol 00166 //@{ 00167 public: 00168 /// Retorna \c "n" si \c "*this" es el n-ésimo hijo de su padre, si no retorna \c 0 (cero) 00169 unsigned Child_Number() { return ( _root==0 ? 0 : _root->_n_child ); } 00170 /// Retorna \c "n" si el hijo más izquierdo de \c "*this" es el n-ésimo hijo, si no retorna \c 0 (cero) 00171 unsigned Leftmost_N() { return Leftmost().Child_Number(); } 00172 /// Retorna \c "n" si el hijo más derecho de \c "*this" es el n-ésimo hijo, si no retorna \c 0 (cero) 00173 unsigned Rightmost_N() { return Rightmost().Child_Number(); } 00174 /// Retorna \c "true" si el árbol es una hoja 00175 bool Is_Leaf() { return ( ! Empty() && Leftmost().Empty() ); } 00176 /// Retorna \c "true" si el árbol no tiene padre 00177 bool Is_Root() { return ( _root != 0 && _root->_father == 0 ); } 00178 /// Cantidad de referencias de la raíz del árbol 00179 unsigned Nref() { return (_root==0 ? 0 : _root->_refCount); } 00180 //@} 00181 00182 /// \name Funciones para manipular valores a bajo nivel 00183 //@{ 00184 private: 00185 /// Convierte el puntero al nodo en un referencia a \c Tree 00186 static Tree& CastTo_Tree_Ref ( Node * &p ) 00187 { return (Tree&) *( reinterpret_cast<Tree*> (&p)); } 00188 //@} 00189 00190 /// \name Funciones recursivas que realizan el trabajo sobre nodos 00191 //@{ 00192 private: 00193 static void Erase0(Node * p); 00194 static bool Comp0(const Node *p, const Node *q); 00195 static void Count0(const Node * p, unsigned & n); 00196 static Node* Copy_Deep0(Node * father, const Node * p); 00197 friend class Tree; 00198 //@} 00199 private: 00200 Tree::Node * _root; ///< Un árbol "es" el puntero al nodo raíz 00201 }; // Tree 00202 00203 #ifdef USE_v_Alive 00204 unsigned Tree::Node::_n_Alive = 0; // Hay que "repetir" estos nombres acá para que el ... 00205 Tree::Node* Tree::Node::_v_Alive[Tree::Node::N_Alive]; // ... compilador les asigne memoria 00206 #endif 00207 00208 /** Crea un nuevo nodo y lo inicializa con \c "d" 00209 00210 - Para mejorar la eficiencia, no incializa los punteros a los hijos. 00211 - Si la macro \c USE_v_Alive de compilación existe, también agrega el nuevo 00212 nodo al contenedor global \c Tree::_v_Alive[], de manera que es posible 00213 saber si un puntero a un nodo está o no en uso. 00214 - En realidad sobra usar este método, pero la utilidad de usarlo es 00215 que es posible examinar \c Tree::_v_Alive[] para saber si los métodos 00216 de árbol están correctamente implementados. 00217 */ 00218 inline Tree::Node * Tree::Node::Get_New( const Tree::value_type& d) { 00219 Node* p = new Node(d); 00220 #ifdef USE_v_Alive 00221 _v_Alive[_n_Alive] = p; 00222 _n_Alive++; 00223 #endif 00224 return p; 00225 } 00226 00227 /** Constructor de copia desde otro árbol (copia superficial) 00228 00229 - Como un sub-árbol en realidad es una referencia, este método 00230 no hace la copia completa [profunda] del árbol. 00231 */ 00232 inline Tree::Tree(Tree& o) { 00233 if (o._root != 0) { 00234 o._root->_refCount++; // una referencia más porque "o" y "*this" ... 00235 } 00236 _root = o._root; // ... ahora comparten la raíz 00237 } 00238 00239 /** Destructor 00240 00241 \par Complejidad: 00242 O( \c Count() ) 00243 00244 \see http://www.di-mare.com/adolfo/binder/c04.htm#sc04 00245 */ 00246 inline Tree::~Tree() { 00247 if (_root != 0) { Erase0(_root); } 00248 } 00249 00250 /// Constructor a partir de un valor 00251 inline Tree::Tree(const Tree::value_type & d) { 00252 _root = Node::Get_New(d); 00253 _root->No_Children(); // ... pues el constructor no inicializa los punteros a los hijos 00254 } 00255 00256 /** Copia superficial desde \c "o" 00257 00258 - El valor anterior de \c "*this" se pierde 00259 00260 \par Complejidad: 00261 O( \c Count() ) 00262 00263 \returns *this 00264 00265 \see http://www.di-mare.com/adolfo/binder/c04.htm#sc05 00266 */ 00267 Tree& Tree::Copy (Tree &o) { 00268 if (_root != o._root) { // evita auto-borrado 00269 if (_root != 0) { 00270 Erase0(_root); // borra el valor actual 00271 } 00272 _root = o._root; // comparte la raíz 00273 if (o._root != 0) { 00274 o._root->_refCount++; // una referencia más 00275 } 00276 } 00277 return *this; 00278 } 00279 00280 /** Traslada el valor de \c "o" a \c "*this" 00281 00282 - El valor anterior de \c "*this" se pierde 00283 - El nuevo valor de \c "*this" es el que \c "o" tuvo 00284 - \c "o" queda en el estado en que lo dejaría \c Erase() 00285 - Si \c "*this" es \c "o" entonces su valor no cambia 00286 - En general, después de esta operación casi 00287 nunca ocurre que <code> (*this == o) </code> 00288 00289 \par Complejidad: 00290 O( \c Count() ) 00291 00292 \returns \c *this 00293 00294 \see http://www.di-mare.com/adolfo/binder/c04.htm#sc07 00295 */ 00296 Tree& Tree::Move (Tree &o) { 00297 if (_root == o._root) { // evita auto-borrado 00298 if (_root != 0) { 00299 Erase0(_root); // borra el valor actual 00300 } 00301 _root = o._root; // se roba los hijos 00302 o._root = 0; // anula al dador 00303 } 00304 return *this; 00305 } 00306 00307 /** Intercambia los valores de \c "*this" y \c "o" 00308 00309 - Debido a que algunos métodos retornan copias del valor de \c "*this" en 00310 lugar de una referencia, como ocurre con \c Tree::Child(), a veces 00311 \c Swap() no tiene el resultado esperado por el programador. 00312 - Por ejemplo, si se invoca <code> T.Child(i). Swap( T.Child(j) ) </code> 00313 el resultado no es intercambiar los hijos, sino más bien intercambiar 00314 los valores de los sub-árboles temporales \c T.Child(i) y \c T.Child(j). 00315 La forma correcta de intercambiar hijos es usar \c Graft(). 00316 00317 \par Complejidad: 00318 O( \c 1 ) 00319 00320 \returns *this 00321 00322 \see http://www.di-mare.com/adolfo/binder/c04.htm#sc08 00323 */ 00324 inline Tree& Tree::Swap (Tree &o) { 00325 Node * tmp = _root; 00326 _root = o._root; 00327 o._root = tmp; 00328 return *this; 00329 } 00330 00331 /** Acceso al padre 00332 00333 - Si el sub-árbol no tiene padre retorna el árbol vacío. 00334 00335 \par Complejidad: 00336 O( \c 1 ) 00337 00338 */ 00339 inline Tree Tree::Father() { 00340 if (_root == 0) { 00341 return Tree( ); 00342 } else { 00343 return Tree( _root->_father ); 00344 } 00345 } 00346 00347 /** Acceso al \c "n"-ésimo hijo 00348 00349 - Si el sub-árbol no tiene un hijo número \c "n" retorna el sub-árbol vacío. 00350 00351 \par Complejidad: 00352 O( \c 1 ) 00353 */ 00354 Tree Tree::Child( unsigned n ) { 00355 if (n >= Tree::N) { 00356 return Tree( ); 00357 } 00358 if (_root == 0) { // ignora árboles vacíos 00359 return Tree( ); 00360 } 00361 return Tree ( _root->_Lchild[n] ); 00362 } 00363 00364 /** Sub-árbol izquierdo [en un árbol binario] 00365 00366 - Sinónimo de \c Child(0). 00367 \par Complejidad: 00368 O( \c 1 ) 00369 */ 00370 inline Tree Tree::Left() { 00371 if (_root == 0) { 00372 return Tree( ); 00373 } else { 00374 return Tree( _root->_Lchild[0] ); 00375 } 00376 } 00377 00378 /** Sub-árbol derecho [en un árbol binario] 00379 00380 - Sinónimo de \c Child(1). 00381 00382 \par Complejidad: 00383 O( \c 1 ) 00384 */ 00385 inline Tree Tree::Right() { 00386 if (_root == 0) { 00387 return Tree( ); 00388 } else { 00389 return Tree( _root->_Lchild[1] ); 00390 } 00391 } 00392 00393 /** \typedef Tree::NOT_null_pointer 00394 \brief Truco para evitar comparar con \c 0 ( \c nil ) 00395 al usar \c Tree::Node* para construir \c Tree(). 00396 00397 Al implementar cada uno de los métodos de \c Tree con frecuencia ocurre 00398 que es posible saber que el sub-árbol retornado no está vacío. En estos casos, conviene 00399 usar un contructor que no verifique si la raíz del árbol es nula. 00400 00401 Esta clase se usa como una marca para que se ejecute el contructor 00402 <code> Tree::Tree(NOT_null_pointer* p) </code> 00403 que no verifica la nulidad de \c "_root"; esta es una micro-eficiencia, pero aquí sirve 00404 para mostrar un truco que es muy usado en C++ para aumentar la eficiencia de los 00405 programas, pues le permite al programado usar la sobrecarga de operadores para evitar 00406 repetir verificaciones innecesarias. 00407 00408 \see http://www.di-mare.com/adolfo/binder/c01.htm#k1-micro-eficiencia 00409 */ 00410 00411 /** Obtiene el hermano no vacío anterior, que está hacia la izquierda 00412 00413 - Si no existe un hermano no vacío hacia la izquierda, retorna un sub-árbol vacío. 00414 - Si <code>n == Child_Number()</code> no necesariamente ocurrirá que 00415 <code> (n-1)== Left_Sibling().Child_Number()</code> 00416 pues los anteriores hijos de \c Father() pueden ser sub-árboles vacíos, como ocurre si 00417 un árbol binario tiene hijo derecho pero no tiene hijo izquierdo. 00418 - Este método usualmente se usa junto con \c Rightmost() 00419 00420 \par Complejidad: 00421 O( <code> Father().Count_Children() </code> ) 00422 */ 00423 Tree Tree::Left_Sibling() { 00424 if (_root == 0) { 00425 return Tree( ); 00426 } 00427 if (_root->_father == 0) { 00428 return Tree( ); 00429 } 00430 00431 unsigned i = _root->_n_child; 00432 for (;;) { 00433 if (i == 0) { // tanto enredo para usar "unsigned" en lugar de "int" 00434 break; 00435 } 00436 --i; 00437 if (_root->_father->_Lchild[i] != 0) { 00438 return Tree( (NOT_null_pointer*) _root->_father->_Lchild[i] ); 00439 } 00440 } 00441 return Tree( ); // ya no hay más hermanos 00442 } 00443 00444 /** Obtiene el hermano no vacío siguiente, que está hacia la derecha 00445 00446 - Si no existe un hermano hacia la derecha, retorna un sub-árbol vacío. 00447 - Si <code>n == Child_Number()</code> no necesariamente ocurrirá que 00448 <code>(n+1) == Right_Sibling().Child_Number()</code> 00449 pues los siguientes hijos de \c Father() pueden ser sub-árboles vacíos, como ocurre si 00450 un árbol binario tiene hijo izquierdo pero no tiene hijo derecho. 00451 - Este método usualmente se usa junto con \c Leftmost() 00452 00453 \par Complejidad: 00454 O( <code> Father().Count_Children() </code> ) 00455 */ 00456 Tree Tree::Right_Sibling() { 00457 if (_root == 0) { 00458 return Tree( ); 00459 } 00460 if (_root->_father == 0) { 00461 return Tree( ); 00462 } 00463 for (unsigned i = _root->_n_child + 1; i<N; ++i) { // comienza en el hermano derecho 00464 if ( _root->_father->_Lchild[i] != 0) { 00465 return Tree ( (NOT_null_pointer*) _root->_father->_Lchild[i] ); 00466 } 00467 } 00468 return Tree( ); // ya no hay más hermanos 00469 } 00470 00471 /** Obtiene el hermano que está inmediatamente hacia la izquierda 00472 00473 - Este método es equivalente a invocar \c Sibling( -1 ) 00474 - Si no existe un hermano hacia la derecha, retorna un sub-árbol vacío. 00475 00476 \par Complejidad: 00477 O( \c 1 ) 00478 */ 00479 Tree Tree::Left_Sibling_Inmediate() { 00480 if (_root == 0) { 00481 return Tree( ); 00482 } 00483 if (_root->_father == 0) { 00484 return Tree( ); 00485 } 00486 unsigned nplus = 1 + _root->_n_child; 00487 if ( _root->_n_child == 0 ) { 00488 return Tree( ); 00489 } else { 00490 return Tree ( _root->_father->_Lchild[ _root->_n_child - 1 ] ); 00491 } 00492 } 00493 00494 /** Obtiene el hermano que está inmediatamente hacia la derecha 00495 00496 - Este método es equivalente a invocar \c Sibling( +1 ) 00497 - Si no existe ese hermano hacia la derecha, retorna un sub-árbol vacío. 00498 00499 \par Complejidad: 00500 O( \c 1 ) 00501 */ 00502 Tree Tree::Right_Sibling_Inmediate() { 00503 if (_root == 0) { 00504 return Tree( ); 00505 } 00506 if (_root->_father == 0) { 00507 return Tree( ); 00508 } 00509 unsigned nplus = 1 + _root->_n_child; 00510 if ( nplus == N ) { 00511 return Tree( ); 00512 } else { 00513 return Tree ( _root->_father->_Lchild[nplus] ); 00514 } 00515 } 00516 00517 /** \c "n"-ésimo hermano a partir de \c "*this". 00518 00519 - El hermano puede ser vacío aunque haya otros hermanos que no son vacíos. 00520 - Se "corre" hacia el n-ésimo hermano \c "n" "posiciones". 00521 - El hermano se determina contando sub-árboles hacia la derecha o izquierda de acuerdo 00522 al signo de \c "n": 00523 - Si \c n=0, regresa \c "*this". 00524 - Si \c n>0, regresa el hermano número \c "+n" contando hacia la derecha de \c "*this". 00525 - Si \c n<0, regresa el hermano número \c "-n" contando hacia la izquierda de \c "*this". 00526 - Si no existe un hermano número \c "n" retorna un sub-árbol vacío. 00527 - El árbol \c "T" tiene 3 hijos no vacíos \c "B", \c "C" y \c "E" y tiene 4 sub-árboles: 00528 - <code> C.Sibling( +0 ) == C</code> 00529 - <code> B.Sibling( +1 ) == C</code> 00530 - <code> E.Sibling( -2 ) == C</code> 00531 - <code> E.Sibling( -1 ) --> Vacío</code> 00532 - <code> A.Sibling( +1 ) --> Vacío </code> 00533 - <code> B.Sibling( -1 ) --> Vacío </code> 00534 - <code> E.Sibling( +1 ) --> Vacío </code> 00535 \code 00536 A <-- T 00537 /|\ 00538 / / \ \ [] --> es representa un sub-árbol vacío 00539 B C [] E 00540 \endcode 00541 00542 \par Complejidad: 00543 O( <code> Father().Count_Children() </code> ) 00544 */ 00545 Tree Tree::Sibling( int n ) { 00546 if (_root == 0) { 00547 return Tree( ); 00548 } 00549 if ( n==0 ) { 00550 return Tree( (NOT_null_pointer*) _root ); 00551 } 00552 if (_root->_father == 0) { 00553 return Tree( ); 00554 } 00555 00556 if ( n >= 0 ) { 00557 unsigned n_new = n + _root->_n_child; 00558 if (n_new < Tree::N) { 00559 return Tree( _root->_father->_Lchild[n_new] ); 00560 } else { 00561 return Tree( ); 00562 } 00563 } else { 00564 int n_abs = -n; 00565 if ( _root->_n_child >= n_abs ) { // se puede hacer la resta 00566 return Tree( _root->_father->_Lchild[ _root->_n_child - n_abs ] ); 00567 } else { 00568 return Tree( ); 00569 } 00570 } 00571 } 00572 00573 /** Obtiene el hijo más izquierdo del árbol 00574 00575 - Este método usualmente se usa junto con \c Right_Sibling() 00576 00577 \par Complejidad: 00578 O( <code> Count_Children() </code> ) 00579 00580 \remark Esta es una forma de procesar los hijos no vacíos de un sub-árbol de izquierda a derecha: 00581 00582 \code 00583 Tree Child = T.Leftmost(); 00584 while ( ! Child.Empty() ) { 00585 Process( Child ); 00586 Child = Child.Right_Sibling(); 00587 } 00588 \endcode 00589 */ 00590 Tree Tree::Leftmost() { 00591 if (_root == 0) { 00592 return Tree( ); 00593 } 00594 for (unsigned i=0; i<N; ++i) { 00595 if ( _root->_Lchild[i] != 0) { 00596 return Tree ( (NOT_null_pointer*) _root->_Lchild[i] ); 00597 } 00598 } 00599 return Tree( ); // ==> _root == 0 00600 } 00601 00602 /** Obtiene el hijo más derecho del árbol 00603 00604 - Este método usualmente se usa junto con \c Left_Sibling() 00605 - Requiere O(n) tiempo de ejecución, donde \c "n" es la cantidad de hijos de \c "*this" 00606 00607 \remark Esta es una forma de procesar los hijos no vacíos de un sub-árbol de derecha a izquierda: 00608 00609 \code 00610 Tree Child = T.Rightmost(); 00611 while ( ! Child.Empty() ) { 00612 Process( Child ); 00613 Child = Child.Left_Sibling(); 00614 } 00615 \endcode 00616 */ 00617 Tree Tree::Rightmost() { 00618 if (_root == 0) { 00619 return Tree( ); 00620 } 00621 00622 unsigned i = N; 00623 for (;;) { 00624 if (i == 0) { // tanto enredo ... para usar "unsigned" en lugar de "int" 00625 break; 00626 } 00627 --i; 00628 if (_root->_Lchild[i] != 0) { 00629 return Tree( (NOT_null_pointer*) _root->_Lchild[i] ); 00630 } 00631 } 00632 return Tree( ); // ==> _root == 0 00633 } 00634 00635 /** Implementación recursiva para \c Count() 00636 00637 - Incrementa \c "n" en el número de hijos que tiene el sub-árbol cuya raíz es \c "p" 00638 - Cambia el valor de \c "n" 00639 - No cuenta el nodo raíz \c "p" 00640 - Esta función complementa a \c Count() 00641 00642 \pre p != 0 00643 */ 00644 void Tree::Count0(const Node * p, unsigned & n) { 00645 for (unsigned i=0; i < N; ++i) { 00646 if (p->_Lchild[i] != 0) { 00647 ++n; // cuenta a este hijo 00648 Count0( p->_Lchild[i], n ); 00649 } 00650 } 00651 } 00652 00653 /** Retorna la cantidad de valores almacenados en el sub-árbol 00654 00655 - Calcula el número de sub-árboles no vacíos del árbol 00656 00657 \par Complejidad: 00658 O( \c Count() ) ==> tiempo <br> 00659 O( \c Height() ) ==> espacio 00660 00661 \see http://www.di-mare.com/adolfo/binder/c05.htm#sc03 00662 */ 00663 unsigned Tree::Count() const { 00664 if (_root == 0) { 00665 return 0; 00666 } else { 00667 unsigned n = 1; // comienza contando en uno... 00668 Count0(_root, n); // ... porque Count0() no cuenta la raíz 00669 return n; 00670 } 00671 } 00672 00673 /** Retorna la cantidad de hijos del árbol 00674 00675 \par Complejidad: 00676 O( \c Count_Children() ) 00677 */ 00678 unsigned Tree::Count_Children() const { 00679 unsigned tot = 0; 00680 for (unsigned i=0; i < N; ++i) { 00681 if (_root->_Lchild[i] != 0) { 00682 ++tot; // cuenta a este hijo porque no está vacío 00683 } 00684 } 00685 return tot; 00686 } 00687 00688 inline bool operator == (const Tree &p, const Tree &q) { return Tree::Comp0(p._root, q._root); } 00689 inline bool operator != (const Tree &p, const Tree &q) { return !(p == q); } 00690 00691 /** Compara recursivamente los árboles cuyos nodo raíz son \c "*p" y \c "*q" 00692 00693 - Implementación recursiva para <code> operator==(Tree, Tree) </code> 00694 */ 00695 bool Tree::Comp0(const Tree::Node *p, const Tree::Node *q) { 00696 if (p == q) { 00697 return true; 00698 } 00699 if ( (p==0) || (q == 0)) { // son diferentes... 00700 return false; // ...pues sólo 1 está vácio 00701 } 00702 if ( ! (p->_data == q->_data) ) { 00703 return false; // valor diferente en la raíz 00704 } 00705 00706 // A comparar a todos los hijos 00707 for (unsigned i=0; i < Tree::N; ++i) { 00708 if (! Comp0(p->_Lchild[i], q->_Lchild[i]) ) { 00709 return false; 00710 } 00711 } 00712 00713 return true; // pues nunca encontró nodos diferentes 00714 } 00715 00716 /** Verifica que se cumpla la invariante de la clase, o sea, que el objeto esté bien construido 00717 00718 - La razón por la que esta función no es un método es continuar la costumbre de muchos 00719 programadores quienes no definen la invariante para sus clases, pues en muchos 00720 casos sobra hacerlo. 00721 - No invoca \c Check_Ok( value_type& ) para cada valor almacenado, aunque si el árbol 00722 cumple con su invariante necesariamentes es porque también sus elementos almacenados 00723 están bien construidos. 00724 - Esta función en general es difícil de implementar, y en algunos casos es imposible 00725 pues, cuando el objeto no está bien construido, puede ocurrir que la función no 00726 retorne (como ocurriria si un nodo interno del árbol apunta de vuelta a la raíz, lo 00727 que se resulta en un círculo). 00728 - En general, la implementáción de esta función no es completa pues hay casos en que 00729 es imposible verificar la invariante de una clase. 00730 00731 \par Complejidad: 00732 O( \c Count() ) ==> tiempo <br> 00733 O( \c Height() ) ==> espacio 00734 00735 \post Retorna \c "true" si el árbol es un objeto bien construido 00736 \see \c Check_Ok(Tree&) 00737 00738 \see http://www.di-mare.com/adolfo/binder/c04.htm#sc11 00739 */ 00740 bool Check_Ok(Tree& T) { 00741 00742 if ( T.Empty() ) { 00743 return true; 00744 } 00745 00746 #ifdef NO_Implementado_para_evitar_forzar_que_el_valor_almacenado_tenga_su_metodo_OK 00747 if (! Check_Ok( T.Data() ) ) { // si el valor almacenado no esta bien... 00748 return false; //... tampoco lo está el árbol 00749 } 00750 /* Usar la función Check_Ok(Tree::value_type en lugar del método 00751 Tree::value_type::Ok() evitar forzar a que los programadores clientes 00752 que usen árboles estén obligados a implementar el método 00753 Tree::value_type::Ok(), que se encarga de verificar la invariante del valor 00754 almacenado en le árbol. 00755 - Lindo: if (! Check_Ok( T.Data() ) ) //.... la función Check_Ok() es opcional 00756 - ¡FEO!: if (! T.Data().Ok() ) //... pues obliga a que exista el método value_type::Ok() 00757 */ 00758 #endif 00759 00760 for (unsigned i = 0; i < Tree::N; ++i) { 00761 if ( T.Child(i).Empty() ) { // este hijo no existe 00762 // continue; // con el siguiente 00763 } 00764 else if ( T.Child(i).Father() != T.Root() ) { // ==> ! T.Father.Empty() 00765 return false; // parece que este hijo no es mi hijo... 00766 } 00767 else if ( i != T.Child(i).Child_Number() ) { 00768 return false; // no estoy registrado como el i-ésimo hijo de mi padre 00769 } 00770 else if ( T.Child(i).Father().Child( i ) != T.Child( i ) ) { 00771 return false; // no estoy registrado como el i-ésimo hijo de mi padre 00772 } 00773 else if ( ! Check_Ok( T.Child(i) ) ) { 00774 return false; // hijo roto... 00775 } 00776 } 00777 return true; 00778 00779 // Las siguientes relaciones lógicas se cumplen 00780 // [ ! T.Empty() ] ==> [ T.Root()!= Tree() ] 00781 // [ T.Child(i).Father() == T.Root()] ==> [ ! T.Father.Empty() ] 00782 00783 /* Si este método retorna es porque el árbol está bien construido. Sin embargo, 00784 una invocación a Check_Ok() con un árbol mal construido posiblemente nunca retorne. 00785 */ 00786 } 00787 00788 /** Sustituye por \c "d" el valor almacenado en la raíz del árbol 00789 00790 - Si el árbol está vacío, le agrega el nodo raíz. 00791 00792 \returns \c *this 00793 */ 00794 Tree Tree::Change_Root(const value_type & d) { 00795 if (_root == 0) { // como el árbol está vacío hay que agregarle la raíz 00796 _root = Node::Get_New(d); // crea el nodo raíz 00797 _root->No_Children(); // y le pone en blanco todos sus hijos 00798 } else { // como no hay más referencias.... 00799 _root->_data = d; // ... cambia el valor directamente 00800 } 00801 return *this; 00802 } 00803 00804 /** Sustituye por \c "d" el valor almacenado en el hijo número \c "n" del árbol 00805 00806 - Si no existe el hijo número \c "n", lo agrega como una hoja con valor \c "d" 00807 - Si ya existe el hijo número \c "n", le sustituye su valor por \c "d" 00808 00809 \pre <code> !Empty() && (0 <= n) && (n < Tree::N) </code> 00810 00811 \par Complejidad: 00812 O( \c Count_Children() ) 00813 00814 \returns <code> Child(n) </code> 00815 */ 00816 Tree Tree::Change_Child(unsigned n, const value_type &d) { 00817 if (_root == 0) { // ignora árboles vacíos 00818 return Tree( ); 00819 } 00820 if (n >= Tree::N) { // ignora índices fuera de rango 00821 return Tree( ); 00822 } 00823 if (_root->_Lchild[n] == 0) { // Hay que agregar un sub-árbol nuevo 00824 Node * p = Node::Get_New(d); 00825 p->No_Children(); 00826 p->_father = _root; 00827 p->_n_child = n; 00828 _root->_Lchild[n] = p; 00829 } else { 00830 _root->_Lchild[n]->_data = d; // cambia el valor directamente 00831 } 00832 return Tree( (NOT_null_pointer*) _root->_Lchild[n] ); 00833 } 00834 00835 /** Sustituye por \c "d" el valor almacenado en el hermano inmediatamente anterior del sub-árbol 00836 00837 - Si <code> n == Child_Number() </code> cambia el valor 00838 del hijo número \c "n-1" de \c Father() 00839 - Si no existe el hijo número \c "n-1" de \c Father() lo agrega como 00840 una hoja con valor \c "d" 00841 - Si ya existe ese hijo número \c "n-1", le sustituye su valor por \c "d" 00842 - Retorna un árbol vacío si no es posible que exista el hijo número \c "n-1" de \c Father() 00843 00844 \pre <code> !Empty() && (1 <= Child_Number()) </code> 00845 00846 \par Complejidad: 00847 O( \c 1 ) 00848 00849 \returns El hermano izquierdo, <code> Sibling(-1) </code> 00850 */ 00851 Tree Tree::Change_Left_Sibling_Inmediate( const value_type &d ) { 00852 if (_root == 0) { // ignora árboles vacíos 00853 return Tree( ); 00854 } 00855 unsigned n = _root->_n_child; 00856 if ( n == 0 ) { // no hay hijos hacia la izquierda 00857 return Tree( ); 00858 } 00859 // assert( (_root->_n_child > 0) && (n > 0) ); 00860 n--; 00861 if (_root->_father->_Lchild[ n ] == 0) { // Hay que agregar un sub-árbol nuevo 00862 Node * p = Node::Get_New(d); 00863 p->No_Children(); 00864 p->_father = _root->_father; 00865 p->_n_child = n; 00866 _root->_father->_Lchild[ n ]->_data = d; 00867 } else { 00868 _root->_father->_Lchild[ n ]->_data = d; // cambia el valor directamente 00869 } 00870 return Tree( (NOT_null_pointer*) _root->_Lchild[n] ); 00871 } 00872 00873 /** Sustituye por \c "d" el valor almacenado en el hermano inmediatamente posterior del sub-árbol 00874 00875 - Si <code> n == Child_Number() </code> cambia el valor 00876 del hijo número \c "n+1" de \c Father() 00877 - Si no existe el hijo número \c "n+1" de \c Father() lo agrega como 00878 una hoja con valor \c "d" 00879 - Si ya existe ese hijo número \c "n+1", le sustituye su valor por \c "d" 00880 - Retorna un árbol vacío si no es posible que exista el hijo número \c "n+1" de \c Father() 00881 00882 \pre <code> !Empty() && ( Child_Number() < Tree::N ) </code> 00883 00884 \par Complejidad: 00885 O( \c 1 ) 00886 00887 \returns El hermano derecho, <code> Sibling(+1) </code> 00888 */ 00889 Tree Tree::Change_Right_Sibling_Inmediate( const value_type &d ) { 00890 if (_root == 0) { // ignora árboles vacíos 00891 return Tree( ); 00892 } 00893 unsigned n = _root->_n_child + 1; 00894 if (n >= Tree::N) { // no hay hijos hacia la derecha 00895 return Tree( ); 00896 } 00897 // assert( n < Tree::N ); 00898 if (_root->_father->_Lchild[ n ] == 0) { // Hay que agregar un sub-árbol nuevo 00899 Node * p = Node::Get_New(d); 00900 p->No_Children(); 00901 p->_father = _root->_father; 00902 p->_n_child = n; 00903 _root->_father->_Lchild[ n ]->_data = d; 00904 } else { 00905 _root->_father->_Lchild[ n ]->_data = d; // cambia el valor directamente 00906 } 00907 return Tree ( _root->_Lchild[n] ); 00908 } 00909 00910 /** Elimina recursivamente a \c "*p" y a todos sus descendientes 00911 00912 - Implementación recursiva para \c Erase() 00913 - Borra el nodo sólo después de que constata que ya no hay punteros que le apunten 00914 - No actualiza los punteros en el padre ==> ese es el trabajo de \c Graft() o \c Erase() 00915 - Lo que sí hace es decrementar \c "p->_refCount" 00916 - Recursivamente, borra a los descendientes de \c "*p" 00917 00918 \pre <code> p != 0 </code> 00919 \post No cambia \c "p" porque trabaja con una copia de su valor 00920 */ 00921 void Tree::Erase0( Tree::Node * p ) { 00922 // assert( p != 0 ); 00923 p->_refCount--; // ya "p" no apunta al nodo 00924 if (p->_refCount == 0) { // elimina el nodo ==> esta es la última referencia 00925 // A matar hijos... 00926 for (unsigned i = 0; i < N; i++) { 00927 Tree::Node * q = p->_Lchild[i]; 00928 if (q != 0) { 00929 if (q->_father == p) { // lo des-padre-ja... 00930 q->_father = 0; // ... pues ya "p" no es su padre 00931 } 00932 Erase0(q); // elimina recursivamente a cada uno de sus hijos 00933 } 00934 // Esta sobra porque "*p" va a desaparecer 00935 // p->_Lchild[i] = 0; // ya ese nodo no es hijo de nadie 00936 } 00937 #ifdef USE_v_Alive 00938 // Elimina a "p" de _v_Alive[] 00939 for (unsigned j = 0; j < Node::N_Alive; ++j) { 00940 if (p == Node::_v_Alive[j]) { // busca hasta que encuentra al puntero 00941 break; 00942 } 00943 } 00944 if (j < Node::N_Alive) { // sí lo encontró 00945 for (unsigned k = j; k < Node::N_Alive; ++k) { // corre a los demás para atrás 00946 Node::_v_Alive[k] = Node::_v_Alive[k+1]; 00947 } 00948 Node::_n_Alive--; // ahora hay uno menos 00949 } else { 00950 for (unsigned k = 0; k<3; ++j) { // marca "feos" los del final 00951 Node::_v_Alive[Node::N_Alive-1-k] = (Tree::Node *)(-1); 00952 } 00953 } 00954 #endif 00955 delete p; // ... lo mata sólo si esta es la última referencia 00956 } 00957 } 00958 00959 /** Elimina el árbol y sus descendientes 00960 00961 \par Complejidad: 00962 O( \c Count() ) + O( <code> Father().Count() </code> ) ==> tiempo <br> 00963 O( \c Height() ) ==> espacio 00964 00965 \see http://www.di-mare.com/adolfo/binder/c04.htm#sc03 00966 */ 00967 void Tree::Erase() { 00968 if (_root == 0) { 00969 return; 00970 } else if (_root->_father != 0) { 00971 _root->_father->_Lchild[_root->_n_child] = 0; 00972 } 00973 Erase0(_root); 00974 _root = 0; 00975 } 00976 00977 // Esta documentación para Tree::Erase_Son() aparece acá porque Doxygen no permite 00978 // incluir un párrafo aparte "\par" en la documentación de 1 sólo renglón. 00979 00980 /** \fn void Tree::Erase_Son(unsigned n) 00981 00982 \brief Elimina el sub-árbol número \c "n" 00983 00984 \par Complejidad: 00985 O( <code> Child(n).Count() </code> ) ==> tiempo <br> 00986 O( <code> Height( Child(n) ) </code> ) ==> espacio 00987 */ 00988 00989 /** Verifica que se cumpla la invariante de la clase, o sea, que el objeto esté bien construido 00990 00991 - Además de todo el trabajo que hace \c Check_Ok(Tree& T), acá hay que constatar que 00992 el nodo raíz no tiene padre, que es la diferencia fundamental entre un árbol y un sub-árbol 00993 00994 \post Retorna \c "true" si el árbol es un objeto bien construido 00995 00996 \deprecated Los árboles y los sub-árboles son la misma cosa. 00997 00998 \see \c Check_Ok(Tree&) 00999 */ 01000 inline bool Check_Ok_Tree(Tree& T) { 01001 if ( T.Root().Empty() ) { 01002 return true; 01003 } else { 01004 return ( T.Root().Father().Empty() ) && Check_Ok( Tree (T) ); 01005 } 01006 } 01007 01008 /** Hace una copia profunda nodo por nodo del árbol cuyo nodo raíz es \c "*p" 01009 01010 - Implementación recursiva para \c Tree::Copy_Deep() 01011 - No altera \c p->_refCount porque copia los nodos. 01012 - \c "father" indica quién debe ser el padre del nuevo nodo 01013 - \c "father" no es el padre de \c "*p" 01014 01015 \pre <code> p != 0 </code> 01016 \post No cambia \c "p" porque trabaja con una copia de su valor 01017 01018 \returns Puntero al nodo raíz del árbol copiado 01019 */ 01020 Tree::Node * Tree::Copy_Deep0(Node * father, const Node * p) { 01021 Node * q; // resultado 01022 q = Node::Get_New(p->_data); // _refCount = 1; _n_child = 0; _father = 0; 01023 q->_n_child = p->_n_child; 01024 q->_father = father; 01025 01026 // inicializa los punteros a los hijos que estarán en _Lchild[] 01027 for (unsigned i=0; i < N; ++i) { 01028 if (p->_Lchild[i] == 0) { // si en el árbol fuente este hijo no existe... 01029 q->_Lchild[i] = 0; // ...tampoco existirá en la copia 01030 } else { // copie todo el sub-árbol 01031 q->_Lchild[i] = Copy_Deep0(q, p->_Lchild[i]); 01032 } 01033 } 01034 return q; 01035 } 01036 01037 /** Copia profunda de \c "o" 01038 01039 - Copia todo el valor de \c "o" sobre \c "*this", de forma que el nuevo valor de 01040 \c "*this" sea un duplicado exacto del valor de \c "o" 01041 - El valor anterior de \c "*this" se pierde 01042 - El objeto \c "o" mantiene su valor anterior 01043 - Luego de la copia, cuando el valor de \c "o" cambia, el de \c "*this" no cambiará, 01044 y viceversa, pues la copia es una copia profunda; no es superficial 01045 - Si \c "*this" es \c "o" entonces su valor no cambia 01046 - Después de esta operación siempre ocurre que <code> *this == o </code> 01047 01048 \par Complejidad: 01049 O( \c Count() ) + O( \c o.Count() ) 01050 01051 \returns \c *this 01052 01053 \see http://www.di-mare.com/adolfo/binder/c04.htm#sc05 01054 */ 01055 Tree& Tree::Copy_Deep(const Tree &o) { 01056 if (_root != 0) { 01057 Erase0(_root); // Borra el contenido actual del árbol 01058 } 01059 if (o._root != 0 ) { 01060 _root = Copy_Deep0(0, o._root); // 0 == cero == this->Father() 01061 } else { 01062 _root = 0; 01063 } 01064 return *this; 01065 } 01066 01067 /** Injerta \c "o" para que sea el \c "n"-ésimo hijo de \c "*this" 01068 01069 - Si \c "o" es sub-árbol de otro árbol, dejara de serlo para pasar ser hijo de \c "*this" 01070 - Si \c "*this" tiene un \c "n"-ésimo hijo, ese hijo desaparece 01071 - Si \c "o" está vacío, elimina el \c "n"-ésimo hijo del árbol [<code> Erase_Son(n) </code>] 01072 01073 \pre 01074 - <code> ! Root().Empty() </code> 01075 - Si el árbol está vacío no tiene raíz, y por lo tanto tampoco puede tener hijos 01076 - <code> ! Ancestor(o, *this) </code> 01077 - "o" no puede ser ancestro de *this" 01078 - <code> (0 <= n) && (n < Tree::N) </code> 01079 - <code> ! Root(). Same( o.Root() ) </code> 01080 01081 \post 01082 - \c "o" deja de ser sub-árbol del árbol en que estaba 01083 - <code> o.Father() .Same( Root() ) </code> 01084 01085 \remarks 01086 - Un sub-árbol puede ser hijo (o sub-árbol) de otro árbol 01087 - Un sub-árbol puede ser hijo únicamente de un árbol 01088 - Este método no hace nada cuando [ <code> ! Root() .Same( o.Root() ) </code> ] 01089 - Injertar un sub-árbol vacío es una forma de eliminar a un hijo junto con 01090 toda su descendencia 01091 01092 \returns "o" ==> El árbol recién injertado 01093 01094 \par Complejidad:: 01095 O( \c Count_Children() ) + O( <code> o.Father().Count_Children() </code> ) 01096 01097 */ 01098 Tree Tree::Graft(unsigned n, Tree &o) { 01099 if (_root == 0) { // ignora árboles vacíos 01100 return Tree( ); 01101 } 01102 if (_root == o._root) { // evita auto-borrado 01103 return Tree( (NOT_null_pointer*) _root ); 01104 } 01105 #ifdef FALTA_verificar_en_Graft 01106 bool Ancestor( Tree & Child, Tree & Father ); 01107 assert( ! Ancestor( o, *this ) ); // "o" no puede ser ancestro de *this" 01108 #endif 01109 if (n >= Tree::N) { // ignora punteros nulos 01110 return Tree( (NOT_null_pointer*) _root ); 01111 } 01112 if (_root->_Lchild[n] == o._root) { // ya el hijo está ahí 01113 return Tree( (NOT_null_pointer*) _root ); 01114 } 01115 if (_root->_Lchild[n] != 0) { 01116 _root->_Lchild[n]->_father = 0; // deja a este hijo [n] sin padre aunque... 01117 _root->_Lchild[n]->_n_child = 0; // ...puede que haya otras referencias a este mismo nodo 01118 Erase0( _root->_Lchild[n] ); // elimna el n-ésimo hijo de "*this" 01119 } 01120 if (o._root == 0) { 01121 _root->_Lchild[n] = 0; // Caso trival si el árbol "o" a injertar está vacío 01122 } else { 01123 if (o._root->_father != 0) { // desliga al hijo "o" de su padre actual 01124 o._root->_father->_Lchild[o._root->_n_child] = 0; // ya no es hijo del padre anterior 01125 o._root->_refCount--; // pues dejó de ser hijo del padre anterior 01126 } 01127 o._root->_father = _root; // nuevo padre 01128 o._root->_n_child = n; // coloca a "o" como el "n-ésimo" hijo 01129 o._root->_refCount++; // su nuevo padre ahora ya le apunta 01130 _root->_Lchild[n] = o._root; 01131 } 01132 01133 return Tree( _root->_Lchild[n] ); 01134 } // Tree::Graft() 01135 01136 } // namespace TV 01137 01138 using namespace TV; 01139 01140 #endif // Tree_V_h 01141 01142 // EOF: Tree_V.h