Java iterators for C++:
|
Los métodos para trabajar con árboles regresan "referencias" que son sub-árboles. More...
#include <Tree_L.h>
Public Types | |
typedef E | value_type |
Nombre estándar del tipo de elemento contenido. More... | |
Public Member Functions | |
Operaciones de copiado | |
Tree & | operator= (const Tree &o) |
Sinónimo de this->Copy(o) More... | |
Tree & | Copy (const Tree &o) |
Copia superficial desde "o" . More... | |
Tree & | Move (Tree &o) |
Traslada el valor de "o" a "*this" . More... | |
Tree & | Swap (Tree &o) |
Intercambia los valores de "*this" y "o" . More... | |
Tree & | Copy_Deep (const Tree &o) |
Copia profunda de "o" . More... | |
Tree & | operator= (const value_type &d) |
Usa Change_Root() para sustituir por "d" el valor almacenado en la raíz del árbol. More... | |
Métodos para cambiar los valores almacenados en el árbol | |
Tree | Change_Root (const value_type &d) |
Sustituye por "d" el valor almacenado en la raíz del árbol. More... | |
Tree | Change_Child (unsigned n, const value_type &d) |
Sustituye por "d" el valor almacenado en el hijo número "n" del árbol. More... | |
Tree | Change_Left_Sibling_Inmediate (const value_type &d) |
Sustituye por "d" el valor almacenado en el hermano inmediatamente anterior del sub-árbol. More... | |
Tree | Change_Right_Sibling_Inmediate (const value_type &d) |
Sustituye por "d" el valor almacenado en el hermano inmediatamente posterior del sub-árbol. More... | |
Tree | Graft (unsigned n, Tree &o) |
Injerta "o" para que sea el "n"-ésimo hijo de "*this" . More... | |
Operaciones para usar los valores almacenados | |
value_type & | Data () |
Valor almacenado en la raíz del sub-árbol. More... | |
value_type & | operator* () |
Valor almacenado en la raíz del sub-árbol. More... | |
value_type * | operator-> () |
Puntero al valor almacenado en la raíz del sub-árbol. More... | |
const value_type & | Data () const |
Valor almacenado en la raíz del sub-árbol. More... | |
const value_type & | operator* () const |
Valor almacenado en la raíz del sub-árbol. More... | |
const value_type * | operator-> () const |
Puntero al valor almacenado en la raíz del sub-árbol. More... | |
Métodos para recorrer el árbol | |
Tree | Root () const |
Raíz del sub-árbol. More... | |
Tree | Father () const |
Acceso al padre. More... | |
Tree | Child (unsigned n) const |
Acceso al "n"-ésimo hijo. More... | |
Tree | Left () const |
Sub-árbol izquierdo [en un árbol binario]. More... | |
Tree | Right () const |
Sub-árbol derecho [en un árbol binario]. More... | |
Tree | Leftmost () const |
Obtiene el hijo más izquierdo del árbol. More... | |
Tree | Rightmost () const |
Obtiene el hijo más derecho del árbol. More... | |
Tree | Sibling (int n) const |
"n"-ésimo hermano a partir de "*this" . More... | |
Tree | Left_Sibling () const |
Obtiene el hermano no vacío anterior, que está hacia la izquierda. More... | |
Tree | Right_Sibling () const |
Obtiene el hermano no vacío siguiente, que está hacia la derecha. More... | |
Tree | Previous_Sibling () const |
Sinónimo de Left_Sibling() More... | |
Tree | Prev_Sibling () const |
Sinónimo de Left_Sibling() More... | |
Tree | Next_Sibling () const |
Sinónimo de Right_Sibling() More... | |
Tree | Right_Sibling_Inmediate () const |
Obtiene el hermano que está inmediatamente hacia la derecha. More... | |
Tree | Left_Sibling_Inmediate () const |
Obtiene el hermano que está inmediatamente hacia la izquierda. More... | |
Propiedades del árbol | |
unsigned | Child_Number () const |
Retorna "n" si "*this" es el n-ésimo hijo de su padre, si no retorna 0 (cero) More... | |
unsigned | Leftmost_N () const |
Retorna "n" si el hijo más izquierdo de "*this" es el n-ésimo hijo, si no retorna 0 (cero) More... | |
unsigned | Rightmost_N () const |
Retorna "n" si el hijo más derecho de "*this" es el n-ésimo hijo, si no retorna 0 (cero) More... | |
bool | Is_Leaf () const |
Retorna "true" si el árbol es una hoja. More... | |
bool | Is_Root () const |
Retorna "true" si el árbol no tiene padre. More... | |
unsigned | use_count () const |
Cantidad de referencias de la raíz del árbol. More... | |
Static Private Member Functions | |
Funciones para manipular valores a bajo nivel | |
static Tree & | CastTo_Sub_Tree_Ref (Tree_Node< E > *&p) |
Convierte el puntero al nodo en un referencia a Tree . More... | |
Funciones recursivas que realizan el trabajo sobre nodos | |
static void | Erase0 (Tree_Node< E > *p) |
Elimina recursivamente a "*p" y a todos sus descendientes. More... | |
static bool | Comp0 (const Tree_Node< E > *p, const Tree_Node< E > *q) |
Compara recursivamente los árboles cuyos nodo raíz son "*p" y "*q" . More... | |
static void | Count0 (const Tree_Node< E > *p, unsigned &n) |
Implementación recursiva para Count() . More... | |
static Tree_Node< E > * | Copy_Deep0 (const Tree_Node< E > *p) |
Hace una copia profunda nodo por nodo del árbol cuyo nodo raíz es "*p" . More... | |
Private Attributes | |
Tree_Node< E > * | m_root |
Un árbol "es" el puntero al nodo raíz. More... | |
Constructores y destructor | |
typedef void | NOT_null_pointer |
Truco para usar el constructor que no verifica (p != 0) More... | |
Tree () | |
Constructor de vector. More... | |
Tree (const Tree &o) | |
Constructor de copia desde otro árbol (copia superficial). More... | |
Tree (const value_type &d) | |
Constructor a partir de un valor. More... | |
~Tree () | |
Destructor. More... | |
Tree (Tree_Node< E > *p) | |
Constructor a partir de un nodo. More... | |
Tree (NOT_null_pointer *p) | |
Constructor a partir de un nodo [ requiere p != 0 ]. More... | |
Operaciones básicas | |
bool | Empty () const |
Retorna "true" si el sub-árbol está vacío. More... | |
unsigned | Count () const |
Retorna la cantidad de valores almacenados en el sub-árbol. More... | |
unsigned | Count_Children () const |
Retorna la cantidad de hijos del árbol. More... | |
unsigned | Size () const |
Usa Count() para retornar la cantidad de valores almacenados en el sub-árbol. More... | |
bool | Ok () |
Usa check_ok(Tree& T) para verificar la invariante de Tree . More... | |
bool | check_ok (const Tree< E > &T) |
Verifica que se cumpla la invariante de la clase, o sea, que el objeto esté bien construido. More... | |
Operaciones de borrado | |
void | Erase () |
Elimina el árbol y sus descendientes. More... | |
void | Erase_Son (unsigned n) |
Elimina el sub-árbol número "n" . More... | |
void | Erase_Son_Prev (unsigned n, Tree_Node< E > *&) |
Elimina el sub-árbol número "n-1" y retorna un puntero al nodo anterior al borrado. More... | |
Operaciones de comparación | |
bool | Equals (const Tree &o) const |
¿¿¿ (*this==o) ??? More... | |
bool | Same (const Tree &o) const |
Retorna true si "o" comparte la raíz con "*this" . More... | |
template<class X > | |
bool | operator== (const Tree< X > &p, const Tree< X > &q) |
¿¿¿ (p == q) ??? More... | |
template<class X > | |
bool | operator!= (const Tree< X > &p, const Tree< X > &q) |
¿¿¿ (p != q) ??? More... | |
Los métodos para trabajar con árboles regresan "referencias" que son sub-árboles.
Tree::Copy_Deep()
.Father()
o Root()
sean métodos const
.Tree&
porque es más eficiente, pues cada vez que un Tree
es copiado hay que actualizar la "cuenta de referencia" de la raíz del sub-árbol. typedef E TL::Tree< E >::value_type |
|
private |
Truco para usar el constructor que no verifica (p != 0)
Truco para evitar comparar con 0
( nil
) al usar Tree::Tree_Node<E>*
para construir Tree()
.
Al implementar cada uno de los métodos de Tree
con frecuencia ocurre que es posible saber que el sub-árbol retornado no está vacío. En estos casos, conviene usar un contructor que no verifique si la raíz del árbol es nula.
Esta clase se usa como una marca para que se ejecute el contructor Tree::Tree(NOT_null_pointer* p)
que no verifica la nulidad de "m_root"
; esta es una micro-eficiencia, pero aquí sirve para mostrar un truco que es muy usado en C++ para aumentar la eficiencia de los programas, pues le permite al programado usar la sobrecarga de operadores para evitar repetir verificaciones innecesarias.
|
inline |
Destructor.
Count()
)
|
inlineprivate |
|
inline |
unsigned TL::Tree< E >::Count | ( | ) | const |
Retorna la cantidad de valores almacenados en el sub-árbol.
Count()
) ==> tiempo Height()
) ==> espaciounsigned TL::Tree< E >::Count_Children | ( | ) | const |
Retorna la cantidad de hijos del árbol.
Count_Children()
)
|
inline |
|
inline |
void TL::Tree< E >::Erase | ( | ) |
|
inline |
|
private |
Elimina el sub-árbol número "n-1"
y retorna un puntero al nodo anterior al borrado.
Erase_Son()
."n-1"
, como también lo hace Erase_Son()
.Erase_Son()
es que este método retorna un puntero al nodo anterior al nodo eliminado."n-1"
porque no incrementa el valor de "n"
, pues se supone que la rutina invocadora ya hizo ese ajuste en el valor originar de "n"
.Erase_Son()
y Graft()
. 0 == NULL
es porque Nodo[n-1]
debe ser el primero en la lista de hijos del padre.Copia superficial desde "o"
.
"*this"
se pierdeCount()
)Traslada el valor de "o"
a "*this"
.
Intercambia los valores de "*this"
y "o"
.
"*this"
en lugar de una referencia, como ocurre con Tree::Child()
, a veces Swap()
no tiene el resultado esperado por el programador.Por ejemplo, si se invoca T.Child(i). Swap( T.Child(j) )
el resultado no es intercambiar los hijos, sino más bien intercambiar los valores de los sub-árboles temporales T.Child(i)
y T.Child(j)
. La forma correcta de intercambiar hijos es usar Graft()
.
1
)Copia profunda de "o"
.
"o"
sobre "*this"
, de forma que el nuevo valor de "*this"
sea un duplicado exacto del valor de "o"
"*this"
se pierde"o"
mantiene su valor anterior"o"
cambia, el de "*this"
no cambiará, y viceversa, pues la copia es una copia profunda; no es superficial"*this"
es "o"
entonces su valor no cambia *this == o
Count()
) + O( o.Count()
)*this
|
inline |
Usa Change_Root()
para sustituir por "d" el valor almacenado en la raíz del árbol.
Tree< E > TL::Tree< E >::Change_Root | ( | const value_type & | d | ) |
Tree< E > TL::Tree< E >::Change_Child | ( | unsigned | n, |
const value_type & | d | ||
) |
Sustituye por "d"
el valor almacenado en el hijo número "n"
del árbol.
"n"
, lo agrega como una hoja con valor "d"
"n"
, le sustituye su valor por "d"
!Empty() && (0 <= n) && (n < infinito)
Count_Children()
) Child(n)
Tree< E > TL::Tree< E >::Change_Left_Sibling_Inmediate | ( | const value_type & | d | ) |
Sustituye por "d"
el valor almacenado en el hermano inmediatamente anterior del sub-árbol.
n == Child_Number()
cambia el valor del hijo número "n-1"
de Father()
"n-1"
de Father()
lo agrega como una hoja con valor "d"
"n-1"
, le sustituye su valor por "d"
"n-1"
de Father()
!Empty() && (1 <= Child_Number())
Father().Count_Children()
) Sibling(-1)
Tree< E > TL::Tree< E >::Change_Right_Sibling_Inmediate | ( | const value_type & | d | ) |
Sustituye por "d"
el valor almacenado en el hermano inmediatamente posterior del sub-árbol.
n == Child_Number()
cambia el valor del hijo número "n+1"
de Father()
"n+1"
de Father()
lo agrega como una hoja con valor "d"
"n+1"
, le sustituye su valor por "d"
"n+1"
de Father()
!Empty() && ( Child_Number() < infinito )
1
) Sibling(+1)
Injerta "o"
para que sea el "n"-ésimo
hijo de "*this"
.
"o"
es sub-árbol de otro árbol, dejara de serlo para pasar ser hijo de "*this"
"*this"
tiene un "n"-ésimo
hijo, ese hijo desaparece"o"
está vacío, elimina el "n"-ésimo
hijo del árbol [ Erase_Son(n)
]"o"
deja de ser sub-árbol del árbol en que estaba o.Father() .Same( Root() )
! Root() .Same( o.Root() )
]Count_Children()
) + O( o.Father().Count_Children()
)
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
Acceso al padre.
Father().Count_Children()
) Acceso al "n"-ésimo
hijo.
"n"
retorna el sub-árbol vacío. Father().Count_Children()
) Obtiene el hijo más izquierdo del árbol.
Right_Sibling()
1
)Obtiene el hijo más derecho del árbol.
Left_Sibling()
Count_Children()
)"n"-ésimo
hermano a partir de "*this"
.
"n"
"posiciones"."n"
:n=0
, regresa "*this"
.n>0
, regresa el hermano número "+n"
contando hacia la derecha de "*this"
.n<0
, regresa el hermano número "-n"
contando hacia la izquierda de "*this"
."n"
retorna un sub-árbol vacío."T"
tiene 3 hijos no vacíos "B"
, "C"
y "E"
y tiene 4 sub-árboles: C.Sibling( +0 ) == C
B.Sibling( +1 ) == C
E.Sibling( -2 ) == C
E.Sibling( -1 ) –> Vacío
A.Sibling( +1 ) –> Vacío
B.Sibling( -1 ) –> Vacío
E.Sibling( +1 ) –> Vacío
Father().Count_Children()
) Obtiene el hermano no vacío anterior, que está hacia la izquierda.
n == Child_Number()
no necesariamente ocurrirá que (n-1)== Left_Sibling().Child_Number()
pues los anteriores hijos de Father()
pueden ser sub-árboles vacíos, como ocurre si un árbol binario tiene hijo derecho pero no tiene hijo izquierdo.Rightmost()
Father().Count_Children()
) Obtiene el hermano no vacío siguiente, que está hacia la derecha.
n == Child_Number()
no necesariamente ocurrirá que (n+1) == Right_Sibling().Child_Number()
pues los siguientes hijos de Father()
pueden ser sub-árboles vacíos, como ocurre si un árbol binario tiene hijo izquierdo pero no tiene hijo derecho.Leftmost()
1
) Sinónimo de Left_Sibling()
Sinónimo de Left_Sibling()
Sinónimo de Right_Sibling()
Obtiene el hermano que está inmediatamente hacia la izquierda.
Sibling
( -1 ) Father().Count_Children()
)
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
Elimina recursivamente a "*p"
y a todos sus descendientes.
Erase()
"*p"
de la lista de hijos del padre ==> ese es el trabajo de Graft()
o Erase()
Erase0()
porque sabe que al decrementar "p->m_refCount"
queda en cero"p->m_refCount"
porque ya el invocador sabe que hay que destruir "*p"
"*p"
(p != 0) && (p->m_refCount == 1)
"p"
porque trabaja con una copia de su valor
|
staticprivate |
Hace una copia profunda nodo por nodo del árbol cuyo nodo raíz es "*p"
.
Tree::Copy_Deep()
p->m_refCount
porque copia los nodosp->m_right_brother
queda con basura porque no queda inicializadop->m_right_brother
p != 0
"p"
porque trabaja con una copia de su valor
|
friend |
Verifica que se cumpla la invariante de la clase, o sea, que el objeto esté bien construido.
check_ok( value_type& )
para cada valor almacenado, aunque si el árbol cumple con su invariante necesariamentes es porque también sus elementos almacenados están bien construidos.Count()
) ==> tiempo Height()
) ==> espacio"true"
si el árbol es un objeto bien construido check_ok(Tree&)
|
friend |
¿¿¿ (p == q) ???
|
friend |
¿¿¿ (p != q) ???