Estructura de Datos Árboles Árboles Binarios Temario Unidad VI 6.1 Definición y operaciones 6.2 Implementación 6.3 Recorrido en Árboles Binarios 6.4 Árboles AVL y su implementación 6.5 Árboles n-arios 6.6 Árboles B 1
Árboles El tipo de estructura más general son los grafos. En un grafo cada elemento puede tener varios elementos anteriores y varios elementos posteriores. Los árboles son un tipo especial de grafo en que cada elemento puede tener varios posteriores pero sólo puede tener un elemento anterior. Tanto los grafos como los árboles son estructuras no lineales. Grafos Árboles Listas Estructuras lineales Pilas Colas Definición Los árboles son una de las estructuras de datos no lineales que sirve para representar estructuras de información jerárquicas y direcciones o etiquetas de una manera organizada. Ejemplos comunes de árboles: La organización de una empresa (organigrama). Árbol genealógico de una persona. Organización de torneos deportivos (tabla de partidos). 2
Aplicaciones En general se usan los árboles asociados a distintos esquemas para el desarrollo de los algoritmos, tales como la programación dinámica, el esquema divide y vencerás. Ejemplos de aplicaciones computacionales: Realizar ordenaciones de datos. Realizar búsquedas. En un disco duro se utiliza una estructura de directorios y subdirectorios en forma de árbol. Asignar bloques de memoria de tamaño variable. Organizar tablas de símbolos en compiladores. Representar tablas de decisión. Solucionar juegos. Probar teoremas. Definición de árbol Un árbol es un conjunto finito T de uno o más nodos tal que: Existe un nodo especial llamado la raíz de árbol. Los nodos restantes están particionados en m > 0 conjuntos disjuntos T1,...,Tm y cada uno de estos conjuntos es a su vez un árbol. Los árboles T1,...,Tm son llamados subárboles de la raíz. Cualquier nodo es la raíz de un subárbol que consiste de él y los nodos debajo de él. Por ello se dice que la definición de árbol es recursiva. Puede estar ordenado o no. 3
Representación de un árbol La forma general de representar un árbol es con grafos usando apuntadores pero también existe otra usada que es con vectores. Terminología Dado un conjunto de E elementos: Un árbol puede estar vacío. Un árbol no vacío puede constar de un solo elemento llamado nodo raíz. Un árbol consta de un nodo raíz e E, conectado por arcos directos a un número finito de otros árboles. Un vértice o nodo del árbol puede tener un nombre y puede tener asociada a él una información. 4
Terminología Raíz. Es el primer nodo de un árbol(único nodo sin padre). Arcos o Ramas. Son las flechas que conectan un nodo a otro. Hoja. Son los nodos terminales son aquellos que no conducen a algún nodo, no tienen hijos. Internos. Son los nodos que no son hojas se llaman también nodos no terminales, tienen al menos un hijo. Terminología Hijo. Si un nodo n1 tiene una rama hacia el nodo n2, se dice que n2 es un nodo hijo de n1. También llamado descendiente directo. Camino. Es una lista de ramas contiguas que van de n1 a n2. Una propiedad que define a los árboles es que existe exactamente un camino entre la raíz y cada uno de los otros nodos en el árbol. 5
Terminología Longitud de un camino. Es el número de nodos del camino menos uno o de forma equivalente es el número de arcos que contiene el camino. Por tanto, hay un camino de longitud cero de cualquier nodo a si mismo. Grado de un nodo. Es el número de hijos que parten de un nodo. El grado de un árbol es el grado máximo de los nodos del árbol. Terminología Orden. Es el número potencial de hijos que puede tener cada elemento de árbol. Nivel de un nodo. Es la longitud del camino que lo conecta al nodo raíz. Profundidad del nodo n k. Es el largo del camino entre la raíz del árbol y el nodo n k. La profundidad de la raíz es siempre 0. 6
Terminología Altura de un nodo n k. Es el máximo largo de camino desde n k hasta alguna hoja. Esto significa que la altura de toda hoja es 0. La altura de un árbol es igual a la altura de la raíz y tiene el mismo valor que la profundidad de la hoja más profunda. La altura de un árbol vacío es -1. Terminología Subárbol. Es un subconjunto de nodos del árbol conectados por ramas del propio árbol, éste es, a su vez un árbol. Bosque. Es un conjunto de árboles Si se elimina la raíz de un árbol se obtiene un bosque, y si se añade un nodo a un bosque se obtiene un árbol. 7
Árbol ordenado Es aquel a partir del cual se puede obtener una secuencia ordenada siguiendo uno de los recorridos posibles del árbol: inorden, preorden o postorden. Existen varios tipos de árboles ordenados: Árboles binarios de búsqueda (ABB). Árboles-B, árboles 2-3-4 Árboles AVL. Árboles Rojo-Negro. Árbol Binario Es un árbol de grado 2. Cada nodo puede tener como máximo dos hijos (0 a 2 descendientes directos), es decir, cada nodo sólo puede tener dos subárboles. 8
Aplicaciones de AB Generalmente en expresiones aritméticas, árboles de decisión y búsqueda (ABB). Ejemplo de un árbol de decisión: Un nodo interno representa preguntas con respuesta (si/no). Los nodos hoja representa las decisiones. Pregunta: Dónde ir a cenar? Ejemplo Árbol de Decisión Cómida rápida? Sí Con café? No Cara? Sí No Sí No Italian coffe McDonalds MMMM VIPS 9
Ejemplo de A. Binario A B C D E F G Operaciones básicas en AB Creación del árbol Creación de nodo Inserción Eliminación Búsqueda Recorridos 10
Implementación Definición de un AB Considerando la siguiente definición de tipo: typedef struct nodo{ Árbol tipo_dato dato; struct nodo *izq; struct nodo *der; } NodoArbol; // estructura que define el nodo NodoArbol *Arbol; Implementación Creación de un nodo NodoArbol * crearnodo(tipo_dato e) { } NodoArbol *nodo; nodo=(nodoarbol *)malloc (sizeof(nodoarbol)); nodo->dato = e; nodo->der=null; nodo->izq=null; return nodo; 11
Recorridos en un AB Se denomina recorrido de un árbol al proceso que permite acceder una sola vez a cada uno de los nodos del árbol. Inorden. Cada nodo se visita después de viistar su subárbol izquierdo y antes de visitar el derecho (Izq, Raiz, Der). Preorden. Cada nodo se visita cada nodo, luego su subárbol izquierdo y finalmente el derecho (Raiz, Izq, Der). Postorden. Cada nodo se visita después de visitar su subárbol izquierdo y después de visitar el derecho (Izq, Der, Raiz). Recorridos en un AB Ejemplo: A B C D E F G Preorden: A, B, D, E, C, F, G Inorden: D, B, E, A, F, C, G Postorden: D, E, B, F, G, C, A 12
Implementación recursiva Inserción ABB void insertar(nodoarbol *r, tipo_dato e) { nodoarbol *nodo; If ( r==null) r= crearnodo(nodo); else if (e > r->dato) //Si el dato a insertar es mayor insertar(aux->der,e) //Se revisa el lado derecho else if (e < r->dato) insertar(r->izq,e); } Implementación Recorridos en un AB void inorden (NodoArbol * r) { if ( r!= NULL) { inorden(r->izq); printf( %i, r- >dato); inorden(r->der); } } void postorden (NodoArbol *r) { if ( r!= NULL) { postorden(r->izq); postorden(r->der); printf ( %i,r- >dato); } } // la impresión puede sustituirse por una // función llamada visita que.. 13
Árbol Binario de Búsqueda En este tipo de árbol los nodos están ordenados de manera conveniente para la búsqueda. Todas las datos del subárbol izquierdo son menores que el dato del nodo raíz, y todas los datos del subárbol derecho son mayores. Ejemplos de ABB M D R 38 A K P W 25 65 13 30 47 94 5 21 50 14
Búsqueda en un ABB int buscar(nodoarbol *r, tipo_dato elem) { if (r == NULL) return 0; else if (r->dato == elem) return 1; else if ( r->dato < elem) return buscar(r->izq, elem); else return buscar(r->der, elem); } Eliminación en ABB Existen cuatro casos o escenarios: 1. Intentar eliminar un nodo que no existe. No se hace nada, se retorna 0. 2. Eliminar un nodo hoja. Se borra el nodo y se actualiza el apuntador del nodo padre a NULL. 3. Eliminar un nodo con un solo hijo. El nodo padre del nodo a borrar se convierte en el padre del único nodo hijo. 15
Eliminación en ABB 4. Eliminar un nodo con dos hijos. En este caso hay dos opciones de eliminación: a) Reemplazar el dato del nodo por la menor de las claves mayores en su subárbol derecho. b) Reemplazar el dato del nodo por la mayor de las claves menores en su subárbol izquierdo. En esta opción, como las claves menores están en la rama izquierda, se baja al primer nodo de la rama izquierda y como la clave mayor está en la rama derecha, se continúa bajando por la rama derecha hasta alcanzar el nodo hoja. Este es el mayor de los menores que reemplaza a la clave del nodo a eliminar. Implementación Eliminación ABB void eliminar (nodoarbol *r, int elem) { nodoarbol *aux1, * aux2; aux1 =raiz; while (!hoja(aux1)) { aux2=aux1; if (aux1 -> izq!=null ) aux1=aux1 -> izq; else aux1=aux1 -> der; } if (aux==r ) { free(aux1); raiz=null; } if (aux2 -> izq== aux1) aux2 -> izq= NULL; else aux2 -> der= NULL; free(aux1); } } 16
Árbol de expresión Un árbol de expresiones es un árbol binario completo, en el cual los nodos interiores son operadores y las hojas son operandos (variables o constantes). Es fácil de representar en un AB ya que los operadores matemáticos son binarios (o unarios como en el caso del operador signo - ). Árbol de expresión 2 3 b a 1 17
Árbol de expresión Se puede evaluar de la siguiente manera: Si la raíz del árbol es una constante o una variable se retorna el valor de ésta. Si la raíz resulta ser un operador, entonces recursivamente se evalúan los subárboles izquierdo y derecho, y se retorna el valor que resulta al operar los valores obtenidos de las evaluaciones de los subárboles con el operador respectivo (+, -, * ó / ). Árbol de expresión Algoritmo de construcción de un AB de Expresión Mientras carácter diferente de nulo. Leer carácter de la lista. Si es paréntesis pasar al siguiente carácter. Crear un nodo nuevo que contenga ese carácter. 18
Algoritmo de construcción Si el carácter que tiene nuevo es un: Operando si el árbol esta vacío hacer raíz a nuevo si no recorrer el árbol por la derecha hasta llegar a un nodo con hojas si la hoja izquierda, no esta etiquetada colocar operando. si no colocarlo en la hoja derecha. Algoritmo de construcción Si el carácter que tiene nuevo es un: Operador si la raíz es un operando insertar nuevo en ese nodo, y convertir el operando en el hijo izq. si no si hay un paréntesis abierto insertar nuevo en la ultima hoja derecha y colocar operando como hijo izquierdo 19
Algoritmo de construcción si el carácter anterior es paréntesis izquierdo. si el siguiente carácter es paréntesis derecho si no si solo hay un operador en el árbol nuevo se convierte en raíz se inserta en el ultimo nodo derecho, y el nodo se convierte en hijo izquierdo. Algoritmo de construcción Si no se cumple ninguna de las condiciones anteriores si la raíz es de igual prioridad o menor prioridad sino convertir la raíz en el hijo izquierdo de nuevo si la prioridad del nodo raíz es mayor al de nuevo insertar nuevo como hijo derecho y colocar el nodo reemplazado como hijo izquierdo. 20
Tipos de Árboles Binarios AB Similares. Tienen la misma estructura. A F B C B M D E A E Tipos de Árboles Binarios A. Equivalentes. Tienen la misma estructura y además la misma información. F F B M B M A E A E 21
Tipos de Árboles Binarios A. Equilibrado. Cuando las alturas de los dos subárboles de cada nodo del árbol se diferencian en una unidad como máximo. M D R A K P W L Tipos de Árboles Binarios A. Completo. Un AB completo (ABC) de profundidad N es un árbol en el que para cada nivel, del 0 al nivel N-1tiene un conjunto lleno de nodos y todos los nodos hoja a nivel N ocupan las posiciones más a la izquierda del árbol. M D R A K P 22
Tipos de Árboles Binarios Árbol lleno. Es un árbol completo que contiene en su último nivel el número máximo de nodos. M D R A K P W Tipos de Árboles Binarios A. Degenerado. Si todos sus nodos excepto el último tienen sólo un subárbol. 10 8 7 7 9 6 8 5 23
Árboles desbalanceados Algunas veces los ABB no facilitan la búsqueda de elementos, sobretodo cuando quedan formados como se ve en la imagen. 1-3 8 7 El problema es que está muy desbalanceado. La solución es balancearlo, y con ello asegurar que asegurar que tiempo promedio de búsqueda sea menor. 4 5 6 24