You are on page 1of 0

1

Estructuras de datos
Un arbol es un conjunto de nodos que cumplen
con las relaciones padre, hijo y hermano.
Llamamos hijos de un nodo a todos los nodos que
podemos llegar directamente por medio de un
apuntador hacia ellos y descendencia a todos los
que pudieramos llegar a traves de los hijos y su
propia descendencia.
Llamamos padre al nodo del cual proviene el nodo
hijo. Existe un nodo que no tiene padre y le
llamamos raiz del arbol.
Ing. Jorge A. Hernndez P.: Arboles
Ing. Jorge A. Hernndez P.: Arboles
Estructuras de datos
Llamamos hermanos a todos los nodos que tienen el
mismo padre.
Llamamos hoja al nodo que no tiene hijos.
Podemos definir un rbol de manera recursiva diciendo
que un rbol sin nodos esta vaco. Un arbol es un nodo
llamado raiz cuyos hijos son tambien arboles(vacios o no).
Notemos que una lista es un arbol cuyos nodos solo tienen
un hijo.
Un arbol binario es aquel cuyos nodos pueden tener a lo
ms dos hijos.
Ing. Jorge A. Hernndez P.: Arboles
Ing. Jorge A. Hernndez P.: Arboles
2
Estructuras de datos
Un arbol cuyos nodos tienen 0 o 2 hijos se llama
estrictamente binario. Si algn nodo tiene un solo
hijo ya no lo es.
Llamamos nivel al numero de apuntadores que se
tienen que recorrer para llegar a un nodo a partir la
raiz, asi el nodo raiz esta en el nivel 0 y sus hijos
en el nivel 1.
La profundidad de un rbol es igual al mayor nivel
de sus hojas
Ing. Jorge A. Hernndez P.: Arboles
Ing. Jorge A. Hernndez P.: Arboles
Estructuras de datos
Un rbol estrictamente binario cuyas hojas estan
todas en el mismo nivel se llama arbol binario
completo.
Un arbol estrictamente binario cuyas hojas estan a
lo ms en dos niveles diferentes se llama arbol casi
completo y se dice que el arbol esta balanceado.
Los arboles binarios son muy importantes en las
operaciones de busqueda y para ello deben
mantenerse balanceados.
Ing. Jorge A. Hernndez P.: Arboles
Ing. Jorge A. Hernndez P.: Arboles
3
Estructuras de datos
Ing. Jorge A. Hernndez P.: Arboles
Ing. Jorge A. Hernndez P.: Arboles
raiz
1
2 3
4 5 6 7
El nodo 1 es el nodo raiz. Los
nodos 2 y 3 son el hijo
izquierdo y el hijo derecho del
nodo raiz. Los nodos 4, 5, 6 y 7
son las hojas del arbol.
El padre del nodo 5 es 2 y del nodo 7 es 3. Los nodos 2
y 3 son hermanos. La profundidad del arbol es 2.
Estructuras de datos
El arbol de la lamina anterior tambien es un arbol
estrictamente binario y ademas completo.
Para mayores ejemplos de arboles binarios y su
clasificacin consultar el libro de Tenenbaum en el
captulo de arboles.
Ing. Jorge A. Hernndez P.: Arboles
Ing. Jorge A. Hernndez P.: Arboles
4
Estructuras de datos
Para implementar un arbol binario es necesario crear primero unaclase
Nodo_Arbol capaz de almacenar cualquier dato y que tenga dos
apuntadores a los hijos izquierdo y derecho.
template <class T> class Nodo_Arbol: public Nodo<T>{
public:
Nodo_Arbol(T);
T GetDato(){ return Nodo<T>::GetDato();}
Nodo_Arbol* GetDer(){ return (Nodo_Arbol *)GetSiguiente();}//cast de Nodo * a Nodo_Arbol *
void SetDer(Nodo_Arbol *d){SetSiguiente((Nodo<T> *)d);}//cast de Nodo_Arbol * a Nodo *
Nodo_Arbol* GetIzq(){ return izq;}
void SetIzq(Nodo_Arbol *d){izq = d;}
private:
Nodo_Arbol *izq;
};
template <class T> Nodo_Arbol<T>::Nodo_Arbol(T x): Nodo<T>(x){ //manda a llamar al constructor de Nodo
izq = NULL;
}
Ing. Jorge A. Hernndez P.: Arboles
Ing. Jorge A. Hernndez P.: Arboles
Estructuras de datos
La implementacin de Nodo_Arbol usa herencia y
hereda las caracteristicas de Nodo, es decir usa las
propiedades y la interfaz de la clase Nodo que se
uso para crear Listas. Para tener una nomenclatura
consistente se renombro el apuntador siguiente
para convertirlo en der, y se aadio el apuntador al
nodo izq. Para ello fue necesario hacer
conversiones de tipos o cast. Estas conversiones
deben manejarse con cuidado para evitar
referencias erroneas a la memoria.
Ing. Jorge A. Hernndez P.: Arboles
Ing. Jorge A. Hernndez P.: Arboles
5
Estructuras de datos
La otra opcin es crear la clase Nodo_Arbol desde
cero como se explico en clase. Es decir se crea una
clase que contenga espacio para almacenar un dato
y los apuntadores der e izq hacia nodos del arbol.
La interfaz resultaria muy parecida a la de los
nodos de la clase Lista. Para evitar la conversin
entre objetos de un tipo a otro puede llegar a
preferirse este metodo, sobre todo tomando en
cuenta la simplicidad de la clase Nodo_Arbol.
Ing. Jorge A. Hernndez P.: Arboles
Ing. Jorge A. Hernndez P.: Arboles
Estructuras de datos
Ahora podemos pasar a analizar las operaciones
que se pueden hacer con un rbol.
Inserta(ELEMENTO x, Nodo_Arbol t) inserta el
elemento x en el arbol t. La regla es que todos los
nodos se insertan como hojas, no puede haber
nodos repetidos y todos los descendientes
izquierdos de un nodo son menores a el y los
derechos son mayores a ese mismo nodo. A un
arbol de este tipo le llamamos arbol de busqueda
binaria.
Ing. Jorge A. Hernndez P.: Arboles
Ing. Jorge A. Hernndez P.: Arboles
6
Estructuras de datos
Anula(Nodo_Arbol *t) convierte el arbol t en un
arbol vaco. El proceso de eliminacin comienza
en las hojas.
Recorrer_en_orden(Nodo_Arbol *t) recorre los
nodos del arbol de acuerdo a la siguiente regla
recursiva:
Recorrer_en_orden(SUBARBOL_IZQ);
Raiz;
Recorrer_en_orden(SUBARBOL_DER);
Ing. Jorge A. Hernndez P.: Arboles
Ing. Jorge A. Hernndez P.: Arboles
Estructuras de datos
Recorrer_en_preorden(Nodo_Arbol *t) recorre los nodos
del arbol de acuerdo a la siguiente regla recursiva:
Raiz;
Recorrer_en_preorden(SUBARBOL_IZQ);
Recorrer_en_preorden(SUBARBOL_DER);
Recorrer_en_postorden(Nodo_Arbol *t) recorre los
nodos del arbol de acuerdo a la siguiente regla recursiva:
Recorrer_en_postorden(SUBARBOL_IZQ);
Recorrer_en_postorden(SUBARBOL_DER);
Raiz;
Ing. Jorge A. Hernndez P.: Arboles
Ing. Jorge A. Hernndez P.: Arboles
7
Estructuras de datos
ELEMENTO Get_Dato(Nodo_Arbol *nd) devuelve el
dato almacenado en el nodo nd.
Nodo_Arbol *GetIzq(Nodo_Arbol *nd) devuelve un
apuntador al hijo izquierdo del nodo nd.
Nodo_Arbol *GetDer(Nodo_Arbol *nd) devuelve un
apuntador al hijo derecho del nodo nd.
BOOL SetDer(Nodo_Arbol *nd, ELEMENTO x)
devuelve verdadero si pudo insertar un nuevo nodo
conteniendo a x como hijo derecho del nodo nd.
BOOL SetDer(Nodo_Arbol *nd, ELEMENTO x) igual
que SetDer pero como hijo izquierdo del nodo nd.
Ing. Jorge A. Hernndez P.: Arboles
Ing. Jorge A. Hernndez P.: Arboles
Estructuras de datos
Nodo_Arbol *Padre(Nodo_Arbol *nd) devuelve un
apuntador al padre del nodo nd.
Nodo_Arbol *Hermano(Nodo_Arbol *nd) devuelve un
apuntador al hermano del nodo nd.
BOOL EsIzq(Nodo_Arbol *nd) devuelve verdadero si el
nodo nd es hijo izquierdo.
BOOL EsDer(Nodo_Arbol *nd) devuelve verdadero si el
nodo nd es hijo derecho.
BOOL EsHoja(Nodo_Arbol *nd) devuelve verdadero si el
nodo nd es hoja.
Ing. Jorge A. Hernndez P.: Arboles
Ing. Jorge A. Hernndez P.: Arboles
8
Estructuras de datos
La siguiente secuencia de inserciones generara el arbol de
la siguiente figura. 6, 3, 9, 10, 5, 7, 2.
Ing. Jorge A. Hernndez P.: Arboles
Ing. Jorge A. Hernndez P.: Arboles
raiz
6
3 9
2 5 7 10
aux
Estructuras de datos
El recorrido en orden del mismo seria: 2, 3, 5, 6, 7,
9, 10.
El recorrido en preorden seria: 6, 3, 2, 5, 9, 7, 10.
El recorrido en postorden seria: 2, 5, 3, 7, 10, 9, 6.
Una llamada a Get_Dato(aux) devolveria 3.
Una llamada a Padre(aux) devolveria un apuntador
al nodo raiz.
Una llamada a Hermano(aux) devolveria un
apuntador al nodo que contiene al 9.
Ing. Jorge A. Hernndez P.: Arboles
Ing. Jorge A. Hernndez P.: Arboles
9
Estructuras de datos
Un procedimiento inserta quedaria como sigue:
template<classT>
BOOL Arbol<T>::Inserta2(T x, Nodo_Arbol<T>*ptr){
if(ptr ==NULL){//Arbol vacio
raiz =creanodo(x);
returnVERDADERO;
}
else{//arbol novacio
if(x >ptr->GetDato())//El datoesmayor queel deel nodoactual
if(ptr->GetDer() ==NULL){//hijoderechoestavacio
ptr->SetDer(creanodo(x));
returnVERDADERO;
}
else//el hijoderechonoestavacio
returnInserta2(x, ptr->GetDer());
if(x <ptr->GetDato())//El datoesmenor queel deel nodoactual
if(ptr->GetIzq() ==NULL){//hijoizquierdoestavacio
ptr->SetIzq(creanodo(x));
returnVERDADERO;
}
else//hijoizquierdonoestavacio
returnInserta2(x, ptr->GetIzq());
return FALSO;
}
}
Ing. Jorge A. Hernndez P.: Arboles
Ing. Jorge A. Hernndez P.: Arboles
Estructuras de datos
Un procedimiento Anula quedaria como sigue:
template<classT>
voidArbol<T>::Anula(){
Nodo_Arbol<T> *aux1, *aux2;
while(raiz !=NULL){//mientrasel arbol noestevacio
aux1=raiz;//aux1seriael nodoaeliminar
while(!EsHoja(aux1)){//minetrasaux1noseaunahoja
aux2=aux1;//aux2esel padredeaux1
if (aux1->GetIzq() !=NULL)//buscar hojaizquierda
aux1=aux1->GetIzq();
else77buscar hojaderecha
aux1=aux1->GetDer();
}
if (aux1==raiz){//casoespecial, laraiznotienepadrre
deleteaux1;
raiz =NULL;
break;
}
if(aux2->GetIzq() ==aux1)// esaux1hijoizquierdo?
aux2->SetIzq(NULL);//apuntar hijoizquierdoaNULL
else
aux2->SetDer(NULL);//apuntar hijoderechoaNULL
deleteaux1;//eliminar aux1
}
}
Ing. Jorge A. Hernndez P.: Arboles
Ing. Jorge A. Hernndez P.: Arboles

You might also like