Página principal | Lista de namespace | Lista de componentes | Lista de archivos | Miembros del Namespace  | Miembros de las clases | Archivos de los miembros | Páginas relacionadas

Tree_L.h

Ir a la documentación de este archivo.
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

Generado el Sun Feb 19 09:37:34 2006 para Uso de TL::Tree y TV::Tree: por  doxygen 1.3.9.1