00001 // Tree_L.h (c) 2004 adolfo@di-mare.com 00002 00003 /** \file Tree_L.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_L_h 00013 #define Tree_L_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 puntero izquierdo al hijo y uno derecho al hermano o padre 00027 namespace TL { 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 /// Nodos almacenados en el árbol 00049 class Node { 00050 friend class Tree; friend class Tree; 00051 private: 00052 Node( const value_type& d ) : _data( d ), _refCount(1) {} ///< Constructor de vector 00053 static Node* Get_New(const value_type& d); 00054 unsigned Abs_n_child(); 00055 private: 00056 value_type _data; ///< Valor almacenado en el nodo 00057 unsigned _refCount; ///< Cantidad de punteros hacia mi 00058 int _n_child; ///< Soy el el hijo número <code> "(_n_child - 1)" </code> de mi padre 00059 Node * _left_child; ///< Puntero al nodo hijo más izquierdo 00060 Node * _right_brother; ///< Puntero al nodo hermano o al padre 00061 private: 00062 #ifdef USE_v_Alive // ==> NDEBUG ==> Overview of File Translation ==> C++ 00063 static const unsigned N_Alive = 333; ///< Cantidad máxima posible de punteros en uso 00064 static Node * _v_Alive[N_Alive]; ///< Punteros en uso 00065 static unsigned _n_Alive; ///< Cantidad de punteros en uso 00066 #endif 00067 }; // Node 00068 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) { Node*p; Erase_Son_Prev(n+1,p /*,p*/); } 00103 private: 00104 void Erase_Son_Prev(unsigned n, Node*& /*, Node*& */); 00105 //@} 00106 00107 /// \name Operaciones de copiado 00108 //@{ 00109 public: 00110 Tree& operator= (Tree &o) { return Copy(o); } ///< Sinónimo de \c this->Copy(o) 00111 Tree& Copy (Tree &o); 00112 Tree& Move (Tree &o); 00113 Tree& Swap (Tree &o); 00114 Tree& Copy_Deep( const Tree &o ); 00115 /// Usa \c Change_Root() para sustituir por "d" el valor almacenado en la raíz del árbol 00116 Tree& operator=( const value_type & d) { Change_Root(d); return *this; } 00117 //@} 00118 00119 /// \name Métodos para cambiar los valores almacenados en el árbol 00120 //@{ 00121 public: 00122 Tree Change_Root(const value_type &d); 00123 Tree Change_Child( unsigned n, const value_type &d ); 00124 Tree Change_Left_Sibling_Inmediate( const value_type &d ); 00125 Tree Change_Right_Sibling_Inmediate( const value_type &d ); 00126 Tree Graft( unsigned n, Tree &o ); 00127 //@} 00128 00129 /// \name Operaciones para usar los valores almacenados 00130 //@{ 00131 public: 00132 value_type& Data () { return _root->_data; } ///< Valor almacenado en la raíz del sub-árbol 00133 value_type& operator * () { return Data(); } ///< Valor almacenado en la raíz del sub-árbol 00134 value_type* operator -> () { return &(_root->_data); } ///< Puntero al valor almacenado en la raíz del sub-árbol 00135 //@} 00136 00137 /// \name Operaciones de comparación 00138 //@{ 00139 public: 00140 friend bool operator == (const Tree &p, const Tree &q); ///< ¿¿¿ (p == q) ??? 00141 friend bool operator != (const Tree &p, const Tree &q); ///< ¿¿¿ (p != q) ??? 00142 bool Equals( const Tree & o ) const { return (*this)==o; } ///< ¿¿¿ (*this==o) ??? 00143 /// Retorna \c true si \c "o" comparte la raíz con \c "*this" 00144 bool Same( const Tree & o ) const { return _root == o._root; } 00145 //@} 00146 00147 /// \name Métodos para recorrer el árbol 00148 //@{ 00149 public: 00150 Tree Root() { return Tree( _root ); } ///< Raíz del sub-árbol 00151 Tree Father(); 00152 Tree Child(unsigned n); 00153 Tree Left(); 00154 Tree Right(); 00155 Tree Leftmost(); 00156 Tree Rightmost(); 00157 Tree Sibling(int n); 00158 Tree Left_Sibling(); 00159 Tree Right_Sibling(); 00160 Tree Previous_Sibling() { return Left_Sibling(); } ///< Sinónimo de \c Left_Sibling() 00161 Tree Prev_Sibling() { return Left_Sibling(); } ///< Sinónimo de \c Left_Sibling() 00162 Tree Next_Sibling() { return Right_Sibling(); } ///< Sinónimo de \c Right_Sibling() 00163 Tree Right_Sibling_Inmediate(); 00164 Tree Left_Sibling_Inmediate(); 00165 //@} 00166 00167 /// \name Propiedades del árbol 00168 //@{ 00169 public: 00170 /// Retorna \c "n" si \c "*this" es el n-ésimo hijo de su padre, si no retorna \c 0 (cero) 00171 unsigned Child_Number() { return ( _root==0 ? 0 : _root->Abs_n_child() - 1); } 00172 /// Retorna \c "n" si el hijo más izquierdo de \c "*this" es el n-ésimo hijo, si no retorna \c 0 (cero) 00173 unsigned Leftmost_N() { return Leftmost().Child_Number(); } 00174 /// Retorna \c "n" si el hijo más derecho de \c "*this" es el n-ésimo hijo, si no retorna \c 0 (cero) 00175 unsigned Rightmost_N() { return Rightmost().Child_Number(); } 00176 /// Retorna \c "true" si el árbol es una hoja 00177 bool Is_Leaf() { return (_root != 0) && (_root->_left_child != 0); } 00178 /// Retorna \c "true" si el árbol no tiene padre 00179 bool Is_Root() { return (_root != 0) && (_root->_right_brother == 0); } 00180 /// Cantidad de referencias de la raíz del árbol 00181 unsigned Nref() { return (_root==0 ? 0 : _root->_refCount); } 00182 //@} 00183 00184 /// \name Funciones para manipular valores a bajo nivel 00185 //@{ 00186 private: 00187 static Tree& CastTo_Sub_Tree_Ref ( Node * &p ) 00188 { return (Tree&) *( reinterpret_cast<Tree*> (&p)); } ///< Convierte el puntero al nodo en un referencia a \c Tree 00189 //@} 00190 00191 /// \name Funciones recursivas que realizan el trabajo sobre nodos 00192 //@{ 00193 private: 00194 static void Erase0(Node * p); 00195 static bool Comp0(const Node *p, const Node *q); 00196 static void Count0(const Node * p, unsigned & n); 00197 static Node* Copy_Deep0(const Node * p); 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 del nodo. 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 Tree::~Tree() { 00247 if (_root != 0) { 00248 if (_root->_refCount == 1) { 00249 Erase0(_root); 00250 } else { 00251 _root->_refCount--; 00252 } 00253 } 00254 } 00255 00256 /// Constructor a partir de un valor 00257 inline Tree::Tree(const Tree::value_type & d) { 00258 _root = Node::Get_New(d); 00259 _root->_n_child = -1; 00260 _root->_left_child = 0; 00261 _root->_right_brother = 0; 00262 } 00263 00264 /** Copia superficial desde \c "o" 00265 00266 - El valor anterior de \c "*this" se pierde 00267 00268 \par Complejidad: 00269 O( \c Count() ) 00270 00271 \returns *this 00272 00273 \see http://www.di-mare.com/adolfo/binder/c04.htm#sc05 00274 */ 00275 Tree& Tree::Copy (Tree &o) { 00276 if (_root != o._root) { // evita auto-borrado 00277 if (_root != 0) { 00278 if ( _root->_refCount == 1 ) { // como es el último... 00279 Erase0(_root); // ...lo mata 00280 } else { 00281 _root->_refCount--; 00282 } 00283 } 00284 _root = o._root; // comparte la raíz 00285 if (o._root != 0) { 00286 o._root->_refCount++; // una referencia más 00287 } 00288 } 00289 return *this; 00290 } 00291 00292 /** Traslada el valor de \c "o" a \c "*this" 00293 00294 - El valor anterior de \c "*this" se pierde 00295 - El nuevo valor de \c "*this" es el que \c "o" tuvo 00296 - \c "o" queda en el estado en que lo dejaría \c Erase() 00297 - Si \c "*this" es \c "o" entonces su valor no cambia 00298 - En general, después de esta operación casi 00299 nunca ocurre que <code> (*this == o) </code> 00300 00301 \par Complejidad: 00302 O( \c Count() ) 00303 00304 \returns \c *this 00305 00306 \see http://www.di-mare.com/adolfo/binder/c04.htm#sc07 00307 */ 00308 Tree& Tree::Move (Tree &o) { 00309 if (_root == o._root) { // evita auto-borrado 00310 if (_root != 0) { 00311 if ( _root->_refCount == 1 ) { // como es el último... 00312 Erase0(_root); // ...lo mata 00313 } else { 00314 _root->_refCount--; 00315 } 00316 } 00317 _root = o._root; // se roba los hijos 00318 o._root = 0; // anula al dador 00319 } 00320 return *this; 00321 } 00322 00323 /** Intercambia los valores de \c "*this" y \c "o" 00324 00325 - Debido a que algunos métodos retornan copias del valor de \c "*this" en 00326 lugar de una referencia, como ocurre con \c Tree::Child(), a veces 00327 \c Swap() no tiene el resultado esperado por el programador. 00328 - Por ejemplo, si se invoca <code> T.Child(i). Swap( T.Child(j) ) </code> 00329 el resultado no es intercambiar los hijos, sino más bien intercambiar 00330 los valores de los sub-árboles temporales \c T.Child(i) y \c T.Child(j). 00331 La forma correcta de intercambiar hijos es usar \c Graft(). 00332 00333 \par Complejidad: 00334 O( \c 1 ) 00335 00336 \returns *this 00337 00338 \see http://www.di-mare.com/adolfo/binder/c04.htm#sc08 00339 */ 00340 inline Tree& Tree::Swap (Tree &o) { 00341 Node * tmp = _root; 00342 _root = o._root; 00343 o._root = tmp; 00344 return *this; 00345 } 00346 00347 /** Acceso al padre 00348 00349 - Si el sub-árbol no tiene padre retorna el árbol vacío. 00350 00351 \par Complejidad: 00352 O( <code> Father().Count_Children() </code> ) 00353 00354 */ 00355 Tree Tree::Father() { 00356 if (_root == 0) { 00357 return Tree( ); 00358 } 00359 00360 Node* p = _root; // soy el primer hijo de mi padre 00361 while (p->_n_child > 0) { 00362 p = p->_right_brother; // se brinca los que no tienen el puntero al padre 00363 } 00364 return Tree( p->_right_brother ); 00365 // para la raíz siempre ocurre que [_root->_right_brother == 0] por lo que 00366 // Tree( p->_right_brother ) produce un árbol vacío 00367 } 00368 00369 /** Acceso al \c "n"-ésimo hijo 00370 00371 - Si el sub-árbol no tiene un hijo número \c "n" retorna el sub-árbol vacío. 00372 00373 \par Complejidad: 00374 O( <code> Father().Count_Children() </code> ) 00375 */ 00376 Tree Tree::Child( unsigned n ) { 00377 if (_root == 0) { 00378 return Tree( ); 00379 } 00380 00381 Node* child = _root->_left_child; // soy el primer hijo de mi padre 00382 if (child == 0) { 00383 return Tree( ); 00384 } 00385 00386 n++; // lo incrementa para evitar incrementar "_n_child" para cada hijo de "_root" 00387 00388 for (;;) { 00389 if (child->_n_child <= 0) { // es el último hijo 00390 if ( unsigned(- child->_n_child) == n ) { 00391 return Tree( (NOT_null_pointer*) child ); 00392 } else { 00393 return Tree( ); 00394 } 00395 } else { 00396 if ( child->_n_child == n ) { 00397 return Tree( (NOT_null_pointer*) child ); 00398 } else if ( unsigned(child->_n_child) < n) { 00399 child = child->_right_brother; 00400 } else { // assert( unsigned(child->_n_child) > n ); 00401 return Tree( ); 00402 } 00403 } 00404 } 00405 } 00406 00407 /** \typedef Tree::NOT_null_pointer 00408 \brief Truco para evitar comparar con \c 0 ( \c nil ) 00409 al usar \c Tree::Node* para construir \c Tree(). 00410 00411 Al implementar cada uno de los métodos de \c Tree con frecuencia ocurre 00412 que es posible saber que el sub-árbol retornado no está vacío. En estos casos, conviene 00413 usar un contructor que no verifique si la raíz del árbol es nula. 00414 00415 Esta clase se usa como una marca para que se ejecute el contructor 00416 <code> Tree::Tree(NOT_null_pointer* p) </code> 00417 que no verifica la nulidad de \c "_root"; esta es una micro-eficiencia, pero aquí sirve 00418 para mostrar un truco que es muy usado en C++ para aumentar la eficiencia de los 00419 programas, pues le permite al programado usar la sobrecarga de operadores para evitar 00420 repetir verificaciones innecesarias. 00421 00422 \see http://www.di-mare.com/adolfo/binder/c01.htm#k1-micro-eficiencia 00423 */ 00424 00425 /** Sub-árbol izquierdo [en un árbol binario] 00426 00427 - Sinónimo de \c Child(0). 00428 \par Complejidad: 00429 O( \c 1 ) 00430 */ 00431 inline Tree Tree::Left() { 00432 if (_root == 0) { 00433 return Tree( ); 00434 } else if ( -1 ==_root->_left_child->_n_child || 00435 1 ==_root->_left_child->_n_child ) { 00436 return Tree( (NOT_null_pointer*) _root->_left_child ); 00437 } 00438 return Tree( ); 00439 } 00440 00441 /** Sub-árbol derecho [en un árbol binario] 00442 00443 - Sinónimo de \c Child(1). 00444 00445 \par Complejidad: 00446 O( \c 1 ) 00447 */ 00448 Tree Tree::Right() { 00449 if (_root == 0) { 00450 return Tree( ); 00451 } else if ( 0 == _root->_left_child ) { // no hay hijos 00452 return Tree( ); 00453 } else if ( -1 ==_root->_left_child->_n_child ) { 00454 return Tree( ); // sólo está el hijo izquierdo 00455 } else if ( 1 ==_root->_left_child->_n_child ) { 00456 if ( -2 == _root->_left_child->_right_brother->_n_child || 00457 2 == _root->_left_child->_right_brother->_n_child ) { 00458 return Tree( (NOT_null_pointer*) _root->_left_child->_right_brother ); 00459 } 00460 } else if ( 2 == _root->_left_child->_n_child || -2 == _root->_left_child->_n_child ) { 00461 return Tree( (NOT_null_pointer*) _root->_left_child ); 00462 } 00463 return Tree( ); // uso 1-2 en lugar de 0-1 porque "_n_child" contiene "uno más" 00464 } 00465 00466 /** Obtiene el hermano no vacío anterior, que está hacia la izquierda 00467 00468 - Si no existe un hermano no vacío hacia la izquierda, retorna un sub-árbol vacío. 00469 - Si <code>n == Child_Number()</code> no necesariamente ocurrirá que 00470 <code> (n-1)== Left_Sibling().Child_Number()</code> 00471 pues los anteriores hijos de \c Father() pueden ser sub-árboles vacíos, como ocurre si 00472 un árbol binario tiene hijo derecho pero no tiene hijo izquierdo. 00473 - Este método usualmente se usa junto con \c Rightmost() 00474 00475 \par Complejidad: 00476 O( <code> Father().Count_Children() </code> ) 00477 */ 00478 Tree Tree::Left_Sibling() { 00479 if (_root == 0) { 00480 return Tree( ); 00481 } 00482 00483 unsigned n_child = _root->Abs_n_child()-1; // assert( n_child >= 0 ); 00484 if ( n_child <= 0 ) { // no puede haber un hijo anterior... 00485 return Tree( ); // huye porque no existen hijos antes del primero 00486 } 00487 #ifdef ESTO_SOBRA_en_Left_Sibling 00488 if (_root->_right_brother == 0) { // sólo la raíz tiene en blanco "_right_brother" 00489 return Tree( ); // la raíz no tiene hermanos 00490 } 00491 // Para el nodo raíz de un árbol [T] el campo [T._root->_right_brother == 0] es nulo 00492 // - Afortunadamente, como [T._root->_n_child == -1], el if(){} anterior retorna 00493 // el sub-árbol vacío para el nodo raíz del árbol [T]. 00494 #endif 00495 00496 Node* brother = _root; // camina sobre los hermanos hasta llegar al padre 00497 while (brother->_n_child > 0) { 00498 brother = brother->_right_brother; // se brinca los que no tienen el puntero al padre 00499 } 00500 Node* father = brother->_right_brother; 00501 // assert( ! Father().Empty() && Father().Same( Tree( brother ) ) ); 00502 00503 brother = father->_left_child; // hijo más izquierdo de Father() 00504 if ( _root == brother ) { 00505 return Tree( ); // ya "_root" era el hijo más izquierdo 00506 } 00507 while ( _root != brother->_right_brother ) { 00508 brother = brother->_right_brother; 00509 } 00510 // assert( _root == brother->_right_brother ); 00511 return Tree( brother ); 00512 } 00513 00514 /** Obtiene el hermano no vacío siguiente, que está hacia la derecha 00515 00516 - Si no existe un hermano hacia la derecha, retorna un sub-árbol vacío. 00517 - Si <code>n == Child_Number()</code> no necesariamente ocurrirá que 00518 <code>(n+1) == Right_Sibling().Child_Number()</code> 00519 pues los siguientes hijos de \c Father() pueden ser sub-árboles vacíos, como ocurre si 00520 un árbol binario tiene hijo izquierdo pero no tiene hijo derecho. 00521 - Este método usualmente se usa junto con \c Leftmost() 00522 00523 \par Complejidad: 00524 O( \c 1 ) 00525 */ 00526 Tree Tree::Right_Sibling() { 00527 if (_root == 0) { 00528 return Tree( ); 00529 } if (_root->_n_child < 0) { // es el último hijo 00530 return Tree( ); // ==> ya no hay dónde más buscar 00531 } else { 00532 return Tree( _root->_right_brother ); 00533 // sólo la raíz tiene "_right_brother" en blanco (puntero nulo); 00534 // en ese caso se retorna el árbol vacío. 00535 } 00536 } 00537 00538 /** Obtiene el hermano que está inmediatamente hacia la izquierda 00539 00540 - Este método es equivalente a invocar \c Sibling( -1 ) 00541 - Si no existe un hermano hacia la derecha, retorna un sub-árbol vacío. 00542 00543 \par Complejidad: 00544 O( <code> Father().Count_Children() </code> ) 00545 */ 00546 inline Tree Tree::Left_Sibling_Inmediate() { 00547 return Sibling( -1 ); 00548 } 00549 00550 /** Obtiene el hermano que está inmediatamente hacia la derecha 00551 00552 - Este método es equivalente a invocar \c Sibling( +1 ) 00553 - Si no existe ese hermano hacia la derecha, retorna un sub-árbol vacío. 00554 00555 \par Complejidad: 00556 O( \c 1 ) 00557 */ 00558 Tree Tree::Right_Sibling_Inmediate() { 00559 // return Sibling( +1 ); 00560 if (_root == 0) { 00561 return Tree( ); 00562 } 00563 if (_root->_n_child <= 0) { // es el último hijo 00564 return Tree( ); // ya no hay hermanos a la derecha 00565 } 00566 // assert( _root->_right_brother != 0 ); // pues "(_root->_n_child > 0)" 00567 Node* brother = _root->_right_brother; 00568 // assert( brother->Abs_n_child() > 0 ); // pues "brother" está "a la derecha" de "_root" 00569 int n_brother = brother->Abs_n_child() - 1; 00570 if ( _root->_n_child == n_brother ) { 00571 return Tree( (NOT_null_pointer*) brother ); 00572 } else { 00573 return Tree( ); 00574 } 00575 #if 0 00576 if (brother->_n_child > 0) { 00577 if ( _root->_n_child + 1 == brother->_n_child ) { 00578 return Tree( (NOT_null_pointer*) brother ); 00579 } else { 00580 return Tree( ); 00581 } 00582 } else { 00583 if ( _root->_n_child + 1 == - brother->_n_child ) { 00584 return Tree( (NOT_null_pointer*) brother ); 00585 } else { 00586 return Tree( ); 00587 } 00588 } 00589 #endif 00590 } 00591 00592 /** Retorna el valor absoluto del campo \c "_n_child" 00593 00594 - Hay que tomar en cuenta que que \c _n_child está incrementado en \c +int(1) 00595 porque la marca de "puntero al padre" es un valor negativo, y como hay un hijo número cero 00596 \c int(0), no sería posible marcar como "puntero al padre" a ese nodo 00597 - Esta rutina también existe para documentar el truco del "puntero al padre", pues más directo 00598 habría sido usar la función \c abs() definida en <code> \#include <cstdlib> </code> 00599 - En otras palabras, parte de la invariante de un nodo siempre será que 00600 <code> (_n_child != 0) </code> porque siempre <code> int(0) == int(-0) </code> 00601 */ 00602 inline unsigned Tree::Node::Abs_n_child() { 00603 return ( _n_child >= 0 ? unsigned(_n_child) : unsigned( - _n_child ) ); 00604 } 00605 00606 /** \c "n"-ésimo hermano a partir de \c "*this". 00607 00608 - El hermano puede ser vacío aunque haya otros hermanos que no son vacíos. 00609 - Se "corre" hacia el n-ésimo hermano \c "n" "posiciones". 00610 - El hermano se determina contando sub-árboles hacia la derecha o izquierda de acuerdo 00611 al signo de \c "n": 00612 - Si \c n=0, regresa \c "*this". 00613 - Si \c n>0, regresa el hermano número \c "+n" contando hacia la derecha de \c "*this". 00614 - Si \c n<0, regresa el hermano número \c "-n" contando hacia la izquierda de \c "*this". 00615 - Si no existe un hermano número \c "n" retorna un sub-árbol vacío. 00616 - El árbol \c "T" tiene 3 hijos no vacíos \c "B", \c "C" y \c "E" y tiene 4 sub-árboles: 00617 - <code> C.Sibling( +0 ) == C</code> 00618 - <code> B.Sibling( +1 ) == C</code> 00619 - <code> E.Sibling( -2 ) == C</code> 00620 - <code> E.Sibling( -1 ) --> Vacío</code> 00621 - <code> A.Sibling( +1 ) --> Vacío </code> 00622 - <code> B.Sibling( -1 ) --> Vacío </code> 00623 - <code> E.Sibling( +1 ) --> Vacío </code> 00624 \code 00625 A <-- T 00626 /|\ 00627 / / \ \ [] --> es representa un sub-árbol vacío 00628 B C [] E 00629 \endcode 00630 00631 \par Complejidad: 00632 O( <code> Father().Count_Children() </code> ) 00633 */ 00634 Tree Tree::Sibling( int n ) { 00635 if (_root == 0) { 00636 return Tree( ); 00637 } else if ( _root->_right_brother == 0 ) { 00638 return Tree( ); 00639 } else if ( n==0 ) { 00640 return Tree( (NOT_null_pointer*) _root ); 00641 } 00642 00643 Node* brother; // desde dónde comenzar a buscar en la lista de hermanos 00644 unsigned n_target; // número de hijo que hay que encontrar: "(_n_child + n)" 00645 00646 // averigua "n_target" (hay que manejar el "+1" del "puntero al padre") 00647 if ( n < 0 ) { // a la izquierda ==> busque al padre para comenzar en _left_child 00648 unsigned n_child = _root->Abs_n_child()-1; // assert( n_child >= 0 ); 00649 unsigned abs_n = unsigned(-n); // assert( abs_n > 0 ); 00650 if ( n_child < abs_n ) { // no se puede hacer la resta porque da un número de hijo negativo 00651 return Tree( ); // se sale pues no existen hijos antes del hijo más izquierdo 00652 } else { 00653 n_target = n_child - abs_n; // como el hermano está hacia la izquierda... 00654 // return Father().Child( n_target ); // ...hay que buscarlo desde el padre 00655 brother = _root; 00656 while (brother->_n_child > 0) { // se brinca los que no tienen el puntero al padre 00657 brother = brother->_right_brother; 00658 } 00659 brother = brother->_right_brother->_left_child; // buscará desde el primer nodo 00660 } 00661 } else { // assert( n > 0 ); // a la derecha ==> busque desde aquí en adelante 00662 brother = _root; 00663 n_target = unsigned(n) + _root->Abs_n_child()-1; // assert( (n > 0) && (n_target > _n_child) ); 00664 } 00665 00666 // hay que manejar el "+1" del "puntero al padre" en "n_target" 00667 ++n_target; // para no tener que restarle int(1) a "child->_n_child" 00668 00669 // avance hacia la derecha en busca del hermano "n_target" 00670 // assert( brother != 0 ); 00671 for (;;) { 00672 if (brother->_n_child < 0) { // es el último hijo 00673 if ( unsigned(- brother->_n_child) == n_target ) { 00674 return Tree( (NOT_null_pointer*) brother ); 00675 } else { 00676 return Tree( ); // esa era el último ==> ya no hay dónde más buscar 00677 } 00678 } else { 00679 unsigned n_child = brother->_n_child; 00680 if (n_child == n_target) { // lo encontró 00681 return Tree( (NOT_null_pointer*) brother ); 00682 } else if (n_child < n_target) { // siga buscando... 00683 brother = brother->_right_brother; 00684 } else { // if (n_child > n_target) // ya se lo brincó; no está 00685 return Tree( ); 00686 } 00687 } 00688 } 00689 } 00690 00691 /** Obtiene el hijo más izquierdo del árbol 00692 00693 - Este método usualmente se usa junto con \c Right_Sibling() 00694 00695 \par Complejidad: 00696 O( \c 1 ) 00697 00698 \remark Esta es una forma de procesar los hijos no vacíos de un sub-árbol de izquierda a derecha: 00699 00700 \code 00701 Tree Child = T.Leftmost(); 00702 while ( ! Child.Empty() ) { 00703 Process( Child ); 00704 Child = Child.Right_Sibling(); 00705 } 00706 \endcode 00707 */ 00708 inline Tree Tree::Leftmost() { 00709 if (_root == 0) { 00710 return Tree( ); 00711 } 00712 return Tree( _root->_left_child ); // puede ser el puntero nulo 00713 } 00714 00715 /** Obtiene el hijo más derecho del árbol 00716 00717 - Este método usualmente se usa junto con \c Left_Sibling() 00718 00719 \par Complejidad: 00720 O( <code> Count_Children() </code> ) 00721 00722 \remark Esta es una forma de procesar los hijos no vacíos de un sub-árbol de derecha a izquierda: 00723 00724 \code 00725 Tree Child = T.Rightmost(); 00726 while ( ! Child.Empty() ) { 00727 Process( Child ); 00728 Child = Child.Left_Sibling(); 00729 } 00730 \endcode 00731 */ 00732 Tree Tree::Rightmost() { 00733 if (_root == 0) { 00734 return Tree( ); 00735 } 00736 Node* child = _root->_left_child; // soy el primer hijo de mi padre 00737 if (child == 0) { 00738 return Tree( ); 00739 } 00740 00741 while (child->_n_child > 0) { // todavía no se ha llegado al último hijo 00742 child = child->_right_brother; 00743 } 00744 return Tree( (NOT_null_pointer*) child ); 00745 } 00746 00747 /** Implementación recursiva para \c Count() 00748 00749 - Incrementa \c "n" en el número de hijos que tiene el sub-árbol cuya raíz es \c "p" 00750 - Cambia el valor de \c "n" 00751 - No cuenta el nodo raíz \c "p" 00752 - Esta función complementa a \c Count() 00753 00754 \pre p != 0 00755 */ 00756 void Tree::Count0(const Node * p, unsigned & n) { 00757 Node* child = p->_left_child; // soy el primer hijo de mi padre 00758 if (child == 0) { 00759 return; 00760 } 00761 00762 for (;;) { 00763 ++n; // cuenta a este hijo 00764 Count0( child, n ); 00765 if (child->_n_child > 0) { // todavía no se ha llegado al último hijo 00766 child = child->_right_brother; 00767 } else { 00768 break; 00769 } 00770 } 00771 } 00772 00773 /** Retorna la cantidad de valores almacenados en el sub-árbol 00774 00775 - Calcula el número de sub-árboles no vacíos del árbol 00776 00777 \par Complejidad: 00778 O( \c Count() ) ==> tiempo <br> 00779 O( \c Height() ) ==> espacio 00780 00781 \see http://www.di-mare.com/adolfo/binder/c05.htm#sc03 00782 */ 00783 unsigned Tree::Count() const { 00784 if (_root == 0) { 00785 return 0; 00786 } else { 00787 unsigned n = 1; // comienza contando en uno... 00788 Count0(_root, n); // ... porque Count0() no cuenta la raíz 00789 return n; 00790 } 00791 } 00792 00793 /** Retorna la cantidad de hijos del árbol 00794 00795 \par Complejidad: 00796 O( \c Count_Children() ) 00797 */ 00798 unsigned Tree::Count_Children() const { 00799 if (_root == 0) { 00800 return 0; 00801 } 00802 Node* child = _root->_left_child; 00803 if ( 0 == child ) { // no hay hijos 00804 return 0; 00805 } 00806 unsigned tot = 0; 00807 for (;;) { 00808 ++tot; // cuenta a este hijo 00809 if (child->_n_child > 0) { // todavía no se ha llegado al último hijo 00810 child = child->_right_brother; 00811 } else { 00812 break; 00813 } 00814 } 00815 return tot; 00816 } 00817 00818 inline bool operator == (const Tree &p, const Tree &q) { return Tree::Comp0(p._root, q._root); } 00819 inline bool operator != (const Tree &p, const Tree &q) { return !(p == q); } 00820 00821 /** Compara recursivamente los árboles cuyos nodo raíz son \c "*p" y \c "*q" 00822 00823 - Implementación recursiva para <code> operator==(Tree, Tree) </code> 00824 */ 00825 bool Tree::Comp0(const Tree::Node *p, const Tree::Node *q) { 00826 if (p == q) { 00827 return true; 00828 } 00829 if ( (p==0) || (q==0)) { // son diferentes... 00830 return false; // ...pues sólo 1 está vácio 00831 } 00832 if ( p->_n_child != q->_n_child ) { 00833 return false; // números de hijo diferentes 00834 } 00835 if ( ! (p->_data == q->_data) ) { 00836 return false; // valor diferente en la raíz 00837 } 00838 00839 // A comparar a todos los hijos 00840 p = p->_left_child; 00841 q = q->_left_child; 00842 for (;;) { 00843 if (p == q) { // como se terminaron juntos... 00844 return true; // ...son iguales 00845 } 00846 if ( (p==0) || (q==0) ) { // son diferentes... 00847 return false; // ...pues sólo 1 está vácio 00848 } 00849 if ( p->_n_child != q->_n_child ) { 00850 return false; // números de hijo diferentes 00851 } 00852 if (! Comp0(p, q) ) { 00853 return false; // recorrido recursivo 00854 } 00855 if ( p->_n_child < 0 ) { // assert( q->_n_child < 0 ); 00856 return true; // ya no hay más hermanos 00857 } 00858 p = p->_right_brother; 00859 q = q->_right_brother; 00860 } 00861 } 00862 00863 /** Verifica que se cumpla la invariante de la clase, o sea, que el objeto esté bien construido 00864 00865 - La razón por la que esta función no es un método es continuar la costumbre de muchos 00866 programadores quienes no definen la invariante para sus clases, pues en muchos 00867 casos sobra hacerlo. 00868 - No invoca \c Check_Ok( value_type& ) para cada valor almacenado, aunque si el árbol 00869 cumple con su invariante necesariamentes es porque también sus elementos almacenados 00870 están bien construidos. 00871 - Esta función en general es difícil de implementar, y en algunos casos es imposible 00872 pues, cuando el objeto no está bien construido, puede ocurrir que la función no 00873 retorne (como ocurriria si un nodo interno del árbol apunta de vuelta a la raíz, lo 00874 que se resulta en un círculo). 00875 - En general, la implementáción de esta función no es completa pues hay casos en que 00876 es imposible verificar la invariante de una clase. 00877 00878 \par Complejidad: 00879 O( \c Count() ) ==> tiempo <br> 00880 O( \c Height() ) ==> espacio 00881 00882 \post Retorna \c "true" si el árbol es un objeto bien construido 00883 \see \c Check_Ok(Tree&) 00884 00885 \see http://www.di-mare.com/adolfo/binder/c04.htm#sc11 00886 */ 00887 bool Check_Ok(Tree& T) { 00888 00889 if ( T.Empty() ) { 00890 return true; 00891 } 00892 00893 #ifdef NO_Implementado_para_evitar_forzar_que_el_valor_almacenado_tenga_su_metodo_OK 00894 if (! Check_Ok( T.Data() ) ) { // si el valor almacenado no esta bien... 00895 return false; //... tampoco lo está el árbol 00896 } 00897 /* Usar la función Check_Ok(Tree::value_type en lugar del método 00898 Tree::value_type::Ok() evitar forzar a que los programadores clientes 00899 que usen árboles estén obligados a implementar el método 00900 Tree::value_type::Ok(), que se encarga de verificar la invariante del valor 00901 almacenado en le árbol. 00902 - Lindo: if (! Check_Ok( T.Data() ) ) //.... la función Check_Ok() es opcional 00903 - ¡FEO!: if (! T.Data().Ok() ) //... pues obliga a que exista el método value_type::Ok() 00904 */ 00905 #endif 00906 00907 unsigned N = T.Rightmost().Child_Number(); 00908 for (unsigned i = 0; i < N; ++i) { 00909 if ( T.Child(i).Empty() ) { // este hijo no existe 00910 // continue; // con el siguiente 00911 } 00912 else if ( T.Child(i).Father() != T.Root() ) { // ==> ! T.Father.Empty() 00913 return false; // parece que este hijo no es mi hijo... 00914 } 00915 else if ( i != T.Child(i).Child_Number() ) { 00916 return false; // no estoy registrado como el i-ésimo hijo de mi padre 00917 } 00918 else if ( T.Child(i).Father().Child( i ) != T.Child( i ) ) { 00919 return false; // no estoy registrado como el i-ésimo hijo de mi padre 00920 } 00921 else if ( ! Check_Ok( T.Child(i) ) ) { 00922 return false; // hijo roto... 00923 } 00924 } 00925 return true; 00926 00927 // Las siguientes relaciones lógicas se cumplen 00928 // [ ! T.Empty() ] ==> [ T.Root()!= Tree() ] 00929 // [ T.Child(i).Father() == T.Root()] ==> [ ! T.Father.Empty() ] 00930 00931 /* Si este método retorna es porque el árbol está bien construido. Sin embargo, 00932 una invocación a Check_Ok() con un árbol mal construido posiblemente nunca retorne. 00933 */ 00934 } 00935 00936 00937 /** Sustituye por \c "d" el valor almacenado en la raíz del árbol 00938 00939 - Si el árbol está vacío, le agrega el nodo raíz. 00940 00941 \returns \c *this 00942 */ 00943 Tree Tree::Change_Root(const value_type & d) { 00944 if (_root == 0) { // como el árbol está vacío hay que agregarle la raíz 00945 _root = Node::Get_New(d); // crea el nodo raíz 00946 _root->_left_child = 0; 00947 _root->_right_brother = 0; 00948 _root->_n_child = -1; 00949 } else { // como no hay más referencias.... 00950 _root->_data = d; // ... cambia el valor directamente 00951 } 00952 return *this; 00953 } 00954 00955 /** Sustituye por \c "d" el valor almacenado en el hijo número \c "n" del árbol 00956 00957 - Si no existe el hijo número \c "n", lo agrega como una hoja con valor \c "d" 00958 - Si ya existe el hijo número \c "n", le sustituye su valor por \c "d" 00959 00960 \pre <code> !Empty() && (0 <= n) && (n < \e infinito) </code> 00961 00962 \par Complejidad: 00963 O( \c Count_Children() ) 00964 00965 \returns <code> Child(n) </code> 00966 */ 00967 Tree Tree::Change_Child(unsigned n, const value_type &d) { 00968 if (_root == 0) { // ignora árboles vacíos 00969 return Tree( ); 00970 } 00971 00972 n++; // evita incrementar "_n_child" en cada iteración 00973 00974 if (_root->_left_child == 0) { // Hay que agregar un sub-árbol nuevo 00975 Node * p = Node::Get_New(d); 00976 p->_n_child = -int(n); 00977 p->_right_brother = _root; 00978 _root->_left_child = p; 00979 p->_left_child = 0; 00980 return Tree ( (NOT_null_pointer*) _root->_left_child ); 00981 } 00982 00983 // assert( _root->_left_child != 0 ); 00984 Node* brother = _root->_left_child; 00985 unsigned n_brother = brother->Abs_n_child(); 00986 00987 if ( n < n_brother ) { // Hay que crear Child(n) y ponerlo de primero 00988 Node * p = Node::Get_New(d); 00989 p->_n_child = +int(n); 00990 p->_right_brother = brother; 00991 _root->_left_child = p; 00992 p->_left_child = 0; 00993 return Tree ( (NOT_null_pointer*) p ); 00994 } else if ( n == n_brother ) { 00995 brother->_data = d; // le cae encima al valor anterior 00996 return Tree ( (NOT_null_pointer*) brother ); 00997 } 00998 00999 // Child(n) no es el primer hijo de "_root" 01000 // assert( _root->_left_child != Child(n)._root ); 01001 01002 // assert( n_brother < n); // se corre hacia la derecha para encontrar "Child(n)" 01003 01004 Node* prev = brother; 01005 for (;;) { 01006 if ( brother->_n_child < 0 ) { 01007 if ( int(n) == - brother->_n_child ) { 01008 brother->_data = d; // le cae encima al valor anterior 01009 return Tree ( (NOT_null_pointer*) brother ); 01010 } else if (int(n) < - brother->_n_child ) { 01011 Node* p = Node::Get_New(d); // ... [d] ==> [brother] ==> end 01012 p->_n_child = int(n); 01013 p->_right_brother = brother; 01014 prev->_right_brother = p; 01015 p->_left_child = 0; 01016 return Tree ( (NOT_null_pointer*) p ); 01017 } else { 01018 Node* p = Node::Get_New(d); // ... [brother] ==> [d] ==> end 01019 p->_n_child = - int(n); 01020 p->_right_brother = brother->_right_brother; 01021 brother->_n_child = - brother->_n_child; // ahora el último es [d] 01022 brother->_right_brother = p; 01023 p->_left_child = 0; 01024 return Tree ( (NOT_null_pointer*) p ); 01025 } 01026 } else { // assert( brother->_n_child > 0 ); 01027 if ( int(n) == brother->_n_child ) { 01028 brother->_data = d; // le cae encima al valor anterior 01029 return Tree ( (NOT_null_pointer*) brother ); 01030 } else if ( brother->_n_child < int(n) ) { 01031 prev = brother; 01032 brother = brother->_right_brother; 01033 } else { // como se acaba de pasar ==> hay que agregarlo después de "prev" 01034 Node* p = Node::Get_New(d); 01035 p->_n_child = int(n); // como "brother" no es el último, tampoco lo será "p" 01036 p->_right_brother = brother; 01037 prev->_right_brother = p; 01038 p->_left_child = 0; 01039 return Tree ( (NOT_null_pointer*) p ); 01040 } 01041 } 01042 } 01043 } 01044 01045 /** Sustituye por \c "d" el valor almacenado en el hermano inmediatamente anterior del sub-árbol 01046 01047 - Si <code> n == Child_Number() </code> cambia el valor 01048 del hijo número \c "n-1" de \c Father() 01049 - Si no existe el hijo número \c "n-1" de \c Father() lo agrega como 01050 una hoja con valor \c "d" 01051 - Si ya existe ese hijo número \c "n-1", le sustituye su valor por \c "d" 01052 - Retorna un árbol vacío si no es posible que exista el hijo número \c "n-1" de \c Father() 01053 01054 \pre <code> !Empty() && (1 <= Child_Number()) </code> 01055 01056 \par Complejidad: 01057 O( <code> Father().Count_Children() </code> ) 01058 01059 \returns El hermano izquierdo, <code> Sibling(-1) </code> 01060 */ 01061 Tree Tree::Change_Left_Sibling_Inmediate( const value_type &d ) { 01062 unsigned n = Child_Number(); 01063 if (n > 0 ) { 01064 return Father().Change_Child( n-1, d ); 01065 } else { 01066 return Tree( ); 01067 } 01068 } 01069 01070 /** Sustituye por \c "d" el valor almacenado en el hermano inmediatamente posterior del sub-árbol 01071 01072 - Si <code> n == Child_Number() </code> cambia el valor 01073 del hijo número \c "n+1" de \c Father() 01074 - Si no existe el hijo número \c "n+1" de \c Father() lo agrega como 01075 una hoja con valor \c "d" 01076 - Si ya existe ese hijo número \c "n+1", le sustituye su valor por \c "d" 01077 - Retorna un árbol vacío si no es posible que exista el hijo número \c "n+1" de \c Father() 01078 01079 \pre <code> !Empty() && ( Child_Number() < \e infinito ) </code> 01080 01081 \par Complejidad: 01082 O( \c 1 ) 01083 01084 \returns El hermano derecho, <code> Sibling(+1) </code> 01085 */ 01086 Tree Tree::Change_Right_Sibling_Inmediate( const value_type &d ) { 01087 if (_root == 0) { 01088 return Tree( ); 01089 } 01090 if ( _root->_right_brother == 0 ) { // es la raíz del árbol y por eso no tiene hermanos 01091 return Tree( ); 01092 } 01093 01094 Node * brother; 01095 if ( _root->_n_child < 0 ) { // "*this" es el último hijo 01096 _root->_n_child = - _root->_n_child; // ya "_root" no es el último hijo 01097 01098 brother = Node::Get_New( d ); 01099 brother->_n_child = - ( _root->_n_child + 1 ); // "brother" es el último hijo 01100 01101 brother->_left_child = 0; 01102 brother->_right_brother = _root->_right_brother; 01103 _root->_right_brother = brother; 01104 01105 return Tree( (NOT_null_pointer*) brother ); 01106 } 01107 01108 // assert( _root->_n_child > 0 ); 01109 int n_brother = _root->_right_brother->Abs_n_child(); 01110 if ( _root->_n_child + 1 == n_brother ) { 01111 _root->_right_brother->_data = d; 01112 return Tree( (NOT_null_pointer*) _root->_right_brother ); 01113 } else { 01114 brother = Node::Get_New( d ); 01115 brother->_n_child = _root->_n_child + 1; // "brother" no puede ser el último hijo 01116 01117 brother->_left_child = 0; 01118 brother->_right_brother = _root->_right_brother; 01119 _root->_right_brother = brother; 01120 01121 return Tree( (NOT_null_pointer*) brother ); 01122 } 01123 } 01124 01125 /** Elimina recursivamente a \c "*p" y a todos sus descendientes 01126 01127 - Implementación recursiva para \c Erase() 01128 - Borra el nodo sólo después de que constata que ya no hay punteros que le apunten 01129 - No saca a \c "*p" de la lista de hijos del padre ==> ese es el trabajo 01130 de \c Graft() o \c Erase() 01131 - La rutina llamadora invoca \c Erase0() porque sabe que al decrementar 01132 \c "p->_refCount" queda en cero 01133 - No decrementa \c "p->_refCount" porque ya el invocador sabe que hay que destruir \c "*p" 01134 - Recursivamente, borra a los descendientes de \c "*p" 01135 01136 \code 01137 // Forma usual de invocación 01138 if ( child->_refCount <= 1 ) { // Ya no hay más referencias a "child" 01139 Erase0( child ); // lo elimina 01140 } else { 01141 child->_refCount--; // uno menos le apunta 01142 child->_n_child = -1; 01143 child->_right_brother = 0; // ya no es hijo de nadie 01144 } 01145 \endcode 01146 01147 \pre <code> (p != 0) && (p->_refCount == 1) </code> 01148 \post No cambia \c "p" porque trabaja con una copia de su valor 01149 */ 01150 void Tree::Erase0( Tree::Node * p ) { 01151 // assert( p != 0 ); 01152 // assert( p->_refCount == 1 ); 01153 01154 // Primero hay que matar hijos... 01155 if ( p->_left_child != 0 ) { 01156 Node *next, *child = p->_left_child; 01157 while ( child != 0 ) { // como hay hijos, decide a a cuáles matar 01158 if ( child->_n_child < 0 ) { 01159 next = 0; // lo obliga a salir porque "child" es el último 01160 } else { 01161 next = child->_right_brother; // recuerda quién es el siguiente 01162 } 01163 if ( child->_refCount == 1 ) { 01164 Erase0( child ); // lo mata porque ésta es la última referencia 01165 // OJO: "child" está destruido ==> "child->_right_brother" es un error 01166 } else { 01167 child->_refCount--; // ya "*p" no le apunta 01168 child->_n_child = -1; // ya no tiene padre porque "*p" va a morir 01169 child->_right_brother = 0; // ni tampoco tiene hermanos 01170 } 01171 child = next; // hay que evitar usar "child->_right_brother" si "child" ya está destruido 01172 } 01173 } 01174 #ifdef USE_v_Alive 01175 // Elimina a "p" de _v_Alive[] 01176 for (unsigned j = 0; j < Node::N_Alive; ++j) { 01177 if (p == Node::_v_Alive[j]) { // busca hasta que encuentra al puntero 01178 break; 01179 } 01180 } 01181 if (j < Node::N_Alive) { // sí lo encontró 01182 for (unsigned k = j; k < Node::N_Alive-1; ++k) { // corre a los demás para atrás 01183 Node::_v_Alive[k] = Node::_v_Alive[k+1]; 01184 } 01185 Node::_n_Alive--; // ahora hay uno menos 01186 Node::_v_Alive[ Node::_n_Alive ] = 0; 01187 } else { 01188 for (unsigned k = 0; k<3; ++j) { // marca "feos" los del final 01189 Node::_v_Alive[Node::N_Alive-1-k] = (Tree::Node *)(-1); 01190 } 01191 } 01192 #endif 01193 // Después de matar a los hijos, mata al nodo... 01194 delete p; // ... porque esta es la última referencia 01195 } 01196 01197 /** Elimina el árbol y sus descendientes 01198 01199 \par Complejidad: 01200 O( \c Count() ) + O( <code> Father().Count() </code> ) ==> tiempo <br> 01201 O( \c Height() ) ==> espacio 01202 01203 \see http://www.di-mare.com/adolfo/binder/c04.htm#sc03 01204 */ 01205 void Tree::Erase() { 01206 if (_root == 0) { 01207 return; 01208 } 01209 01210 // Encuentra el padre de "_root" 01211 Node* brother = _root; // camina sobre los hermanos hasta llegar al padre 01212 while (brother->_n_child > 0) { 01213 brother = brother->_right_brother; // se brinca los que no tienen el puntero al padre 01214 } 01215 Node* father = brother->_right_brother; 01216 // assert( Father().Same( Tree( brother ) ) ); 01217 01218 // Desconecta a "_root" de la lista de hijos del padre 01219 if (father == 0) { // sólo la raíz tiene en blanco el puntero "_right_brother" 01220 // no hay que desenlazar a la raíz porque nunca está en una lista de hermanos 01221 } else { 01222 // busca al "nodo anterior" para sacar a "_root" de la lista de sus hermanos 01223 if ( _root == father->_left_child ) { // "_root" es el hijo más izquierdo 01224 if ( _root->_n_child < 0 ) { 01225 father->_left_child = 0; // elimina la lista de hijos porque "_root" no tiene hermanos 01226 } else { 01227 father->_left_child = _root->_right_brother; // desenlaza al primer hijo 01228 } 01229 } else { 01230 brother = father->_left_child; // hijo más izquierdo de Father() 01231 while ( _root != brother->_right_brother ) { 01232 brother = brother->_right_brother; 01233 } 01234 brother->_right_brother = _root->_right_brother; // saca a "_root" de la lista de hermanos 01235 } 01236 } 01237 01238 // ahora ya puede detruir al nodo 01239 if ( _root->_refCount == 1 ) { 01240 Erase0(_root); // mata al nodo porque ésta es la última referencia 01241 } else { 01242 _root->_refCount--; // lo va a desconectar de "_root" 01243 _root->_n_child = -1; // ya no tiene padre 01244 _root->_right_brother = 0; // ni tampoco tiene hermanos 01245 } 01246 _root = 0; 01247 } 01248 01249 // Esta documentación para Tree::Erase_Son() aparece acá porque Doxygen no permite 01250 // incluir un párrafo aparte "\par" en la documentación de 1 sólo renglón. 01251 01252 /** \fn void Tree::Erase_Son(unsigned n) 01253 01254 \brief Elimina el sub-árbol número \c "n" 01255 01256 \par Complejidad: 01257 O( <code> Child(n).Count() </code> ) ==> tiempo <br> 01258 O( <code> Height( Child(n) ) </code> ) ==> espacio 01259 */ 01260 01261 /** Elimina el sub-árbol número \c "n-1" y retorna un puntero al nodo anterior al borrado 01262 01263 - Esta es la rutina que en realidad hace el trabajo de \c Erase_Son(). 01264 - Elimina el sub-árbol número \c "n-1", como también lo hace \c Erase_Son(). 01265 - La única diferencia con \c Erase_Son() es que este método retorna un puntero 01266 al nodo anterior al nodo eliminado. 01267 - "prev" apunta al nodo que está antes de "prev" en el árbol. 01268 - Trabaja con \c "n-1" porque no incrementa el valor de \c "n", pues se supone que 01269 la rutina invocadora ya hizo ese ajuste en el valor originar de \c "n". 01270 - Esta rutina existe para compartir el código que se necesita para implementar 01271 \c Erase_Son() y \c Graft(). 01272 - Si retorna <code> 0 == NULL </code> es porque <code> Nodo[n-1] </code> 01273 debe ser el primero en la lista de hijos del padre. 01274 01275 \remark [Eliminado porque ya no hace falta] 01276 - "prev_prev" apunta al nodo que está antes de "prev" en el árbol. 01277 - Si "prev" y "prev_prev" son la misma variable, el valor correcto para "prev" es 01278 calculado. 01279 */ 01280 void Tree::Erase_Son_Prev(unsigned n, Node* & prev /*, Node* & prev_prev */) { 01281 // prev_prev = 0; // el que está "antes" de "prev" 01282 prev = 0; // nodo que antecede a "child" 01283 if (_root == 0) { // ignora árboles vacíos 01284 return; 01285 } 01286 Node* child = _root->_left_child; // "child" es el nodo que hay que eliminar 01287 if ( child == 0 ) { // no hay hijos ==> el Nodo[n] es un sub-árbol vacío 01288 return; 01289 } 01290 01291 // n++; // sobra, porque la rutina invocadora ya ajustó el valor a cotejar con "_n_child" 01292 01293 // camina sobre los hermanos hasta llegar a Nodo[n] 01294 if ( child->_n_child <= 0 ) { // sólo hay un hijo 01295 unsigned n_child = - child->_n_child; 01296 if ( n == n_child ) { // es el único hijo y hay que eliminarlo 01297 if ( child->_refCount <= 1 ) { // aquí saca a "child" de la lista de hijos de "_root" 01298 Erase0( child ); 01299 } else { 01300 child->_refCount--; 01301 child->_n_child = -1; 01302 child->_right_brother = 0; // ya no es hijo de nadie 01303 } 01304 _root->_left_child = 0; 01305 return; 01306 } else { // no hace falta eliminar a nadie pues Child(n) es un sub-árbol vacío 01307 // hay que determinar adónde debe apuntar "prev" 01308 if ( n > n_child ) { 01309 // prev_prev = prev; 01310 prev = child; 01311 return; // porque el n-ésimo hijo estará después de "child" 01312 } else { // assert( n < n_child ); 01313 return; // el n-ésimo hijo quedará de primero en la lista de hijos del padre 01314 } 01315 } 01316 } 01317 01318 // assert( (child->_n_child > 0) && (Count_Children() > 1) ); 01319 for (;;) { 01320 if (child->_n_child <= 0) { // hay que eliminar el último hijo 01321 if ( unsigned(- child->_n_child) == n ) { // assert( prev != 0 ); 01322 prev->_right_brother = child->_right_brother; 01323 prev->_n_child = - prev->_n_child; // este es el nuevo último 01324 if ( child->_refCount <= 1 ) { 01325 Erase0( child ); 01326 } else { 01327 child->_refCount--; 01328 child->_n_child = -1; 01329 child->_right_brother = 0; // ya no es hijo de nadie 01330 } 01331 } else if ( unsigned(- child->_n_child) < n ) { 01332 // no encontró al hermano con _n_child == n 01333 // prev_prev = prev; 01334 prev = child; 01335 } 01336 break; 01337 } else if ( unsigned(child->_n_child) == n ) { 01338 if ( prev == 0 ) { 01339 _root->_left_child = child->_right_brother; 01340 } else { 01341 prev->_right_brother = child->_right_brother; 01342 } 01343 if ( child->_refCount <= 1 ) { 01344 Erase0( child ); 01345 } else { 01346 child->_refCount--; 01347 child->_n_child = -1; 01348 child->_right_brother = 0; // ya no es hijo de nadie 01349 } 01350 break; 01351 } else if ( unsigned(child->_n_child) < n) { 01352 // prev_prev = prev; 01353 prev = child; 01354 child = child->_right_brother; 01355 } else { // assert( unsigned(child->_n_child) > n ); 01356 break; // no encontró al hermano con _n_child == n 01357 } 01358 } 01359 } 01360 01361 /** Verifica que se cumpla la invariante de la clase, o sea, que el objeto esté bien construido 01362 01363 - Además de todo el trabajo que hace \c Check_Ok(Tree& T), acá hay que constatar que 01364 el nodo raíz no tiene padre, que es la diferencia fundamental entre un árbol y un sub-árbol 01365 01366 \post Retorna \c "true" si el árbol es un objeto bien construido 01367 01368 \deprecated Los árboles y los sub-árboles son la misma cosa. 01369 01370 \see \c Check_Ok(Tree&) 01371 */ 01372 inline bool Check_Ok_Tree(Tree& T) { 01373 if ( T.Root().Empty() ) { 01374 return true; 01375 } else { 01376 return ( T.Root().Father().Empty() ) && Check_Ok( Tree (T) ); 01377 } 01378 } 01379 01380 /** Hace una copia profunda nodo por nodo del árbol cuyo nodo raíz es \c "*p" 01381 01382 - Implementación recursiva para \c Tree::Copy_Deep() 01383 - No altera \c p->_refCount porque copia los nodos 01384 - El campo \c p->_right_brother queda con basura porque no queda inicializado 01385 - Le corresponde a la rutina invocadora inicializar \c p->_right_brother 01386 01387 \pre <code> p != 0 </code> 01388 \post No cambia \c "p" porque trabaja con una copia de su valor 01389 01390 \returns Puntero al nodo raíz del árbol copiado 01391 */ 01392 Tree::Node * Tree::Copy_Deep0(const Node * p) { 01393 Node * q; // resultado 01394 q = Node::Get_New(p->_data); // _refCount = 1; 01395 q->_n_child = p->_n_child; 01396 01397 if ( p->_left_child == 0 ) { 01398 q->_left_child = 0; 01399 } else { // cuando hay hijos los copia 01400 Node * pChild = p->_left_child; 01401 Node * qChild = Copy_Deep0( pChild ); // copia el primer nodo 01402 q->_left_child = qChild; 01403 while ( pChild->_n_child > 0 ) { 01404 pChild = pChild->_right_brother; 01405 qChild->_right_brother = Copy_Deep0( pChild ); 01406 qChild = qChild->_right_brother; 01407 } 01408 qChild->_right_brother = q; // "q" es el padre de todos 01409 } 01410 return q; 01411 } 01412 01413 /** Copia profunda de \c "o" 01414 01415 - Copia todo el valor de \c "o" sobre \c "*this", de forma que el nuevo valor de 01416 \c "*this" sea un duplicado exacto del valor de \c "o" 01417 - El valor anterior de \c "*this" se pierde 01418 - El objeto \c "o" mantiene su valor anterior 01419 - Luego de la copia, cuando el valor de \c "o" cambia, el de \c "*this" no cambiará, 01420 y viceversa, pues la copia es una copia profunda; no es superficial 01421 - Si \c "*this" es \c "o" entonces su valor no cambia 01422 - Después de esta operación siempre ocurre que <code> *this == o </code> 01423 01424 \par Complejidad: 01425 O( \c Count() ) + O( \c o.Count() ) 01426 01427 \returns \c *this 01428 01429 \see http://www.di-mare.com/adolfo/binder/c04.htm#sc05 01430 */ 01431 Tree& Tree::Copy_Deep(const Tree &o) { 01432 // Borra el valor actual 01433 if (_root != 0) { 01434 if ( _root->_refCount == 1 ) { // como es el último... 01435 Erase0(_root); // ...lo mata 01436 } else { 01437 _root->_refCount--; 01438 } 01439 } 01440 01441 // Hace la copia desde "o" 01442 if (o._root != 0 ) { 01443 _root = Copy_Deep0( o._root ); 01444 _root->_n_child = -1; // es el nodo raíz 01445 _root->_right_brother = 0; 01446 _root->_refCount = 1; 01447 } else { 01448 _root = 0; 01449 } 01450 return *this; 01451 } 01452 01453 /** Injerta \c "o" para que sea el \c "n"-ésimo hijo de \c "*this" 01454 01455 - Si \c "o" es sub-árbol de otro árbol, dejara de serlo para pasar ser hijo de \c "*this" 01456 - Si \c "*this" tiene un \c "n"-ésimo hijo, ese hijo desaparece 01457 - Si \c "o" está vacío, elimina el \c "n"-ésimo hijo del árbol [<code> Erase_Son(n) </code>] 01458 01459 \pre 01460 - <code> ! Root().Empty() </code> 01461 - Si el árbol está vacío no tiene raíz, y por lo tanto tampoco puede tener hijos 01462 - <code> ! Ancestor(o, *this) </code> 01463 - "o" no puede ser ancestro de *this" 01464 - <code> (0 <= n) && (n < \e infinito) </code> 01465 - <code> ! Root(). Same( o.Root() ) </code> 01466 01467 \post 01468 - \c "o" deja de ser sub-árbol del árbol en que estaba 01469 - <code> o.Father() .Same( Root() ) </code> 01470 01471 \remarks 01472 - Un sub-árbol puede ser hijo (o sub-árbol) de otro árbol 01473 - Un sub-árbol puede ser hijo únicamente de un árbol 01474 - Este método no hace nada cuando [ <code> ! Root() .Same( o.Root() ) </code> ] 01475 - Injertar un sub-árbol vacío es una forma de eliminar a un hijo junto con 01476 toda su descendencia 01477 01478 \returns "o" ==> El árbol recién injertado 01479 01480 \par Complejidad:: 01481 O( \c Count_Children() ) + O( <code> o.Father().Count_Children() </code> ) 01482 01483 */ 01484 Tree Tree::Graft(unsigned n, Tree &o) { 01485 if (_root == 0) { // ignora árboles vacíos 01486 return Tree( ); 01487 } 01488 if (_root == o._root) { // evita auto-borrado 01489 return *this; 01490 } 01491 #ifdef FALTA_verificar_en_Graft 01492 bool Ancestor( Tree & Child, Tree & Father ); 01493 assert( ! Ancestor( o, *this ) ); // "o" no puede ser ancestro de *this" 01494 #endif 01495 01496 n++; // lo incrementa para no incrementar "_n_child" para cada hijo de "_root" o de "o" 01497 01498 if ( o._root == 0 ) { // Sólo hay que eliminar el hijo número "n" de "_root" 01499 Node * prev; 01500 Erase_Son_Prev(n, prev /*, prev */); 01501 return Tree( ); // si se vale repetir "prev" en Erase_Son_Prev() 01502 } 01503 // assert( o._root != 0 ); 01504 01505 // Determina quién es el padre de "o" 01506 Node * brother = o._root; 01507 while ( brother->_n_child > 0 ) { 01508 brother = brother->_right_brother; 01509 } 01510 Node * o_father = brother->_right_brother; // éste es el padre de "o" 01511 Node * prev; 01512 01513 if ( o_father != _root ) { 01514 /* El puntero "prev" apunta al nodo después del que hay que injertar "o". 01515 - Si "prev == 0" hay que poner a "o" de primero en lista de hijos de "_root". 01516 - Si "prev != 0" hay que instalar "o" después de "prev". 01517 - Aquí es donde se usa Erase_Son_Prev(). 01518 */ 01519 // Elimina el hijo número "n" de "_root" 01520 Erase_Son_Prev(n, prev /*, prev */); 01521 // assert( Child(n-1).Empty() ); // Ojo: mata "Child(n-1)" porque ya "n" está incrementado 01522 } else { // assert( o_father == _root ); // Caso especial ==> T.Graft( T.Child(n), n ± i ); 01523 unsigned o_n_child = o._root->Abs_n_child(); 01524 if ( o_n_child == n ) { // Caso especial cuando "o" ya es hijo de "_root" 01525 // "o" está en su lugar ==> no hay que hacer nada 01526 // [y hay que evitar borrarlo con Erase_Son(n)] 01527 return Tree( (NOT_null_pointer*) o._root ); 01528 } 01529 01530 Erase_Son_Prev(n, prev /*, prev */); 01531 01532 if ( (prev == o._root) || (prev != 0 && prev->_right_brother == o._root ) ) { 01533 // ya "o" está en donde debe 01534 if ( o._root->_right_brother == _root ) { // basta cambiar "_n_child" 01535 o._root->_n_child = - int(n); 01536 } else { 01537 o._root->_n_child = + int(n); 01538 } 01539 return Tree( (NOT_null_pointer*) o._root ); 01540 } 01541 } 01542 01543 if (o_father != 0) { // Saca a "o" de la lista de hijos de su padre 01544 o._root->_refCount--; // pues no estará en la lista de hijos de su padre actual 01545 assert( o_father->_left_child != 0 ); 01546 if ( o._root == o_father->_left_child ) { // "o" es el primer hijo 01547 if ( o._root->_n_child < 0 ) { // "o" es el único hijo 01548 o_father->_left_child = 0; 01549 } else { // "o" tiene hermanos 01550 o_father->_left_child = o._root->_right_brother; 01551 } 01552 } else { 01553 brother = o_father->_left_child; // hermano más izquierdo de "o" 01554 while ( brother->_right_brother != o._root ) { 01555 brother = brother->_right_brother; 01556 } 01557 brother->_right_brother = o._root->_right_brother; 01558 if ( o._root->_n_child < 0 ) { // "o" estaba de último hijo 01559 brother->_n_child = - brother->_n_child; // hay un nuevo hijo de último 01560 } 01561 } 01562 } 01563 // assert( o.Father().Empty() ); // ya "o" está solito y sin familia 01564 01565 o._root->_refCount++; // lo incrementa porque lo va a enlazar como hijo de "_root" 01566 01567 if ( prev == 0 ) { // enlaza "o" al principio de la lista de hijos de "_root" 01568 if ( _root->_left_child == 0 ) { 01569 o._root->_right_brother = _root; // "o" será el único hijo de "_root" 01570 o._root->_n_child = - int(n); 01571 _root->_left_child = o._root; 01572 } else { 01573 o._root->_right_brother = _root->_left_child; 01574 // assert( o._root->_right_brother != _root ); 01575 o._root->_n_child = + int(n); 01576 _root->_left_child = o._root; 01577 } 01578 } else { // assert( prev != 0 ); 01579 // enlaza en el medio de la lista de hijos de "_root" 01580 o._root->_right_brother = prev->_right_brother; 01581 prev->_right_brother = o._root; 01582 if ( o._root->_right_brother == _root ) { 01583 prev->_n_child = - prev->_n_child; // ya "prev" no está de último 01584 o._root->_n_child = - int(n); 01585 } else { 01586 o._root->_n_child = + int(n); 01587 } 01588 } 01589 01590 return Tree( (NOT_null_pointer*) o._root ); 01591 01592 01593 /* ¿Por qué hay que usar "prev_prev"? En realidad no hace falta, pero sí hay que 01594 destacar un caso especial, cuando "o" es hijo de "*this", o sea cuando: 01595 - ( Root(). Same( o.Root() ) ) 01596 R T.Erase(); T = 'R'; 01597 / \ T.Change_Child(1, '1'); 01598 1 3 T.Change_Child(3, '3'); 01599 01600 Al ejecutar T.Graft( 5 , T.Child(3) ); lo que hay que hacer es desligar el Nodo['3'] de su 01601 padre, el árbol T que tiene por raíz a Nodo['A'], para ligarlo de nuevo como Nodo['5']. 01602 01603 Para este caso, "prev" apunto a T.Child(3), pues es después de Nodo['3'] en donde habría 01604 que enlazar a Nodo['5']. Desafortunadamente, como el primer paso del algoritmo saca de 01605 T a Nodo[3], al tratar de enlazarlo luego de "prev" en realidad lo que se haría es 01606 enlazar al nodo después de sí mismo; estor resulta en la "desaparición misteriosa" 01607 de Nodo['3']. Por eso, la solución a este caso especial, es retornar no "prev", sino 01608 "prev_prev", que apunta al nodo anterio al Nodo[5], que en este caso es Nodo['1']. 01609 */ 01610 } // Graft() 01611 01612 } // namespace TL 01613 01614 using namespace TL; 01615 01616 #endif // Tree_L_h 01617 01618 // EOF: Tree_L.h