Estructura de Datos
Tema 6. Árboles
Presenta: David Martínez Torres
Universidad Tecnológica de la Mixteca
Instituto de Computación
Oficina No. 37
[email protected]Contenido
1. Definición y operaciones
2. Implementación de árboles binarios
3. Recorrido de árboles binarios
4. Implementación de árboles AVL
5. Árboles n-arios: La estructura TRIE
6. Referencias
1. Definición y operaciones
En estructura de datos, la forma más simple de un árbol, es un
Árbol Binario
Consiste de:
Un nodo (llamado raiz) y Note la
Sub-árboles Izquierdo y Derecho Definición
Ambos sub-árboles son áboles binarios
recursiva
raiz \
nodos
izq 5 der
Sub árbol
izquierdo
\ 3 \ 8 \
\ 4 \ hojas
1. Definición y operaciones
Estructura de dato
typedef struct arbol{
int info; //datos
struct arbol *p; //apuntador al padre
struct arbol *izq; //apuntador al hijo izq.
struct arbol *der; //apuntador al hijo der.
}tipoArbol;
typedef tipoArbol * tipoArbolPtr;
1. Definición y operaciones
Los árboles
binarios no
necesariamente
deben tener sus dos
hijos
1. Definición y operaciones
Árbol estrictamente
binario
•Un nodo que no es
hoja tiene subárboles
que no son vacíos
•Un árbol estrictamente
binario con n hojas
tiene siempre 2n-1
nodos
1. Definición y operaciones
Nivel 0
Profundidad=3
Nivel 1
Nivel de F=2
Altura de A=4
Nivel 2 Grado de C=2
Nivel 3
La profundidad de un árbol binario es el máximo nivel
de cualquier hoja del árbol.
1. Definición y operaciones
Altura: Es el nivel de la hoja en el camino mas largo
desde la raiz mas 1. Por definición, la altura de un
arbol vacío es -1
Grado: Es el número de hijos que tiene en ese
momento el nodo
Nivel de un nodo: es su distancia desde la raiz al
nodo
Orden: Número potencial de hijos que puede tener
cada elemento de un arbol.
1. Definición y operaciones
Estructuras que no son árboles binarios
1. Definición y operaciones
Insertar elementos
Eliminar elementos
Buscar elementos
Recorrer el árbol
Modificar elementos
Mínimo
Máximo
Predecedor
Sucesor
Guardar datos al archivo
Leer datos del archivo
2. Implementación de árboles binarios
x
Sea x un nodo en un árbol de búsqueda
binaria. Si y es un nodo del sub-árbol
izquierdo de x, entonces la clave de y clave
de x. Si z es un nodo del sub-árbol derecho yx
de x, entonces la clave de x clave de z.
xz
•Por ejemplo, dos árboles de búsqueda binaria son:
2
3
5
7
3 7
5 8
2 4 8
•La propiedad del árbol de búsqueda nos permite imprimir o recorrer sus nodos en el orden
de sus claves haciendo uso de un simple algoritmo recursivo.
2. Implementación de árboles binarios
void insertar(tipoArbolPtr *ra, int dato){ if(dato == ant->info)
tipoArbolPtr nuevo, ant, act; printf(“dato ya existe");
else {
nuevo=crearNodo(dato); if(dato<ant->info)
if(!nuevo) ant->izq=nuevo;
printf(“No hay memoria”); else
else { ant->der=nuevo;
if(*ra==NULL) nuevo->p=ant;
*ra=nuevo; }
else { }
ant=*ra; }
act = *ra; }
while (act != NULL && dato!=ant->info){
ant = act;
if ( dato < ant->info)
act = act->izq;
else
act= act->der;
}
Eliminación en un árbol de búsqueda binaria
Casos:
1. Que el elemento sea un nodo hoja.
2. Que el elemento sea un nodo sin hijo izquierdo o
derecho. En este caso, su único sub-árbol sube para
toma el lugar del nodo.
3. Que el elemento posea dos sub-árboles.
La eliminación puede ser por sucesor o predecesor.
Si es por sucesor, el sucesor no posee hijo izquierdo,
luego éste puede ser movido desde su posición a la
del elemento a eliminar, pero el nodo que se liberará
la memoria será el sucesor.
Eliminación en un árbol de búsqueda binaria: CASO
1 Nodo hoja.
15 15
5 16 5 16
3 3
12 20 12 20
z
10 13 18 23 10 18 23
6 6
7 7
Eliminación en un árbol de búsqueda binaria: CASO 2.
Nodo con un solo hijo
15 z 15
20
5 16 5
3 3
12 20 12 18 23
10 13 18 23 10 13
6 6
7 7
Eliminación en un árbol de búsqueda binaria: CASO 3.
Nodo con sus dos hijos (por sucesor)
15 15
z
z
5 16 5 16
3 3
12 20 12 20
10 13 18 23 10 13 18 23
6 6
7 7
15
15
z
5 16
6 16
3
6 12 20 3
12 20
10 13 18 23
10 13 18 23
7
7
Eliminar un elemento en un árbol de búsqueda binaria
Algoritmo:
Verificar que el árbol no esté vacío
Introducir el elemento a eliminar
Buscar el elemento
Si se encontró, imprimir el árbol actual indicando el elemento a
eliminar.
llamar a la función eliminar, pasándole como parámetros el
apuntador de la raíz del árbol por referencia y el apuntador del
elemento encontrado
La función eliminar debe considerar los tres casos de eliminación
Al eliminarlo, liberar la memoria del elemento y mostrar el árbol
sin el elemento.
3. Recorrido de árboles binarios
En orden
En preorden
En postorden
Ejemplo del recorrido en orden del árbol
En orden (recursivo)
Recorrer el árbol izquierdo en
orden 5
Visitar la raíz 3 7
Recorrer el árbol derecho en 2 8
4
orden
void enorden(tipoArbolPtr raiz){
if(raiz!=NULL){
enorden(raiz->izq);
printf("%3d",raiz->num); 234578
enorden(raiz->der);
}
}
Ejemplo del recorrido en preorden del árbol
En preorden
Visitar la raíz
Recorrer el árbol izquierdo en preorden
Recorrer el árbol derecho en preorden
5
3 7
2 4 8 532478
Ejemplo del recorrido en postorden del árbol
En postorden
Recorrer el árbol izquierdo en postorden
Recorrer el árbol derecho en postorden
Visitar la raíz
5
3 7
2 4 8 243875
Modificar algún elemento
Prototipo de función
void modificar(*raiz,dato);
Algoritmo:
1. Buscar el elemento
2. Si se encontró el elemento
Pedir que campo modificar
3. Sino
Informar que no se encontró el elemento
4. Fin
4. Árboles balanceados
Es un árbol binario de búsqueda que tiene como
objetivo realizar reacomodos o balanceos después de
inserciones o eliminaciones de elementos.
AVL
B
2-3
4. Árboles balanceados AVL
Estos árboles fueron nombrados por sus desarrolladores
Adelson-Velskii y Landis
Agrega la propiedad de altura para balancear el árbol en caso
necesario.
typedef struct arbolAvl{
int info;
int fe; //factor de equilibrio
struct arbolAvl *izq; //apuntador al hijo izq.
struct arbolAvl *der; //apuntador al hijo der.
}tipoArbolAvl;
typedef tipoArbolAvl * tipoArbolAvlPtr;
4. Árboles balanceados AVL
Propiedad:
Que la altura de los subárboles de cada nodo difiere en
no más de 1. Esto es, la altura B=hd-hi: -1<=B<=1
Para mantenerlo balanceado es necesario saber la
altura o la diferencia en alturas de todos los
subárboles.
Se necesita un campo “FE”(Factor de Equilibrio) en
cada nodo, como un contador de la diferencia entre
las alturas de sus subárboles.
Principal característica: excelente tiempo de ejecución
para las operaciones de (búsqueda, altas y bajas)
Ejemplo, árbol balanceado AVL
Inserción en AVL
La inserción se hace siguiendo el camino de búsqueda
Puede aumentar la altura de una rama, por lo cual cambiará el factor de
equilibrio de dicho nodo.
Implica que se retornará por el camino de búsqueda para actualizar el
FE de cada nodo
Se puede llegar a desbalancear por tanto rebalancear.
O puede mejorar. Si el arbol A se le inserta el 2, resultará en
perfectamente balanceado. Pero si se le inserta el 5 se desbalancea
El proceso termina cuando se llega a la raíz o cuando termina el re-
balanceo del mismo
10 10
0 -1
4 17 4 17
0 2 0
1
6 15 20
6 15 20 -1 0 0
0 0 0 5 Árbol A + Nodo 5
Árbol A
Reestructuración AVL
Hay 4 casos posibles a tener en cuenta, según donde se hizo la Inserción.
10
1. Inserción en el 2. Inserción en el 10
Subárbol IZQ De la Subárbol DER De la
Rama IZQ de 10 Rama DER de 10
10 10
3. Inserción en el 4. Inserción en el
Subárbol DER De la Subárbol DER De la
Rama IZQ de 10 Rama IZQ de 10
Solución: La ROTACION le devuelve el equilibrio al árbol.
Rotación Simple: Caso 1 y 2: Implica a 10 y su descendiente
Rotación Doble: Caso 3 y 4: Implica a los 3 nodos
Soluciones simétricas: En c/caso, las ramas están opuestas.
AVL: Rotación Simple
AVL: Rotación Simple
Luego de Insertar el Nodo 2 el árbol quedó n
desbalanceado. -2
Según que rama ha crecido, la Rotación Simple n1 10
puede ser por la izquierda(II) o por la 4
derecha(DD). 2
-1
Movimientos de apuntadores (ptr’s). 0
n es ptr al nodo problema.
II (nuestro ej). n1 apunta a rama IZQ
n1 n
n->izq=n1–>der
0
n1->der=n 4
0
n=n1 2
DD. n1 apunta a rama DER 10
0
n->der=n1–>izq
n1->izq=n
n=n1
AVL: Rotación Doble
AVL: Rotación Doble
Movimientos de apuntadores (ptr’s).
n apunta al nodo problema; n1 al hijo de n con
problemas, n2 al hijo de n1 n
DI(nuestro ej). Derecha–izquierda
2
30
n1->izq=n2–>der 60
n1
n2–>der=n1 -1
n->der=n2–>izq n2 40
0
n2–>izq=n
n=n2 La solución consiste
en subir el 40, pender
ID: izquierda–derecha el 30 a su izquierda y
n1->der=n2–>izq el 60 a su derecha.
n2–>izq=n1 n2 n1
n->izq=n2–>der
n2–>der=n 40
n=n2
30 60
n
Ejemplos de rotaciones simples de nodos
n->izq=n1–>der
Rotación simple a
n1->der=n
la Izquierda (II)
n=n1
Ra iz Raiz Ra iz
n n n1 n
5 -3 3
n1 -2 n1 -2
5
3 10
3 -1 10
-1
1 5
1 4
1 4
2
2 4 10
2
a) b) c)
Ejemplos de rotaciones simples de nodos
Rotación simple a la derecha (DD)
n->der=n1–>izq Raiz
n1->izq=n n1 n
n=n1 10
5 12
3 9 15
b)
Ejemplos de rotaciones dobles de nodos
Rotación izquierda derecha(ID) n1->der=n2–>izq
n2–>izq=n1
n->izq=n2–>der
n2–>der=n
n=n2
Raiz
n2 n
n1 7
5 9
1 6 8 10
b)
Ejemplos de rotaciones dobles de nodos
Rotación derecha izquierda (DI) n1->izq=n2–>der
n2–>der=n1
n->der=n2–>izq
n2–>izq=n
n=n2
Raiz
n2 n
7 n1
5 10
3 6 8 12
b)
Ejemplo: Crear el arbol AVL a partir de la inserción de
las siguientes claves.
65, 50, 23, 70, 82, 68 y 39
Eliminación en AVL
La operación de eliminación en árboles balanceados
consiste en quitar un nodo del árbol sin violar los
principios que definen a un árbol balanceado.
Se distinguen los mismos casos que en árboles
binarios:
CASO 1. Si el elemento a borrar es hoja, simplemente
se suprime.
CASO 2. Si el elemento a borrar tiene sólo un hijo,
entonces tiene que sustituirse por él.
CASO 3. Si el elemento a borrar tiene los dos hijos,
entonces tiene que sustituirse por su sucesor o
predecesor, dependiendo de la opción que se elija.
… Eliminación en AVL
Para eliminar un nodo en un árbol balanceado lo
primero que debe hacerse es localizar su posición en
el árbol. Se elimina siguiendo los criterios
establecidos anteriormente y se regresa por el camino
de búsqueda, actualizando el FE de los nodos
visitados. Si en alguno de los nodos se viola el criterio
de equilibrio, entonces debe reestructurarse el árbol.
El proceso termina cuando se llega hasta la raíz del
árbol.
… Eliminación en AVL
Ejemplo. Dado el siguiente árbol AVL, eliminar las
siguientes claves: 40, 5, 20, 30 y 75. Realice
primero por sucesor y después por antecesor.
5. Árboles n-arios: La estructura TRIE
Un trie es una estructura de árbol en la que:
Cada nodo (excepto la raíz) está etiquetado con un
caracter (a, ..., z) o una marca de fin (símbolo $).
Un camino de la raíz a una hoja (etiquetada con $)
corresponde a una palabra del diccionario.
Cada nodo (excepto la raíz y las hojas) es un
prefijo del conjunto.
5. Árboles n-arios: La estructura TRIE
Representación de diccionarios de palabras. Muchas
palabras implica mucha memoria y operaciones lentas
Muchas palabras tienen prefijos comunes. P. ej.:
operador, operando; encontrado, -a, -os, -as...
Implementaciones de Tries:
Nodo-vector. cada nodo es un vector de apuntadores
para acceder a los subárboles directamente.
Nodo-lista. cada nodo es una lista enlazada por
apuntadores que contiene las raíces de los subárboles.
5. Árboles n-arios: La estructura TRIE
Ejemplo de
representación
de un árbol
TRIE, con las
siguientes
palabras:
cris, cruz, javi,
juan, rafa,
raquel
5. Árboles n-arios: La estructura TRIE
Nodo-vector [4]
5. Árboles n-arios: La estructura TRIE
Nodo-lista
5. Árboles n-arios: La estructura TRIE
Aplicaciones de los árboles TRIE
Diccionarios
Soporta operaciones de búsqueda de palabras
Comparaciones de subcadenas -> procesamiento de
textos, biología computacional, etc.
Referencias
1. Tenenbaum, Aaron & Langsam, Yedidyah &
Augenstein, Moshe “Estructuras de Datos en C”.
Prentice-Hall, México 1997.
2. Deitel & Deitel “Como programar en C/C++”.
Prentice-Hall, México
3. Wirth, Niklaus “Algoritmos y estructura de Datos”.
Prentice-Hall, México.
4. Javier Campos . Técnicas Avanzadas de
Programación