recorridos en árboles binarios - Profesor ROBERTO OSORNIO SOTO

Anuncio
 INSTITUTO POLITÉCNICO NACIONAL SECRETARIA ACADÉMICA DIRECCIÓN DE EDUCACIÓN SUPERIOR ESIME CULHUACAN NOMBRE ALUMNO: Apellido paterno Apellido materno Nombre (s) No. BOLETA GRUPO FECHA DIA MES AÑO INGENIERÍA EN COMPUTACIÓN ASIGNATURA ESTRUCTURAS DE DATOS PROFESOR M. en C. BEATRIZ EUGENIA CORONA RAMÍREZ PRÁCTICA No. 9 RECORRIDOS EN ÁRBOLES BINARIOS 1. Objetivo El alumno comprenderá y aplicara los conceptos de los recorridos en árboles binarios en un programa que genere los recorridos. 2. Material y Equipo Computadora, Compilador C y/o Java y unidad de almacenamiento (USB) 3. Introducción Teórica La organización de los datos en una estructura en forma jerárquica o de niveles, es otra opción de representar estructuras de datos comúnmente denominados árboles. Su principal característica es que tienen una relación de uno a muchos (1:n) entre sus elementos. Estructura para representar: Un árbol genealógico Un organigrama Los directorios de un S.O. 98
Terminología Nodo Raíz Nodo Padre Hijo Derecho Hijo Izquierdo Nodo Hoja Nodo Hermano Ancestros Profundidad o Altura Nodo Descendiente Subárbol izquierdo Subárbol derecho Nivel de un nodo Es el primer elemento de un árbol binario, por lo tanto solo se tiene un nodo raíz Es el nodo que al menos tiene un hijo derecho y/o izquierdo Nodo que se encuentra al lado derecho de otro nodo Nodo que se encuentra al lado izquierdo de otro nodo Es el nodo que no tiene hijos. Un nodo de un árbol binario puede tener uno, dos o ningún hijo. Nodo que tiene un mismo padre. Nodo padre de un nodo padre (El nodo raíz es un ancestro de todos los nodos del árbol). Es el número máximo de nodos de una rama del árbol. Equivale a 1 mas que el mayor número de niveles de T. El hijo de un nodo o hijo de otro descendiente de ese nodo. Todos los nodos son descendiente del raíz. Todos los descendentes por la izquierda de un nodo forman un subárbol izquierdo cuya raíz es el hijo izquierdo de ese nodo. Idem subárbol izquierdo Distancia desde la raíz. La raíz esta en el nivel cero, cantidad de nodos por los que se tiene que pasar para llegar a un nodo. (el número máximo de nodos en el nivel n es 2n) 99
Ejemplo Nodo raíz = 1 El hijo derecho de 1 es 3 El hijo derecho de 6 es 10. El hijo izquierdo de 7 es 11. El hijo izquierdo de 1 es 2. El nodo padre de 6 y 7 es 3. El nodo padre de 9 es 5 Los nodos hojas son 13, 9 10, 11, 14. Los nodos hermanos son 4 y 5, 6 y 7 11 y 12 Los ancestros de 10 son 6, 3 y 1 Los descendientes de 7 son 11, 12 y 14 El subárbol derecho de 1 es el que tiene raíz 3 El subárbol izquierdo de 1 es el que tiene raíz 2 El nodo de nivel 0 es 1 Los nodos del nivel 1 son 2 y 3 Los nodos del nivel 2 son 4, 5, 6 y 7 Los nodos del nivel 3 son 8, 9, 10, 11 y 12 Los nodos de nivel 4 son 13 y 14 La manera más eficiente para realizar una búsqueda en una estructura lineal es con un algoritmo de búsqueda binaria sin embargo no es eficiente para la inserción y eliminación de datos, esta sería mejor con una lista encadenada. 100
Ejemplos ABB NO ABB a, c y d son copias. a, c y d son similares. El árbol T se dice que es completo si todos sus niveles, excepto posiblemente el último tiene el máximo número de nodos posibles y si todos los nodos del último nivel están situados los más posible a la izquierda Así solo existe un único árbol Tn con exactamente n nodos Los hijos izquierdos y derechos de un nodo K, son respectivamente 2*k y (2*k)+1. 101
1.
2.
1.
i)
ii)
iii)
Nodo 5  H.I. 2*5 = 10 H.D (2*5)+1=11  [5/2]=2 (padre) Y el padre de K es el nodo [k/2] Los hijos del nodo 9 son 18 y 19 y su padre es el [9/2] = 4 La profundidad dn del árbol completo Tn viene dado por Dn= [log2 n+1] Representación de árboles binarios en memoria Si T es un árbol, existen varias formas de representarlo en memoria. Representación enlazada de T (listas enlazadas) Representación secuencial de T (arreglos simple) Requerimientos: Se tenga acceso directo a la raíz R de T Dado cualquier nodo N de T se tenga acceso directo a los hijos de N. Representación usando listas enlazada Usaremos tres arreglos paralelos INFO, IZQ y DER y una variable puntero RAIZ Cada nodo N de T corresponderá a una posición k tal que: INFO[K] contiene los datos del nodo N IZQ[K] contiene la localidad del hijo izquierdo de N DER[K] contiene la localidad del hijo derecho de N RAIZ contiene la posición de la raíz de T. Si el árbol está vacío RAIZ = NULL 102
Ej. Considere el siguiente árbol binario T, en la figura anterior se representan esquemáticamente la representación enlazada de T, donde cada nodo está representado por 3 campos y los subárboles que están vacíos se representa con una “x” Ahora se hará una representación en memoria de forma enlazada. Info izq der info izq der 14 0 0 K Raíz
F 0 0 C 3 6 E 12 0 G 0 0 5
15 0 16 A 10 2 Disp
19 H 17 1 8
J 7 0 L 0 0 D 0 0 9 20 11 4 B 18 13 Representación secuencial de T Suponiendo que T es un árbol binario que es completo o casi completo. Por lo tanto T se representa en un arreglo lineal llamado ÁRBOL. a) La raíz R de T se guarda en ÁRBOL [1] ÁRBOL[1]=NULO, esta vacío b) Si un nodo N está en ÁRBOL [K], entonces: Su HI está en ÁRBOL[2*K] Su HD está en ÁRBOL[2*K+1] En términos generales la representación secuencial de un árbol de profundidad d requerirá un arreglo de aproximadamente 2d+2 elementos. Un árbol de 11 nodos  n=11 D=[log2n+1]  D=3.32(log 11)+1=4.45  4 (completo) , 5(casi completo) Requiere un arreglo de 2d+2=26=64 elementos. 1 2 3 4 45 22 77 11 103
Árbol Árbol n = 9 D = log2 9+1=4.16  4 5 6 7 8 9 10 11 12 13 14 15 16 30 90 15 25 88 ÁRBOLES BINARIOS EXTENDIDOS (ÁRBOLES – 2) Un árbol binario T es un árbol –2, si cada nodo N tiene 0 a 2 hijos. Los nodos internos tienen dos hijos (O), los nodos externos son lo que tienen 0 hijos ( ) Considere un árbol binario T como en la figura a y T puede ser convertido aun árbol‐2, reemplazando a cada subárbol vacío por un nuevo nodo como en b. Los nodos del árbol T original son ahora los nodos interiores del extendido y los nuevos nodos son los nodos externos del árbol extendido. Ej. E=(a‐b)/((c*d)+e) variables de E  nodos externos operadores de E  nodos internos 104
Recorrido de árboles binarios. La acción de recorrer una estructura de datos es muy importante, ya que permite hacer algo en todos los elementos (desplegarlos). En una estructura lineal se hace de inicio a fin pero en una jerárquica hay diferentes formas, de las cuales existen 3 modos estándar de recorrer un árbol binario T de raíz R. • Preorden 1. procesar (visitar) el nodo raíz R 2. recorrer el subárbol izquierdo de R en preorden 3. recorrer en preorden el subárbol derecho del nodo raíz. • In orden 1. recorrer el subárbol izquierdo de R en inorden 2. procesar (visitar) el nodo raíz R 3. recorrer en inorden el subárbol derecho del nodo raíz. • Postorden 1. recorrer el subárbol izquierdo de R en postorden 2. recorrer en postorden el subárbol derecho del nodo raíz. 3. procesar (visitar) el nodo raíz R La diferencia entre los tres es el momento en el que se procesa o visita la raíz R: Pre  R se visita antes de los subárboles In  se visita entre los dos subárboles Post  al final de los dos Siempre se recorre el subárbol izquierdo antes del derecho. También existe el recorrido: CONVERSO en los que el orden de recorrido se invierte a der  izquierda y no de izq  der También existe uno llamado nivel por nivel; se visita a partir del nivel 0 a n, y de izquierda a derecha.  insertar el apuntador al nodo raíz a una fila  mientras la fila no se vacié i. sacar el apuntador de la fila y procese el nodo señalado ii. inserte en la fila los apuntadores de los hijos del nodo procesado (si existen). 105
Ejemplo: Obtener los 7 recorridos del siguiente árbol pre‐orden = < / & ? $ + in‐orden / & < ? = + $ post‐orden & / ? < + $ = pre‐orden‐c = $ + < ? / & in‐orden‐c $ + = ? < & / post‐orden‐c + $ ? & / < = nivel x nivel = < $ / ? + & Ejercicio 106
4. Desarrollo Realizar un programa que genere un árbol binario e imprima sus recorridos /*Crea arbol binario*/ #include<stdio.h> #include<conio.h> #include<stdlib.h> crea_arbol(struct arbol *); Preorden(struct arbol *); struct arbol {int dato; struct arbol *IZQ; struct arbol *DER;}; main() { clrscr(); char resp='s'; int dato; struct arbol *R; R‐>dato=NULL; R‐>IZQ=NULL; R‐>DER=NULL; printf("Teclea RAIZ: "); scanf("%d",&R‐>dato); crea_arbol(R); getch(); clrscr(); printf("\nINORDEN"); printf("\nLos datos almacenados en el arbol son:"); printf("\n\n"); Preorden(R); getch(); } crea_arbol(struct arbol *NODO) { int RESP; struct arbol *OTRO; 107
printf("Teclea el valor del nodo: "); scanf("%d",&NODO‐>dato); printf("¨Existe nodo por la izquierda. [S/N]?)"); scanf("%d",&RESP); if(RESP==1) {OTRO=new struct arbol; OTRO‐>dato=NULL; OTRO‐>IZQ=NULL; OTRO‐>DER=NULL; NODO‐>IZQ=OTRO; crea_arbol(NODO‐>IZQ);} else {NODO‐>IZQ=NULL;} printf("\n¨Existe nodo por la derecha. [S/N]?"); scanf("%d",&RESP); if(RESP==1) {OTRO=new struct arbol; OTRO‐>dato=NULL; OTRO‐>IZQ=NULL; OTRO‐>DER=NULL; NODO‐>DER=OTRO; crea_arbol(NODO‐>DER);} else { NODO‐>DER=NULL; } } Preorden(struct arbol *NODO) {if(NODO != NULL) {printf("\n"); printf("%d",NODO‐>dato); Preorden(NODO‐>IZQ); Preorden(NODO‐>DER);}} 108
5. Cuestionario [Trabajo complementario] 1. Define que es una estructura jerarquica 2. Menciona las ventajas de una estructura de este tipo 3. Considerar el siguiente árbol binario T a) recorrido pre orden: ABDECF b) recorrido in orden: DBEACF c) recorrido post orden: DEBFCA Crear el árbol correspondiente 4. Igual con el siguiente árbol 5. Sea la siguiente expresión algebraica construir el árbol y sus 7 recorridos [a+(b‐c)]*[(d‐e)/(f+g‐h)] 6. Conclusiones 109
Descargar