La descarga está en progreso. Por favor, espere

La descarga está en progreso. Por favor, espere

Arboles M.C. José Andrés Vázquez FCC/BUAP

Presentaciones similares


Presentación del tema: "Arboles M.C. José Andrés Vázquez FCC/BUAP"— Transcripción de la presentación:

1 Arboles M.C. José Andrés Vázquez FCC/BUAP
El tipo de dato Arbol Aparecen estructuras de tipo árbol en: Sist. Op: Sistema de ficheros (Arbol de directorios) Compiladores, proc. textos, algoritmos de búsqueda Elementos: Nodos Conexiones (dirigidas) entre pares de nodos Un nodo particular: Raíz Cada nodo (excepto raíz) está conectado al menos con otro (padre). Relación padre-hijo. Tomado del libro "Thinking in Java" Explicar qué es el "modelado". Ejemplo Arboles M.C. José Andrés Vázquez FCC/BUAP

2 Arboles M.C. José Andrés Vázquez FCC/BUAP
Arboles. Conceptos Un único camino conduce de la raíz a cada nodo Longitud del camino: Número de conexiones a atravesar Nodos sin hijos: Hojas (leaves) Arbol con N nodos ó N-1 conexiones entre nodos Profundidad de un nodo: Longitud del camino raíz ð nodo Altura de un nodo: Longitud del camino desde el nodo a su hoja más profunda Hermanos: Nodos con el mismo padre (siblings) Arboles M.C. José Andrés Vázquez FCC/BUAP

3 Arboles. Conceptos (II)
Relación antepasado (u) / descendiente (v): Si hay camino de u a v. Tamaño de un nodo: Número de descendientes (incluyendo al nodo) Arbol (def. recursiva): o es vacío, o consiste en una raíz y cero o más (sub)árboles no vacíos A1..Ak conectados a la raíz Arboles M.C. José Andrés Vázquez FCC/BUAP

4 Arboles. Implementación
1.- Cada nodo contiene: Referencias a todos sus hijos Datos almacenados en el nodo Problema: Número de hijos desconocido 2.- Cada nodo: Lista con sus hijos Referencia a los datos contenidos Referencia a su nodo hermano Representación "first child / next sibling" Arboles M.C. José Andrés Vázquez FCC/BUAP

5 Arboles. Implementación (II)
nodoRaiz sigHermano null primerHijo null null null null null null null null null Arboles M.C. José Andrés Vázquez FCC/BUAP

6 Arboles M.C. José Andrés Vázquez FCC/BUAP
Arbol N-ario Ningún nodo puede tener más de N hijos El más utilizado: Binario, 2 hijos (left, right) Def. recursiva (Arbol binario) ... o es vacío ... o tiene raíz, árbol derecho, árbol izquierdo Implementación: Conocido el número de hijos. 2 referencias Arboles M.C. José Andrés Vázquez FCC/BUAP

7 Arboles M.C. José Andrés Vázquez FCC/BUAP
Arboles binarios Arbol binario completo (complete binary tree) Todas las hojas tiene la misma profundidad El resto de nodos (no terminales) tienen 2 hijos Arbol binario cuasi-completo (cusi-complete binary tree) Cada nivel (excepto el más profundo) debe contener todos sus posibles nodos En el nivel más profundo, los nodos están lo más a la izquierda que sea posible Arbol binario completo: El que resulta de añadir nodos a un arbol binario lleno. Añadir de izquierda a derecha, sin pasar al nivel siguiente antes de completar el actual Arboles M.C. José Andrés Vázquez FCC/BUAP

8 Arboles binarios: Expresiones
Un nodo terminal representa un operando El resto de los nodos representan operadores (binarios) Evaluación de la expresión: Evaluación de los subárboles (recursivamente) Aplicación del operador a los valores obtenidos 6 + ((7 - 3) * 5) + 6 * - 5 7 3 Arboles M.C. José Andrés Vázquez FCC/BUAP

9 Arboles y recursividad
El tipo árbol se define recursivamente Muchas rutinas para manejo de árboles se implementan fácilmente de forma recursiva public class NodoBinario { Object dato; NodoBinario left; NodoBinario right; public NodoBinario (Object elemento) dato = elemento; left = null; right = null; } // Métodos... dato left right Arboles M.C. José Andrés Vázquez FCC/BUAP

10 Arboles y recursividad (II)
public NodoBinario duplicar() { NodoBinario root = new NodoBinario(dato); if (left != null) root.left = left.duplicar(); if (right != null) root.right = right.duplicar(); return root; } public static int size (NodoBinario nodo) // Tamaño del árbol que tiene a ese nodo como raíz if (nodo == null) return 0; else return 1 + size(nodo.left) + size (nodo.right); size = 1 size left size right Arboles M.C. José Andrés Vázquez FCC/BUAP

11 Arboles y recursividad (III)
public static int altura(NodoBinario nodo) // Un árbol con un único nodo tiene altura = 0 // El nodo tiene que ser != null. Si no, no está definida su altura { int altDerecha = (nodo.right == null ? 0 : 1+altura(nodo.right)); int altIzquierda = (nodo.left == null ? 0 : 1+altura(nodo.left)); return Math.max (altDerecha, altIzquierda); } // Otra forma de hacer lo mismo... if (nodo == null) return -1; else return 1 + Math.max(altura(nodo.left), altura(nodo.right)); altura = 0 altura Izquierda altura Derecha Arboles M.C. José Andrés Vázquez FCC/BUAP

12 Arboles M.C. José Andrés Vázquez FCC/BUAP
Recorrido de árboles Recorrido: Acceso a todos los nodos de un árbol Ej: Para realizar una operación en cada nodo Fácil implementación mediante recursividad Tipos de recorrido: Según el orden en que se "visitan" los nodos duplicar(): Recorrido preorder size(), altura(): Recorridos postorder Obtención de expresiones algebraicas: inorder Arboles M.C. José Andrés Vázquez FCC/BUAP

13 Arboles M.C. José Andrés Vázquez FCC/BUAP
Recorrido "Preorden" Recorrido preorder: 1.- Nodo raíz 2.- Subárbol left en preorden 3.- Subárbol right en preorden Preorden 1 // en la clase NodoBinario... public void mostrarPreorden() { System.out.println(dato); if (left != null) left.mostrarPreorden(); if (right != null) right.mostrarPreorden(); } 2 3 4 6 5 7 Arboles M.C. José Andrés Vázquez FCC/BUAP

14 Arboles M.C. José Andrés Vázquez FCC/BUAP
Recorrido "Inorden" Recorrido inorder: 1.- Subárbol left en inorden 2.- Nodo raíz 3.- Subárbol right en inorden Inorden 2 // ...NodoBinario... public void mostrarInorden() { if (left != null) left.mostrarInorden(); System.out.println(dato); if (right != null) right.mostrarInorden(); } 1 5 3 7 4 6 Arboles M.C. José Andrés Vázquez FCC/BUAP

15 Arboles M.C. José Andrés Vázquez FCC/BUAP
Recorrido "Postorden" Recorrido postorder: 1.- Subárbol left en postorden 2.- Subárbol right en postorden 3.- Nodo raíz Postorden 7 // ...NodoBinario... public void mostrarPostorden() { if (left != null) left.mostrarPostorden(); if (right != null) right.mostrarPostorden(); System.out.println(dato); } 1 6 3 5 2 4 Arboles M.C. José Andrés Vázquez FCC/BUAP

16 Recorrido de árboles. Ejercicio
A B C D F G E H I J K PRE: ABDEHICFJKLMG IN: DBHEIAJFLKMCG POST: DHIEBJLMKFGCA Preorden: ... Inorden: ... Postorden: ... L M Arboles M.C. José Andrés Vázquez FCC/BUAP

17 Arboles M.C. José Andrés Vázquez FCC/BUAP
Recorrido por niveles Se recorren los nodos por niveles de profundidad Dentro de cada nivel, de izquierda a derecha Recorrido en anchura (breadth-first) Implementación: Utilizando una Cola Almaceno en la cola los nodos que deben ser visitados Al visitar un nodo, sus hijos se colocan en la cola La cola puede llegar a contener muchos nodos ¿Qué sucede usando Pila en lugar de Cola? ¿recorrido en preorden? ¿Algún cambio? Arboles M.C. José Andrés Vázquez FCC/BUAP

18 Recorrido por niveles (II)
// ...NodoBinario... public static void mostrarPorNiveles(NodoBinario n) { Cola q = new Cola(); q.ponerElemento(n); while(!q.estaVacia()) NodoBinario elemento = (NodoBinario) q.extraerElemento(); System.out.println(elemento.dato); if (elemento.left != null) q.ponerElemento(elemento.left); if (elemento.right != null) q.ponerElemento(elemento.right); } Arboles M.C. José Andrés Vázquez FCC/BUAP

19 Arboles binarios de búsqueda
Arboles binarios + Almacenan datos con clave Clave: Relación de orden total (...¿duplicados?) Características: La raíz tiene un valor de clave mayor que la de cualquier elemento del subárbol de la izquierda La raíz tiene una clave menor que cualquiera del subárbol de la derecha Ambos subárboles (izquierda y derecha) son igualmente Arboles Binarios de Búsqueda Arboles M.C. José Andrés Vázquez FCC/BUAP

20 Arboles binarios de búsqueda (II)
6 2 12 1 8 13 4 3 5 7 10 9 11 Un recorrido inorder muestra los datos ordenados ¿Cuál es el coste de una búsqueda? (Ej. 9) Arboles M.C. José Andrés Vázquez FCC/BUAP

21 Arboles binarios de búsqueda (III)
Operaciones de búsqueda: Como búsqueda dicotómica en vectores ordenados Eficiencia en las operaciones: Estructuras lineales ð coste de operaciones: O(N) La mayor parte de las operaciones son O(log N) Algunas se comportan como O(N) en el peor caso Permite las operaciones habituales: Inserción, búsqueda y borrado Arboles M.C. José Andrés Vázquez FCC/BUAP

22 Arboles M.C. José Andrés Vázquez FCC/BUAP
Búsqueda en ABB public class ArbolBinarioBusq { protected NodoBinarioBusq raiz; public Object buscar(int claveBuscar){ return buscar(claveBuscar, raiz);} private static Object buscar(int claveBuscar, NodoBinario n) // Devuelve: dato contenido en el nodo con esa clave, o null NodoBinarioBusq nodo = (NodoBinarioBusq) n; if (nodo == null) return null; if (nodo.clave > claveBuscar) return buscar(claveBuscar, nodo.left); if (nodo.clave < claveBuscar) return buscar(claveBuscar, nodo.right); // Solo queda el caso (nodo.clave == claveBuscar) return nodo.dato; }... } NodoBinarioBusq clave NodoBinarioBusq desciende de NodoBinario Comentario sobre la conversión para acceder al atributo "clave" Otras posibilidades de conversión (al invocar recursivamente) Ejercicio: Tratar de hacer la búsqueda iterativa dato left right Arboles M.C. José Andrés Vázquez FCC/BUAP

23 Arboles M.C. José Andrés Vázquez FCC/BUAP
Búsqueda en ABB (II) // Dato almacenado con la clave menor. Recursivo. public Object buscarMin(){return buscarMin(raiz);} private static Object buscarMin(NodoBinario nodo) { if (nodo == null) return null; if (nodo.left == null) return nodo.dato; return buscarMin(nodo.left); } // Dato almacenado con la clave mayor. Iterativo. public Object buscarMax() NodoBinario nodo = raiz; if (nodo != null) while (nodo.right != null) nodo = nodo.right; return nodo.dato; else return null; raiz 2 Tratar de hacer cada uno de los métodos de la otra forma (recursivo/iterativo) 1 4 3 5 Arboles M.C. José Andrés Vázquez FCC/BUAP

24 Arboles M.C. José Andrés Vázquez FCC/BUAP
Inserción en ABB Algoritmo recursivo muy simple: Si el árbol está vacío, colocar como nuevo elemento Si no está vacío: comparar con la clave de la raíz Insertar (recursividad) en el subárbol izquierdo o derecho Si ya hay un nodo con ese valor: ¡Error! Ejercicio: insertar(Object dato, int clave) ¡Cuidado con las modificaciones en los nodos! Arboles M.C. José Andrés Vázquez FCC/BUAP

25 Arboles M.C. José Andrés Vázquez FCC/BUAP
Inserción en ABB (II) 6 2 8 public void insertar(Object dato, int clave){ raiz = insertar(dato, clave, raiz);} private static NodoBinarioBusq insertar(Object dato, int clave, NodoBinarioBusq nodo) // Devuelve el estado en que queda el nodo tras insertar { if (nodo == null) nodo = new NodoBinarioBusq(dato, clave); else if (clave < nodo.clave) nodo.left = insertar(dato, clave, (NodoBinarioBusq) nodo.left); else if (clave > nodo.clave) nodo.right = insertar(dato, clave, (NodoBinarioBusq) nodo.right); else System.out.println("Duplicado. Error al insertar!"); return nodo; } 1 4 3 insertar (..., 5) 6 2 8 1 4 ¿Es necesario devolver un "nodo"? Modificar para tratamiento de claves duplicadas 3 5 Arboles M.C. José Andrés Vázquez FCC/BUAP

26 Arboles M.C. José Andrés Vázquez FCC/BUAP
Borrado en ABB La operación más compleja. Puede afectar otros nodos Posibilidades según los hijos del nodo a borrar: Borrado de un nodo sin hijos Se pone a null la referencia de su padre. Nodo con un único hijo El subárbol hijo se cuelga del padre del nodo a borrar Nodo con 2 hijos Las modificaciones afectan a otros nodos. No trivial Arboles M.C. José Andrés Vázquez FCC/BUAP

27 Arboles M.C. José Andrés Vázquez FCC/BUAP
Borrado en ABB (II) 6 6 6 2 8 2 8 2 8 1 4 1 4 1 4 3 3 3 borrar(4) ð Su único subárbol hijo ocupa su posición borrar(8) ð ok borrar(2) ð ¿Cómo? Veamos un caso más sencillo: Borrado del dato con clave mínima Arboles M.C. José Andrés Vázquez FCC/BUAP

28 Arboles M.C. José Andrés Vázquez FCC/BUAP
Borrado en ABB (III) Borrado del dato con clave mínima: Posición conocida (extremo izquierdo) No tiene más de 1 hijo borrarMin() 6 2 8 1 4 // ... en la clase ArbolBinarioBusq public void borrarMin(){ raiz = (NodoBinarioBusq) borrarMin(raiz); } private static NodoBinario borrarMin(NodoBinario nodo) { if (nodo == null) System.out.println("Arbol vacio. Error al borrar"); else if (nodo.left != null) nodo.left = borrarMin(nodo.left); else nodo = nodo.right; return nodo; 3 borrarMin() 6 3 8 1 4 2 Arboles M.C. José Andrés Vázquez FCC/BUAP

29 Arboles M.C. José Andrés Vázquez FCC/BUAP
Borrado en ABB (IV) Caso general de borrado: Como borrarMin(), salvo nodos con 2 hijos La posición del nodo borrado la deberá ocupar El nodo mayor del subárbol izquierdo o el nodo menor del subárbol derecho Operaciones de buscar y eliminar el nodo de menor (o mayor) clave ya conocidas Arboles M.C. José Andrés Vázquez FCC/BUAP

30 Arboles M.C. José Andrés Vázquez FCC/BUAP
Borrado en ABB (V) public void borrar(int claveBorrar){ raiz = (NodoBinarioBusq) borrar(claveBorrar, raiz);} private static NodoBinario borrar(int claveBorrar, NodoBinario nodo) { if (nodo == null) System.out.println("Arbol vacio. Error al borrar"); else if (claveBorrar < getClave(nodo)) nodo.left = borrar(claveBorrar, nodo.left); else if (claveBorrar > getClave(nodo)) nodo.right = borrar(claveBorrar, nodo.right); else if ((nodo.left != null) && (nodo.right != null)) nodo.clave = claveMin(nodo.right); nodo.dato = buscarMin(nodo.right); nodo.right = borrarMin(nodo.right); } else nodo = (nodo.left != null) ? nodo.left : nodo.right; return nodo; private static int getClave(NodoBinario nodo){ return ((NodoBinarioBusq) nodo).clave;} Arboles M.C. José Andrés Vázquez FCC/BUAP

31 Complejidad y eficiencia
El coste de las operaciones depende de la profundidad del árbol ...de la profundidad del nodo en que se realiza la operación Profundidad del árbol: O(log N) ...si los nodos están "distribuidos uniformemente" Problemas: Algunas operaciones no contribuyen a mantener esa uniformidad (Ej: Borrado) Arboles M.C. José Andrés Vázquez FCC/BUAP

32 Complejidad y eficiencia (II)
Borrado (nodo con 2 hijos) Siempre elimina elementos del subárbol derecho Borrados en un subárbol aleatorio ¿Es una solución? Casos particularmente malos: Inserción de datos preordenados... Todos los nodos sin rama izquierda (o derecha) Mantener equilibrio: Impedir que se alcancen profundidades innecesarias Arboles M.C. José Andrés Vázquez FCC/BUAP


Descargar ppt "Arboles M.C. José Andrés Vázquez FCC/BUAP"

Presentaciones similares


Anuncios Google