Contenido del Tema 6.1. Introducción 6.2. Pilas 6.3. Colas 6.4. Listas 6.5. Arboles Binarios. Arboles Binarios de Búsqueda 6.6. Otras Estructuras. Metodología de la Programación. Curso 2002/03. Pág. 1 Objetivos • Especificación e Implementación de nuevas estructuras de datos Técnica: Abstracción de Datos • Tipos de Estructuras de Datos: 1) Datos organizados por Posición Pilas , Colas y Listas 2) Datos organizados por Valor Arboles Binarios Metodología de la Programación. Curso 2002/03. Pág. 2 • Estudio de las Estructuras de Datos: Definición de la Estructura de Datos e identificación de su Conjunto de Operaciones Desarrollo de diversas Implementaciones Presentación de Aplicaciones Metodología de la Programación. Curso 2002/03. Pág. 3 Definición • Pila: Grupo Ordenado, (de acuerdo al tiempo que llevan en la pila) de Elementos Homogéneos (todos del mismo tipo). • Acceso a la Pila: añadir y eliminar elementos, SÓLO a través de la CABEZA de la Pila • Estructura LIFO (Last Input First Output) Añadir Eliminar Cabeza Pila Metodología de la Programación. Curso 2002/03. Pág. 4 Conjunto de Operaciones MÓDULO MPila DEFINICIÓN TIPOS TElemento= // cualquier tipo de datos TPila= // por definir PROC MeterPila(↓↑pila:TPila; ↓elem: TElemento) // Añade un elemento por la cabeza de la pila PROC SacarPila(↓↑pila:TPila;↑elem:TElemento) // Saca un elemento por la cabeza de la Pila Metodología de la Programación. Curso 2002/03. Pág. 5 Conjunto de Operaciones FUNC CrearPila():TPila // Crea una pila vacía FUNC PilaVacia (↓pila :TPila):LÓGICO // Nos dice si una pila está vacía FUNC PilaLlena(↓pila:TPila):LÓGICO // Nos dice si una pila está llena. PROC DestruirPila(↓↑ pila:TPila) // Destruye una pila previamente creada Fin Metodología de la Programación. Curso 2002/03. Pág. 6 Implementación 1) Con un Array • Array estructura adecuada Elementos Homogéneos • Elementos almacenados de forma Secuencial CONSTANTES MAXPILA ← 100 TIPOS TElemento = ENTERO TPila = ARRAY[1..MAXPILA]DE TElemento Metodología de la Programación. Curso 2002/03. Pág. 7 Sólo es posible acceder a la Cabeza de la Pila ¿ Cómo es posible conocer la posición de la cabeza? 1) Variable entera “cabeza” Inconveniente: se ha de pasar como parámetro adicional a todas las operaciones sobre la pila 2) Extender el array, en pila[0] almacenaremos el índice del elemento que ocupa la cabeza actual Metodología de la Programación. Curso 2002/03. Pág. 8 CONSTANTES CABEZA ← 0 MAXPILA ← 100 TIPOS TPila = ARRAY[CABEZA..MAXPILA] DE TElemento 3 5 [0] [1] 3 ....... 2 [2] [3] Cabeza [99] [100] 2 3 5 Cabeza Basura Metodología de la Programación. Curso 2002/03. Pág. 9 • Inconveniente: Solo es posible implementar una pila de enteros (no de cualquier otro tipo de datos) • Solución: CONSTANTES MAXPILA ← 100 TIPOS TElemento= // cualquier tipo de datos TPila=REGISTRO Cabeza: NATURAL Elementos: ARRAY[1..MAXPILA] DE TElemento Cabeza k Elementos 5 1 13 2 8 k MAXPILA Metodología de la Programación. Curso 2002/03. Pág. 10 IMPLEMENTACIÓN FUNC CrearPila():TPila VARIABLES pila:TPila INICIO pila.Cabeza ← 0 RESULTADO ← pila FIN FUNC PilaVacia(↓pila:TPila ):LÓGICO INICIO RESULTADO←pila.Cabeza=0 FUNC PilaLlena(↓pila:TPila ):LÓGICO INICIO RESULTADO ←(pila.Cabeza = MAXPILA) FIN PROC DestruirPila(↓↑pila:TPila) INICIO // No hay que hacer nada. FIN FIN Metodología de la Programación. Curso 2002/03. Pág. 11 PROC SacarPila(↓↑pila:TPila; ↑elem:TElemento) INICIO ↓elem :TElemento) INICIO elem ← pila.Elementos [pila.Cabeza] pila.Cabeza←pila.Cabeza-1 FIN /* precondición: la pila no ha de estar vacía */ PROC MeterPila(↓↑pila:TPila; pila.Cabeza←pila.Cabeza+1 pila.Elementos [pila.Cabeza] ← elem FIN /* precondición: la pila no ha de estar llena */ Metodología de la Programación. Curso 2002/03. Pág. 12 PROC MeterPila (↓↑pila:TPila; ↓elem:TElemento; ↑llena : LÓGICO) Inicio llena ←PilaLlena(pila) SI (¬llena) ENTONCES pila.Cabeza← pila.Cabeza + 1 pila.Elementos [pila.Cabeza] ← elem FINSI Fin /* Sin Precondición.Introduce un elemento en la pila si no está llena */ PROC SacarPila(↓↑pila:TPila ; ↑elem:TElemento; ↑vacia:LÓGICO) INICIO vacia ← PilaVacia(pila) SI ¬vacia ENTONCES elem←pila.Elementos[pila.Cabeza] pila.Cabeza ←pila.Cabeza-1 FINSI FIN /* Sin precondición. Saca un elemento de la pila si no está vacía*/ Metodología de la Programación. Curso 2002/03. Pág. 13 2) Con una Lista Enlazada de Punteros • Comienzo de una lista enlazada Cabeza de la Pila TIPOS TElemento= // cualquier tipo de datos TPila = PUNTERO A TNodoPila TNodoPila = REGISTRO dato:TElemento sig: TPila FINREGISTRO cabeza 10 8 10 8 Metodología de la Programación. Curso 2002/03. Pág. 14 PROC MeterPila(↓↑pila:TPila; ↑elem: TElemento; ↑llena: LÓGICO) VARIABLES nuevonodo : TPila INICIO llena ← FALSO nuevonodo ← NUEVO(TNodoPila) nuevonodo^.dato ← elem nuevonodo^.sig ← pila pila ← nuevonodo FIN PROC SacarPila(↓↑pila:TPila; ↑elem:TElemento; ↑vacía: LÓGICO) VARIABLES ptr: TPila INICIO vacía ← PilaVacía(pila) SI ¬vacía ENTONCES elem ← pila^.dato ptr ← pila pila ← pila^.sig ELIMINAR(ptr) FINSI FIN Metodología de la Programación. Curso 2002/03. Pág. 15 PROC CrearPila():TPila PROC DestruirPila(↓↑pila:TPila) INICIO Variables RESULTADO ← NULO Fin ptr: TPila Inicio MIENTRAS(pila≠ NULO)HACER FUNC PilaVacia(pila :TPila ):LÓGICO INICIO RESULTADO ← (pila= NULO) FIN ptr ← pila pila ← pila^.sig ELIMINAR(ptr) FINMIENTRAS FIN Metodología de la Programación. Curso 2002/03. Pág. 16 Aplicaciones • Ejemplo1: Leer una secuencia de caracteres desde teclado e imprimirla al revés • Ejemplo2: Verificar si una cadena de caracteres está balanceada en paréntesis o no abc(defg(ijk))(l(mn)op)qr SI abc(def))ghij(kl)m NO • Ejemplo3: Reconocimiento del Lenguaje, L={W$W´ / W es una cadena de caracteres y W´es su inversa} (Suponemos que $ no está ni en W ni en W´) Metodología de la Programación. Curso 2002/03. Pág. 17 ALGORITMO Inverso DESDE MPila IMPORTA TPila, CrearPila, MeterPila, SacarPila, Pilavacia, DestruirPila CONSTANTES ENTER ← CHR(13) TIPOS TElemento = CARÁCTER VARIABLES c : TElemento pila : TPila ll,v:LÓGICO INICIO pila ← CrearPila() LEER(c) MIENTRAS (c≠ENTER) ∧ (¬ll) HACER MeterPila(pila,c,ll) Leer(c) FINMIENTRAS SacarPila(pila,c,v) MIENTRAS (¬PilaVacia(pila))HACER SacarPila(pila,c,v) Escribir(c) FINMIENTRAS DestruirPila(pila) FIN Metodología de la Programación. Curso 2002/03. Pág. 18 ALGORITMO Balanceo DESDE MPila IMPORTA CrearPila, TPila, MeterPila, SacarPila, PilaVacia, DestruirPila CONSTANTES ENTER ← CHR(13) Tipos TElemento = CARÁCTER VARIABLES c : TElemento pila : TPila bien,ll, v : LÓGICO Inicio pila ← CrearPila() bien ← CIERTO LEER(c) MIENTRAS(bien ∧ (c≠ENTER)HACER SI c= ‘(’ ENTONCES MeterPila(pila,c,ll) bien ← ¬ll EN OTRO CASO SI c = ‘)’ ENTONCES SacarPila(pila,c,v) bien ← ¬v FINSI FINSI LEER(c) FINMIENTRAS SI bien ∧ PilaVacia(pila) ENTONCES Escribir(“cadena balanceada “) EN OTRO CASO Escribir(“cadena no balanceada”) FINSI DestruirPila(pila) FIN Metodología de la Programación. Curso 2002/03. Pág. 19 Algoritmo Lenguaje_L DESDE MPila IMPORTA TPila, CrearPila, MeterPila, SacarPila, DestruirPila CONSTANTES ENTER ← CHR(13) TIPOS TElemento = CARÁCTER VARIABLES c1, c2 : TElemento pila : TPila bien, ll, v : LÓGICO Inicio pila ← CrearPila() ll ← FALSO LEER(c1) MIENTRAS (c1=≠‘$’)∧(¬ll) HACER MeterPila(pila,c1,ll) LEER(c1) FINMIENTRAS Leer(c1) bien ← TRUE MIENTRAS (bien ∧ (c1 ≠ENTER)) HACER SacarPila(pila,c2,v) bien ← (¬v) ∧ (c1=c2) /* He podido sacar el elemnto y conicide */ SI (bien) ENTONCES Leer(c1) FINSI FINMIENTRAS SI (bien ∧ PilaVacia(pila))ENTONCES Escribir(“ Si pertenece”) EN OTRO CASO Escribir (“No pertenece”) FINSI DestruirPila(pila) FIN Metodología de la Programación. Curso 2002/03. Pág. 20 • Aplicaciones complejas que se pueden solucionar con pilas: Expresiones Algebraicas Operadores: +, -, *, / Operandos: Letras mayúsculas • Notación Infija: • El operador binario está situado entre sus dos operandos A+ B • Inconveniente: Son necesarias reglas de precedencia y uso de paréntesis para evitar ambigüedades A+B*C Metodología de la Programación. Curso 2002/03. Pág. 21 Notación Prefija Notación Postfija • El operador binario esta situado justo antes de sus dos operandos +AB • Gramática: <expr_pref>::=<letra>|<operador> <expr_pref><expr_pref> <letra> ::= A| B ....|Z <operador> ::= + | - | * | / • Ejemplos: A+(B*C) +A*BC (A+B)*C *+ABC • El operador binario está situado justo después de sus dos operandos AB+ • Gramática: <exp_post>::=<letra>|<expr_post> <exp_post><operador> <letra> ::=A| B ....|Z <operador> ::= + | - | * | / • Ejemplos: A+(B*C) ABC*+ (A+B)*C AB+C* Metodología de la Programación. Curso 2002/03. Pág. 22 • Ventaja: Usando expresiones prefijas y postfijas no son necesarias reglas de precedencia, ni uso de paréntesis. Las gramáticas que las generan son muy simples, y los algoritmos que las reconocen y evaluan muy fáciles • Ejemplo 4: Algoritmo que evalúa una expresión en notación Postfija 1)Usaremos una pila 2)La expresión postfija se almacenará en un array de caracteres y será correcta 3)Los operadores serán: +, -, * y / 4)Los operandos serán letras mayúsculas (a cada una le podemos asignar un valor) Metodología de la Programación. Curso 2002/03. Pág. 23 CONSTANTES MAX ← 20 TIPOS TArray = ARRAY[1..MAX] DE CARÁCTER TElemento=ENTERO FUNC Operando(↓c:CARACTER) :ENTERO VARIABLES res:ENTERO INICIO CASO c SEA ‘A’ : res ‘B’ : res ‘C’ : res ‘D’ : res EN OTRO CASO res ← 0 FINCASO RESULTADO ← FIN ← ← ← ← 5 7 -1 11 res Metodología de la Programación. Curso 2002/03. Pág. 24 FUNC Eval_postfija(↓exp: TArray; ↓ultimo:NATURAL):ENTERO MPila IMPORTA DESDE DestruirPila TPila, CrearPila, MeterPila, SacarPila, Variables pila : TPila i, op1, op2, result : ENTERO c : CARÁCTER v,ll:LÓGICO FUNC es_operador(↓c:CARÁCTER):LÓGICO INICIO RESULTADO ← (c=`*´) ∨ (c=`/´) ∨ (c=`+´) ∨ (c=`-´} FIN Metodología de la Programación. Curso 2002/03. Pág. 25 Inicio pila ← CrearPila() PARA i ← 1 HASTA ultimo HACER c ← exp[i] SI es_operador(c) ENTONCES SacarPila(pila,op2,v) SacarPila(pila,op1,v) CASO c SEA ‘+’ :MeterPila(pila,op1+op2,ll) ‘-’ : MeterPila(pila,op1-op2,ll) ‘*’ : MeterPila(pila,op1*op2,ll) ‘/’ : MeterPila(pila, op1/op2,ll) FINCASO EN OTRO CASO MeterPila(pila, Operando(c)) FINSI FINPARA SacarPila(pila,result) DestruirPila(pila) RESULTADO ← result Fin Metodología de la Programación. Curso 2002/03. Pág. 26 Definición • Cola: es un grupo ordenado (con respecto al tiempo que llevan en él) de elementos homogéneos (todos del mismo Tipo) • Acceso: los elementos se añaden por un extremo (final) y se sacan por el otro extremo (frente) • Estructura FIFO (First Input First Output) Sacar Frente Meter Final Metodología de la Programación. Curso 2002/03. Pág. 27 Conjunto de Operaciones MODULO MCola DEFINICIÓN TIPOS TElemento =// cualquier tipo de datos TCola= // por definir FUNC CrearCola(): TCola // Crea una cola vacia FUNC ColaVacia(↓cola:TCola): LÓGICO /* Operación lógica que nos dice contiene algún elemento o no*/ si la cola Metodología de la Programación. Curso 2002/03. Pág. 28 FUNC ColaLlena(↓cola:TCola):LÓGICO /* Operación lógica que nos dice si la cola está llena o no */ PROC MeterCola(↓↑cola: TCola; ↓elem: TElemento) // Introduce un elemento al final de la cola/ PROC SacarCola(↓↑cola: TCola; ↑elem: TElemento) // Saca un elemento del frente de la cola PROC DestruirCola(↓↑cola:TCola) // Destruye una cola previamente creada Fin Metodología de la Programación. Curso 2002/03. Pág. 29 Implementación 1) Con un Array • Se deja fijo el frente de la cola y se mueve el final a medida que se añaden nuevos elementos (Idem Pila) • Las operaciones Meter, Crear, ColaVacia y ColaLlena se implementan de una forma similar a sus análogas en Pilas • La operación de Sacar es mas complicada: cada vez que saquemos un elemento de la cola se han de desplazar el resto una posición en el array, para hacer coincidir el frente con la primera posición del array • Ventaja Simplicidad • Inconveniente Ineficiente (colas con muchos elementos o elementos grandes) Metodología de la Programación. Curso 2002/03. Pág. 30 • Ejemplo: 1 Meter(Cola,”A”) Meter(cola, “B”) 3 4 .......... Final=1 A 1 2 A B 1 2 3 4 .......... Final=2 3 4 .......... 3 4 .......... B Sacar(cola, elem) elem) 1 Desplazar 2 2 B 1 Final=1 2 3 4 .......... Metodología de la Programación. Curso 2002/03. Pág. 31 Solución: • Utilizar un indice para el frente y otro para el final y permitir que ambos fluctuen por el array • Ventaja: operación Sacar más sencilla • Inconveniente: Es posible que final sea igual a Maxcola (última casilla del array) y que la cola no esté llena Metodología de la Programación. Curso 2002/03. Pág. 32 • Ejemplo: Meter(Cola,”A”) Meter(cola, “B”) Meter(cola, “C”) Frente=1 A Final=1 1 2 A B 1 2 A B 1 2 Sacar(cola,elem Sacar(cola,elem)) B 1 2 3 4 .......... 3 4 .......... Final=3 4 .......... C 3 Final=2 Frente=1 C 3 Frente=1 Frente=2 Final=3 4 .......... Metodología de la Programación. Curso 2002/03. Pág. 33 • Solución: • Tratar al array como una Estructura Circular, Circular donde la última posición va seguida de la primera Evitamos que el final de la cola alcance el final físico del array y no esté llena • Operación Meter Añade elementos a las posiciones del array e incrementa el índice final • Operación Sacar Más sencilla. Sólo se incrementa el índice frente a la siguiente posición Metodología de la Programación. Curso 2002/03. Pág. 34 • Ejemplo: 1 Frente=5 Final=6 6 H 3 B 5 Final=6 6 Meter(cola,”G”) 6 3 B 5 G 3 B Sacar(cola,elem Sacar(cola,elem)) 6 Final=1 2 H 3 5 4 Frente=5 4 1 2 H 2 H 5 4 1 Frente=5 1 2 Frente=6 Final=6 4 Metodología de la Programación. Curso 2002/03. Pág. 35 ¿Como sabemos si la cola está vacía o llena? 1 Frente=4 Final=2 6 1 Final=3 A H 5 Frente=3 M 6 3 B S Meter(cola,”L”) 6 1 2 4 3 Sacar(cola,elem Sacar(cola,elem)) M A H 5 4 B 5 1 2 2 L B S 3 Final=3 !!Cola llena!! 4 2 6 3 5 Frente=4 4 Frente=4 Final=3 !!Cola Vacía!! Metodología de la Programación. Curso 2002/03. Pág. 36 • Solución: • 1) Disponer de otra variable Contabilizará los elementos almacenados en la cola Variable=0 Cola vacía Variable=MaxCola Cola llena Inconveniente: añade más procesamiento a las operaciones Meter y Sacar • 2) Frente apunte a la casilla del array que precede a la del elemento frente de la cola Solución elegida Metodología de la Programación. Curso 2002/03. Pág. 37 • Ejemplo: 1 Frente=4 Final=6 6 H 5 1 2 3 B Meter(cola,”G”) 6 2 H 5 4 G 3 B Frente=4 Final=1 4 ¿Como saber si la cola está llena? Es necesario que la posición a la que apunta frente en cada momento este Reservada Cola Llena: final+ final+1 =frente 1 Frente=3 Final=2 6 M A H 5 2 res 3 B S 4 Metodología de la Programación. Curso 2002/03. Pág. 38 ¿Como saber si la cola está vacía? Cola Vacía: Frente = Final 1 Frente=4 Final=5 1 2 3 6 5 B res 4 Sacar(cola,elem Sacar(cola,elem)) 2 3 6 5 Frente=5 Final=5 4 • Crear la cola (inicializarla vacía): frente =Maxcola (índice del array que precede al elemento frente de la cola) y final=Maxcola Cola Vacía correcto (frente = final) Metodología de la Programación. Curso 2002/03. Pág. 39 • Agrupamos en un registro los índices frente y final, junto con el array que contendrá los elementos de la cola CONSTANTES MAXCOLA ← 100 TIPOS TElemento = // Cualquier tipo de datos TCola = REGISTRO elementos:ARRAY[1..MAXCOLA]DE TElemento Frente,Final : [1.. MAXCOLA] FINREGISTRO frente Maxcola 2 final 5 1 13 2 MaxCola Metodología de la Programación. Curso 2002/03. Pág. 40 FUNC CrearCola():TCola VARIABLES cola: TCola INICIO cola.Frente ← MAXCOLA cola.Final ← MAXCOLA RESULTADO ← cola FIN PROC DestruirCola(↓↑cola :TCola) INICIO // No hay que hacer nada. FIN FUNC ColaLlena(↓cola:Tcola ):LÓGICO INICIO RESULTADO ← (cola.Final MOD MAXCOLA)+1 = cola.Frente FIN FUNC ColaVacia(↓cola:Tcola ):LÓGICO INICIO RESULTADO← ← cola.Final = cola.Frente FIN Metodología de la Programación. Curso 2002/03. Pág. 41 PROC MeterCola(↓↑cola:TCola; ↓elem:TElemento) VARIABLES fin:NATURAL INICIO fin ← (cola.Final MOD MAXCOLA) + 1 cola.Final ← fin cola.elementos[fin]←elem FIN PROC SacarCola(↓↑cola:TCola; ↑elem:TElemento) VARIABLES ini:NATURAL INICIO ini ← (cola.Frente MOD MAXCOLA) + 1 cola.Frente ← ini elem←cola.elementos[ini] FIN Metodología de la Programación. Curso 2002/03. Pág. 42 2) Con listas enlazadas con Punteros • Usamos dos variables de tipo puntero, frente y final, que apunten a los nodos que contienen los elementos frente y final 10 8 4 Frente Final • ¿Que sucedería si intercambiáramos las posiciones de frente y final en la lista enlazada? Metodología de la Programación. Curso 2002/03. Pág. 43 • Agrupamos las variables frente y final en un registro TIPOS TElemento = // cualquier tipo de datos TPuntero = PUNTERO A TNodo TNodo = REGISTRO valor : TElemento sig : TPuntero FINREGISTRO TCola = REGISTRO Frente : TPuntero Final : TPuntero FINREGISTRO 3 10 Frente 8 Final Metodología de la Programación. Curso 2002/03. Pág. 44 FUNC CrearCola(): TCola VARIABLES cola:TCola INICIO cola.Frente ← NULO cola.Final ← NULO RESULTADO ← cola FIN FUNC ColaVacia(↓cola: TCola):LÓGICO INICIO RESULTADO ← cola.Frente = NULO FIN PROC DestruirCola(↓↑cola: TCola) Variables nodo,sgte: TPuntero Inicio SI(cola.Frente≠NULO) ENTONCES sgte ← cola.Frente MIENTRAS (sgte≠NULO) HACER nodo ← sgte sgte ← sgte^.sig ELIMINAR(nodo) FINMIENTRAS FINSI cola.Frente ← NULO cola.Final ← NULO FIN Metodología de la Programación. Curso 2002/03. Pág. 45 PROC MeterCola(↓↑cola:TCola; ↓elem:TElemento) VARIABLES ptr: TPuntero Inicio ptr ← NUEVO(TNodo) ptr^.valor ← elem ptr^sig ← NULO SI ColaVacia(cola) ENTONCES cola.Frente ← ptr EN OTRO CASO cola.Final^.sig ← ptr FINSI cola.Final ← nuevonodo FIN PROC SacarCola (↓↑cola:TCola; ↑elem:TElemento) VARIABLES temp : TipoPuntero INICIO temp ← cola.Frente elem ← cola.Frente^.valor cola.Frente ← cola.Frente^.sig SI (cola.Frente=NULO) ENTONCES cola.Final ← NULO FINSI ELIMINAR(temp) FIN Metodología de la Programación. Curso 2002/03. Pág. 46 Ejemplo: Reconocimiento del lenguaje. L={W$W/W es una cadena que no contiene a$} Algoritmo Lenguaje_L DESDE MCola IMPORTA TCola, CrearCola, ColaVacia, SacarCola, MeterCola, DestruirCola CONSTANTES ENTER ← CHR(13) TIPOS TElemento = CARÁCTER VARIABLES bien : LÓGICO c1,c2 : TElemento cola : TCola INICIO cola ← CrearCola() LEER(c1) MIENTRAS (c1 ≠ ‘$’) HACER MeterCola(cola,c1) LEER(c1) FINMIENTRAS Metodología de la Programación. Curso 2002/03. Pág. 47 Leer(c1) bien ← CIERTO MIENTRAS (bien ∧ (c1≠ENTER) HACER SI ColaVacia(cola) ENTONCES bien ← FALSE EN OTRO CASO SacarCola(cola,c2) SI (c1 ≠c2) ENTONCES bien ← FALSE EN OTRO CASO LEER(c1) FINSI FINSI FINMIENTRAS SI (bien ∧ ColaVacia(cola)) ENTONCES Escribir(“Pertenece”) EN OTRO CASO Escribir(“No pertenece”) FINSI DestruirCola(cola) FIN Metodología de la Programación. Curso 2002/03. Pág. 48 • Definición de lista • Implementación - Estática - Dinámica Metodología de la Programación. Curso 2002/03. Pág. 49 • Definición: Una lista es una colección de elementos homogéneos (del mismo tipo), con una relación lineal entre ellos. • Los elementos pueden o no estar ordenados con respecto a algún valor y se puede acceder a cualquier elemento de la lista. • En realidad, las pilas y colas vistas en secciones anteriores son listas, con algunas restricciones. Metodología de la Programación. Curso 2002/03. Pág. 50 Operaciones sobre listas: Crear ¿Esta vacía? ¿Está llena? Insertar un elemento - De forma ordenada - De forma no ordenada Eliminar un elemento Imprimir Destruir Metodología de la Programación. Curso 2002/03. Pág. 51 MÓDULO Mlistas DEFINICIÓN TIPOS =// cualquier tipo de datos = // por definir TElemento TLista FUNC CrearLista():TLista FUNC ListaVacia(↓lista:TLista): LÓGICO FUNC ListaLlena(↓lista:TLista): LÓGICO PROC InsertarLista(↓↑lista:TLista; ↓elem:TElemento) PROC EliminarLista(↓↑Lista:TLista; ↓elem:TElemento) PROC ImprimirLista(lista:TLista) PROC DestruirLista(↓↑lista: TLista) IMPLEMENTACIÓN .............. Fin Metodología de la Programación. Curso 2002/03. Pág. 52 • Implementación: – Representación secuencial – Representación enlazada - Dinámica - Estática Metodología de la Programación. Curso 2002/03. Pág. 53 Dinámicas • Utilizaremos punteros para crear la lista enlazada de elementos. • Las definiciones de tipos y la implementación de las operaciones se han visto. Metodología de la Programación. Curso 2002/03. Pág. 54 Estáticas • Array de registros: • Elemento. • Enlace al siguiente elemento. • Los registros pueden almacenarse en cualquier orden físico y se enlazarán a través del campo enlace. Metodología de la Programación. Curso 2002/03. Pág. 55 Metodología de la Programación. Curso 2002/03. Pág. 56 • Inconveniente Variable estática Elección de Tamaño Máximo • Debemos escribir nuestros propios algoritmos de manejo de memoria No disponemos de NUEVO y ELIMINAR. ELIMINAR • En el array de registros coexistirán dos listas: - Nuestra lista enlazada de elementos. - Una lista enlazada con el espacio libre disponible. Metodología de la Programación. Curso 2002/03. Pág. 57 Metodología de la Programación. Curso 2002/03. Pág. 58 Consideraciones • El cero (o cualquier otro valor distinto de [1..10]) hará las funciones de NULO en las listas enlazadas con punteros. • Cuando no existe ningún elemento en la lista (lista vacía) sólo existirá la lista libre, que enlaza todas las posiciones del array. • Si la lista se llena, no tendremos lista libre. • Para simular el manejo de memoria real mediante asignación dinámica de memoria, consideramos el array y la variable Libre como globales al módulo de implementación de la lista. Metodología de la Programación. Curso 2002/03. Pág. 59 MÓDULO Mlistas DEFINICIÓN CONSTANTES VALOR_NULO ← 0 // Hace las funciones de NULO MAX ← 100 TIPOS TLista = [0..Max] TElemento = // cualquier tipo de datos TNodo = REGISTRO elemento : TElemento sig : TLista FINREGISTRO FUNC CrearLista():TLista FUNC ListaVacia(↓lista:TLista): LÓGICO PROC ListaLlena(↓lista: TLista): LÓGICO PROC ImprimirLista(↓lista: TLista) PROC InsertarLista(↓↑lista:TLista; ↓elem:TElemento) PROC EliminarLista(↓↑lista:TLista; ↓elem:TElemento) PROC DestruirLista(↓↑lista:TLista) Metodología de la Programación. Curso 2002/03. Pág. 60 IMPLEMENTACIÓN TIPOS TMemoria = ARRAY [1..MAX] DE TNodo VARIABLES memoria : TMemoria libre : TLista FUNC CrearLista():TLista INICIO RESULTADO ← VALOR_NULO FIN FUNC ListaVacia(↓lista:TLista): LÓGICO INICIO RESULTADO ← (lista = VALOR_NULO) FIN FUNC ListaLlena(↓lista:TLista):LÓGICO INICIO RESULTADO ← (libre = VALOR_NULO) FIN Metodología de la Programación. Curso 2002/03. Pág. 61 Para los procedimientos InsertarLista y EliminarLista, necesitamos antes implementar las operaciones (NuevoNodo, EliminarNodo) equivalentes a las que usamos al trabajar con memoria dinámica. FUNC NuevoNodo(): Tlista VARIABLES ptr: TLista INICIO ptr ← libre SI (ptr ≠ Nulo) ENTONCES libre ← memoria[ptr]. sig FINSI RESULTADO ← ptr FIN PROC EliminarNodo (↓↑p : TLista) INICIO memoria[p].sig ← libre lbre ← p p ← VALOR_NULO FIN Metodología de la Programación. Curso 2002/03. Pág. 62 de en ep D m le TE to en MIENTRAS (ptr ≠ VALOR_NULO) HACER Escribir(memoria[ptr].elemento) ptr ← memoria[ptr].sig FINMIENTRAS de PROC ImprimirLista(↓lista : TLista) VARIABLES ptr : TLista INICIO ptr ← lista FIN PROC InsertarLista(↓↑lista: TLista; ↓elem: TElemento) VARIABLES ptr : TLista INICIO ptr ← NuevoNodo() SI (ptr ≠ VALOR_NULO) ENTONCES memoria[ptr].elemento ← elem memoria[ptr].sig ← lista lista ← ptr FINSI FIN Metodología de la Programación. Curso 2002/03. Pág. 63 PROC EliminarLista (↓↑lista: TLista; ↓elem :TElemento) VARIABLES pav, pret : TLista Suponemos que el INICIO elemento a borrar pav ← lista // puntero avanzado está en la lista pret ← Nulo // puntero retrasado MIENTRAS (memoria[pav].elemento ≠ elem) HACER pret ← pav pav ← memoria[pav].sig FINMIENTRAS SI (pret = VALOR_NULO) ENTONCES lista ← memoria[lista].sig EN OTRO CASO memoria[pret].sig ← memoria[pav].sig FINSI EliminarNodo(pav) Fin Metodología de la Programación. Curso 2002/03. Pág. 64 PROC DestruirLista(↓↑lista: TLista) Variables aux: TLista INICIO MIENTRAS (lista ≠ VALOR_NULO) HACER aux ← lista lista ← memoria[lista].sig EliminarNodo(aux) FIN FIN INICIO // Mlista Libre ← 1 PARA ptr ← 1 HASTA (Max-1) HACER memoria[ptr].sig ← ptr + 1 FINPARA memoria[Max].enlace ← VALOR_NULO FIN // Mlista Metodología de la Programación. Curso 2002/03. Pág. 65 • Implementación estática o dinámica. • El campo de enlace del último nodo apunta al primer nodo de la lista, en lugar de tener el valor NULO. • No existe ni primer ni último nodo. Tenemos un anillo de elementos enlazados unos con otros. Metodología de la Programación. Curso 2002/03. Pág. 66 • Es conveniente, aunque no necesario, tener un enlace (puntero o índice) al último nodo lógico de la lista. Así podemos acceder facilmente a ambos extremos de la misma. p • Una lista circular vacía vendrá representada por un valor NULO (o VALOR_NULO). Metodología de la Programación. Curso 2002/03. Pág. 67 Ejemplo: (usando una implementación estática) PROC ImprimirLista(↓lista:TLista) VARIABLES ptr : TLista INICIO ptr ← lista SI (ptr ≠ VALOR_NULO) ENTONCES REPETIR Escribir(memoria[ptr].elemento) ptr ← memoria[ptr].sig HASTA QUE ptr = lista FINSI Fin Metodología de la Programación. Curso 2002/03. Pág. 68 • Con una lista enlazada circular es muy fácil implementar una Cola, sin tener que disponer de un registro con dos campos para el frente y para el final. Frente Final p Implementación Metodología de la Programación. Curso 2002/03. Pág. 69 • Es una lista enlazada en la que cada nodo tiene al menos tres campos: - Elemento. El dato de la lista. - Enlace al nodo anterior. - Enlace al nodo siguiente. • Los algoritmos para las operaciones sobre listas doblemente enlazadas son normalmente más complicados. • Pueden ser recorridas fácilmente en ambos sentidos. lista Implementación Metodología de la Programación. Curso 2002/03. Pág. 70 • Una lista doblemente enlazada puede modificarse para obtener una estructura circular de la misma lista Implementación Metodología de la Programación. Curso 2002/03. Pág. 71 NIVEL DE UTILIZACIÓN • Estructura muy utilizada. • Ejemplo: Manejo de tablas hash con el método de encadenamiento para el tratamiento de sinónimos. – Utilizaríamos un array de listas como tabla hash. (Lo que en el primer tema se llamó Encadenamiento) – Las listas tienen como elementos cadenas de caracteres. Metodología de la Programación. Curso 2002/03. Pág. 72 Modulo Mhash DEFINICIÓN DESDE MLista IMPORTA Tlista CONSTANTES MAXCAD ← 20 MAXELE ← 100 TIPOS TCadena = TElemento = TRango = TTablaHash= ARRAY [0..MAXCAD-1] DE CARÁCTER TCadena [0.. MAXELE-1] ARRAY TRango DE TLista PROC Almacenamiento(↓↑tabla:TTablaHash; ↓dato:TElemento) FUNC Búsqueda(↓tabla:TTablaHash; ↓dato:TElemento):LÓGICO PROC Eliminación(↓↑tabla:TTablaHash; ↓dato:TElemento) Metodología de la Programación. Curso 2002/03. Pág. 73 IMPLEMENTACIÓN PROC Almacenamiento(↓↑tabla:TTablaHash; ↓dato:TElemento) INICIO Insertar(tabla[Hash(dato)],dato) FIN FUNC Búsqueda(↓tabla:TTablaHash; ↓dato:TElemento):LÓGICO INICIO RESULTADO ← Buscar(tabla[Hash(dato)],dato) FIN PROC Eliminación(↓↑tabla:TTablaHash; ↓dato:TElemento) INICIO Eliminar(tabla[Hash(dato)],dato) FIN Fin /* Mhash */ Metodología de la Programación. Curso 2002/03. Pág. 74 • Definición: es un conjunto finito de elementos que está vacío o está partido en tres subconjuntos disjuntos. – El primer subconjunto contiene un único elemento llamado la raíz del árbol binario. – Los otros dos subconjuntos son a su vez árboles binarios, llamados subárboles izquierdo y derecho. derecho • El subárbol izquierdo o derecho puede estar vacío. • Cada elemento de un árbol binario se denomina nodo. nodo Metodología de la Programación. Curso 2002/03. Pág. 75 • Un método convencional para representar gráficamente un árbol binario es: • Consta de 9 nodos. • A es el nodo raiz. A B • El subárbol izquierdo tiene como nodo raiz B. C • El subárbol derecho tiene C como raiz. E D G • La ausencia de ramas indica un árbol vacío. F H I Metodología de la Programación. Curso 2002/03. Pág. 76 • Si A es la raíz de un árbol binario y B es la raíz de su subárbol izquierdo o derecho, se dice que A es el padre de B y B es el hijo izquierdo o derecho de A. • Un nodo que no tiene hijos se denomina nodo hoja. hoja • Un nodo n1 es un antecesor de un nodo n2 (y n2 es un descendiente de n1) n1 si n1 es el padre de n2 o el padre de algún antecesor de n2. n2 • Un nodo n2 es un descendiente izquierdo de un nodo n1 si n2 es el hijo izquierdo de n1 o un descendiente del hijo izquierdo de n1. n1 Un descendiente derecho se puede definir de forma similar. • Dos nodos son hermanos si son los hijos izquierdo y derecho del mismo padre. Metodología de la Programación. Curso 2002/03. Pág. 77 • Árbol estrictamente binario: binario árbol binario en que cada nodo no-hoja tiene subárboles izquierdo y derecho no vacíos. • Nivel de un nodo en un árbol binario: binario La raíz tiene nivel 0, y el nivel de cualquier otro nodo en el árbol es uno más que el nivel de su padre. • Profundidad de un árbol binario: binario máximo nivel de cualquier hoja del árbol. la longitud del camino más largo desde la raiz hasta una hoja. • Árbol binario completo de profundidad d: árbol estrictamente binario con todas sus hojas con nivel d. Metodología de la Programación. Curso 2002/03. Pág. 78 Un árbol binario contiene m nodos en el nivel L. Contiene como máximo 2m nodos en el nivel L+1. Un árbol binario completo de profunfidad d contiene exactamente 2L nodos en cada nivel L, entre 0 y d Puede contener como máximo 2L nodos en el nivel L El número total de nodos en un árbol binario completo de profundidad d es: tn = 20 + 21 + 22 + ... + 2d = 2d+1 - 1 Metodología de la Programación. Curso 2002/03. Pág. 79 Árbol ternario: conjunto finito de elementos que está vacío o está partido en cuatro subconjuntos disjuntos. – El primer subconjunto contiene un único elemento llamado la raíz del árbol. – Los otros tres subconjuntos son a su vez árboles. Árbol n-ario: conjunto finito de elementos que está vacío o está partido en n+1 subconjuntos disjuntos. – El primer subconjunto contiene un único elemento llamado la raíz del árbol. – Los otros n subconjuntos son a su vez árboles. Metodología de la Programación. Curso 2002/03. Pág. 80 Operaciones sobre árboles: ¿Esta vacío? Crear árbol vacío Crear árbol dada su raíz, y sus hijos derecho e Izquierdo ¿Está lleno? Devolver el contenido del nodo raíz Devolver el subárbol derecho Devolver el subárbol derecho Destruir Metodología de la Programación. Curso 2002/03. Pág. 81 Módulo MArbolBin DEFINICIÓN Imp TIPOS TElemento = // Cualquier tipo de datos TArbolBin = PUNTERO A TNodoArbolBin TNodoArbolBin = REGISTRO dato : TElemento izq,der : TArbolBin FINREGISTRO lem e diná ntación mic a FUNC CrearArbolVacio():TArbolBin FUNC CrearArbol(↓raiz:TElemento;↓izq, ↓dch: TArbolBin ): TArbolBin FUNC ArbolVacio(↓arbol:TArbolBin):LÓGICO FUNC Info(↓arbol:TArbolBin):TElemento FUNC Izq(↓arbol:TArbolBin): TArbolBin FUNC Der(↓arbol: TArbolBin): TArbolBin PROC DestruirArbol(↓↑arbol: TArbolBin) Metodología de la Programación. Curso 2002/03. Pág. 82 IMPLEMENTACIÓN FUNC CrearArbolVacio():TArbolBin INICIO RESULTADO ← NULO FIN FUNC CrearArbol(↓raiz:TElemento;↓izq, ↓dch: TArbolBin ): TArbolBin VARIABLES arbol : TArbolBin INICIO arbol ← NUEVO(TNodoArbolBin) arbol^.dato ← raiz arbol^.izq ← izq arbol^.der ← dch RESULTADO ← arbol FIN Metodología de la Programación. Curso 2002/03. Pág. 83 FUNC ArbolVacio(↓arbol:TArbolBin):LÓGICO INICIO RESULTADO ← (arbol = NULO) FIN FUNC Info(↓arbol:TArbolBin):TElemento INICIO RESULTADO ← arbol^.dato FIN FUNC Izq(↓arbol:TArbolBin): TArbolBin INICIO RESULTADO ← arbol^.izq FIN FUNC Der(↓arbol: TArbolBin): TArbolBin INICIO RESULTADO ← arbol^.der FIN Metodología de la Programación. Curso 2002/03. Pág. 84 PROC DestruirArbol(↓↑arbol: TArbolBin) INICIO SI (¬ArbolVacio(arbol)) ENTONCES DestruirArbol(arbol^.der) DestruirArbol(arbol^.izq) ELIMINAR(arbol) FINSI FIN FIN // MArbolBin Metodología de la Programación. Curso 2002/03. Pág. 85 Módulo MArbolBinEstático DEFINICIÖN CONSTANTES VALOR_NULO ← 0 MAX ← 100 TIPOS Se deja propuesto como ejercicio la parte de implementación de los procedimientos y funciones de una implementación estática de un árbol binario TArbolBin = [0..MAX] Im TNodoArbolBin = REGISTRO ple dato : TElemento me e izq,der : TArbolBin stá ntaci tica ón FINREGISTRO FUNC CrearArbolVacio():TArbolBin FUNC CrearArbol(↓raiz:TElemento;↓izq, ↓dch: TArbolBin ): TArbolBin FUNC ArbolVacio(↓arbol:TArbolBin):LÓGICO FUNC Info(↓arbol:TArbolBin):TElemento FUNC Izq(↓arbol:TArbolBin): TArbolBin FUNC Der(↓arbol: TArbolBin): TArbolBin PROC DestruirArbol(↓↑arbol: TArbolBin) Metodología de la Programación. Curso 2002/03. Pág. 86 NIVEL DE UTILIZACIÓN • Estructura de datos muy útil cuando se deben tomar decisiones de "dos caminos” • Muy utilizado en aplicaciones relacionadas con expresiones aritméticas. * (12-3)*(4+1) Ejemplos: + 5 2 + - 5+2 12 3 4 1 Metodología de la Programación. Curso 2002/03. Pág. 87 Ejemplo: Diseñemos un algoritmo para evaluar una expresión aritmética que está almacenada en un árbol binario. Tipos TipoDecision = (Operador, Operando) TElemento = REGISTRO CASO contenido:TipoDecision SEA Operador: oper: CARÁCTER Operando: val: REAL FINCASO FINREGISTRO Metodología de la Programación. Curso 2002/03. Pág. 88 FUNC Eval(↓arbol:TArbolBin):REAL VARIABLES dato:TElemento; result: REAL INICIO dato ← Info(arbol) SI (dato.contenido = Operando) ENTONCES result ← dato.val EN OTRO CASO CASO dato.oper SEA '+': result ← Eval(Izq(arbol))+Eval(Der(arbol)) '-': result ← Eval(Izq(arbol))-Eval(Der(arbol)) '*': result ← Eval(Izq(arbol))*Eval(Der(arbol)) '/': result ← Eval(Izq(arbol))/Eval(Der(arbol)) FINCASO FINSI RESULTADO ← result Fin Metodología de la Programación. Curso 2002/03. Pág. 89 La estructura lista enlazada es lineal La estructura árbol ¿Búsqueda? ¿Búsqueda más eficiente? Siempre que los datos se distribuyan de forma adecuada Árbol binario de búsqueda Metodología de la Programación. Curso 2002/03. Pág. 90 • Definición: árbol binario en el que el subárbol izquierdo de cualquier nodo (si no está vacío) contiene valores menores que el que contiene dicho nodo, y el subárbol derecho (si no está vacío) contiene valores mayores. E Ejemplo: B A H D C I F G Metodología de la Programación. Curso 2002/03. Pág. 91 Operaciones: Crear Buscar Insertar Suprimir Imprimir Las definidas para un árbol binario general Metodología de la Programación. Curso 2002/03. Pág. 92 Módulo MABB Definición TIPOS TRecorrido = (InOrden,PreOrden,PostOrden) TClave = ENTERO TElemento = REGISTRO clave:TClave ......... FINREGISTRO TABB = PUNTERO A TNodoABB TNodoABB = REGISTRO izq,der:TABB elem:TElemento FINREGISTRO // Operaciones típicas de los árboles FUNC CrearABB():TABB FUNC FUNC FUNC FUNC PROC ABBVacio(↓arbol:TABB):LÓGICO InfoABB(↓arbol:TABB):TElemento IzqABB(↓arbol:TABB): TABB DerABB(↓arbol: TABB): TABB DestruirABB(↓↑arbol: TABB) Metodología de la Programación. Curso 2002/03. Pág. 93 // Operaciones Exclusivas de los árboles binarios de búsqueda PROC BuscarABB(↓arbol:TABB; ↓c:TClave; ↑dato:TElemento; ↑EnArbol:LÓGICO) PROC InsertarABB(↓↑arbol:TABB; ↓dato:TElemento) PROC SuprimirABB(↓↑arbol:TABB; ↓c:TClave) PROC ImprimirABB(↓arbol:TABB; ↓rec:TRecorrido) IMPLEMENTACIÓN FUNC CrearABB():TABB INICIO RESULTADO ← NULO FIN FUNC ABBVacio(↓arbol:TABB):LÓGICO INICIO RESULTADO ← (arbol = NULO) FIN FUNC InfoABB(↓arbol:TABB):TElemento INICIO RESULTADO ← arbol^.dato FIN Metodología de la Programación. Curso 2002/03. Pág. 94 FUNC IzqABB(↓arbol:TABB): TABB INICIO RESULTADO ← arbol^.izq FIN FUNC DerABB(↓arbol: TABB): TABB INICIO RESULTADO ← arbol^.der FIN PROC DestruirABB(↓↑arbol: TABB) INICIO DestruirABB(arbol^.izq) DestruirABB(arbol^.dch) ELIMINAR(arbol) FIN Metodología de la Programación. Curso 2002/03. Pág. 95 PROC BuscarABB(↓arbol:TABB; ↓c:TClave; ↑dato:TElemento; ↑EnArbol:LÓGICO) // Solución Iterativa VARIABLES ptrArbol: TABB ele:TElemento INICIO EnArbol ← FALSO ptrArbol ← arbol MIENTRAS ((¬ABBVacio(ptrArbol)) ∧ (¬EnArbol)) HACER ele = InfoABB(ptrArbol) SI (ele.clave = c) ENTONCES EnArbol ← CIERTO dato ← ele SINO SI (c < ele.clave) ENTONCES ptrArbol ← IzqABB(ptrArbol) EN OTRO CASO ptrArbol ← DechABB(ptrArbol) FINSI FINMIENTRAS FIN Metodología de la Programación. Curso 2002/03. Pág. 96 PROC BuscarABB(↓arbol:TABB; ↓c:TClave; ↑dato:TElemento; ↑EnArbol:LÓGICO) // Solución Recursiva VARIABLES ele:TElemento INICIO SI (ABBVacio(arbol)) ENTONCES EnArbol ← FALSO EN OTRO CASO ele = InfoABB(arbol) SI (ele.clave = c) ENTONCES EnArbol ← CIERTO dato ← ele SINO SI (c < ele.clave ) ENTONCES BuscarABB(IzqABB(arbol),c,dato,EnArbol) EN OTRO CASO BuscarABB(DechABB(arbol),c,dato,EnArbol) FINSI FINSI FIN Metodología de la Programación. Curso 2002/03. Pág. 97 Consideraciones acerca de la operación de inserción. A D B B A F C E Entrada: ABCDEFG C D G B E F Entrada: DBFACEG D A G C Los mismos datos, insertados en orden diferente, producirán árboles con formas o distribuciones de elementos muy distintas. G F E Entrada: BADCGFE Metodología de la Programación. Curso 2002/03. Pág. 98 PROC InsertarABB(↓↑arbol:TABB; ↓dato:TElemento) // Solución Iterativa VARIABLES nuevonodo,pav,pret:TABB clavenueva:Tclave ele:TElemento Inicio nuevonodo ← NUEVO(TNodoABB) nuevonodo^.izq ← NULO nuevonodo^.der ← NULO nuevonodo^.elem ← dato clavenueva ← dato.clave pav ← arbol // Puntero Avanzado pret ← NULO // Puntero Retrasado Metodología de la Programación. Curso 2002/03. Pág. 99 MIENTRAS (pav ≠ NULO) HACER pret ← pav ele = pav^.elem SI (clavenueva < ele.clave ) ENTONCES pav ← pav^.izq // Voy hacia el EN OTRO CASO pav ← pav^.dch // Voy hacia el FINSI FINMIENTRAS ele = pret^.elem SI (clavenueva < ele.clave ) ENTONCES pret ^.izq ← nuevonodo // Inserto en EN OTRO CASO pret ^.dch ← nuevonodo // Inserto en FINSI FIN hijo izquierdo hijo derecho el hijo izquierdo el hijo izquierdo Metodología de la Programación. Curso 2002/03. Pág. 100 PROC InsertarABB(↓↑arbol:TABB; ↓dato:TElemento) VARIABLES ele:TElemento ¿Por qué usamos arbol^.izq INICIO // Solución Recursiva y arbol^.dch en vez de SI (ABBVacio(arbol)) ENTONCES IzqABB(arbol) y arbol ← NUEVO(TNodoABB) DechABB(arbol)? arbol^.izq ← NULO arbol^.der ← NULO arbol^.elem ← dato EN OTRO CASO ele = InfoABB(arbol) SI (dato.clave < ele.clave) ENTONCES InsertarABB(arbol^.izq, dato) EN OTRO CASO InsertarABB(arbol^.dch, dato) FINSI FINSI FIN Metodología de la Programación. Curso 2002/03. Pág. 101 Consideraciones acerca de la operación de suprimir. • Pasos: 1) Encontrar el nodo a suprimir. Equivalente a Buscar 2) Eliminarlo del árbol. 3 casos padre de x ex-padre de x Caso 1 x Metodología de la Programación. Curso 2002/03. Pág. 102 ex-padre de x padre de x Caso 2 x ex-hijo de x hijo de x J J Q B B R L M N K P R L Z N K Eliminar Q P z Caso 3 M Metodología de la Programación. Curso 2002/03. Pág. 103 PROC SuprimirABB(↓↑arbol:TABB; ↓c:TClave) VARIABLES // Solución Iterativa pav,pret:TABB INICIO pav ← arbol pret ← NULO //Busco el elemento MIENTRAS (pav ≠ NULO) ∧ (pav^.elem.clave ≠ c) HACER pret ← pav SI (c < pav^.elem.clave) ENTONCES pav ← pav^.izq EN OTRO CASO pav ← pav^.der FINSI FINMIENTRAS SI (pav = NULO) ENTONCES // No hacer Nada, ya que no hay nada que borrar SINO SI (pav = arbol) ENTONCES // equivalente a: (pret = NULO) SuprimirNodo(arbol) SINO SI (pret^.izq = pav) ENTONCES SuprimirNodo(pret^.izq) EN OTRO CASO SuprimirNodo(pret^.der) FINSI FIN Metodología de la Programación. Curso 2002/03. Pág. 104 PROC SuprimirNodo(↓↑arbol:TABB) Variables // Solución Iterativa temp,ant:TABB Inicio 0 o 1 hijo temp ← arbol SI (arbol^.der = NULO) ENTONCES arbol ← arbol^.izq // Casos sin Hijos ó sin Hijo derecho SINO SI (arbol^.izq = NULO) ENTONCES arbol ← arbol^.der EN OTRO CASO temp ← arbol^.izq // Caso de Sólo Hijo derecho // Caso Hijos derecho y izquierdo 1 hijo // Busco el mayor hijo derecho del hijo izquierdo ant ← arbol MIENTRAS (temp^.der <> NULO) HACER anterior ← temp 2 hijos temp ← temp^.der FINMIENTRAS arbol^.elem ← temp^.elem SI (anterior = arbol) ENTONCES anterior^.izq ← temp^.izq EN OTRO CASO anterior^.der ← temp^.izq FINSI FINSI ELIMINAR(temp) FIN Metodología de la Programación. Curso 2002/03. Pág. 105 PROC SuprimirABB(↓↑arbol:TABB; ↓c:TClave) // Solución Recursiva VARIABLES ele:TElemento INICIO SI (ABBVacio(arbol)) ENTONCES // No hacer Nada, ya que no hay nada que borrar EN OTRO CASO ele = InfoABB(arbol) SI (ele.clave = c) ENTONCES SuprimirNodo(arbol) SINO SI (c < ele.clave ) ENTONCES SuprimirABB(arbol^.izq,c) EN OTRO CASO SuprimirABB(arbol^.dch,c) FINSI FINSI ¿Por qué usamos arbol^.izq FIN y arbol^.dch en vez de y en vez de IzqABB(arbol) y DechABB(arbol? Metodología de la Programación. Curso 2002/03. Pág. 106 PROC SuprimirNodo(↓↑arbol:TABB) // Solución Recursiva Variables temp:TABB ele :TElemento FUNC MayorHijoDerecho(↓arbol:TipoABBúsqueda):TElemento INICIO // Solución Recursiva SI (ABBVacio(DchABB(arbol))) ENTONCES RESULTADO ← InfoABB(arbol) EN OTRO CASO RESULTADO ← MayorHijoDerecho(DchABB(arbol)) FINSI FIN INICIO SI (arbol^.der = NULO) ENTONCES temp ← arbol arbol ← arbol^.izq// Casos sin Hijos ó sin Hijo derecho ELIMINAR(temp) SINO SI (arbol^.izq = NULO) ENTONCES temp ← arbol arbol ← arbol^.der// Caso de Sólo Hijo derecho ELIMINAR(temp) EN OTRO CASO // Caso Hijos derecho y izquierdo ele ← MayorHijoDerecho(IzqABB(arbol)) arbol^.elem ← ele SuprimirABB(arbol^.izq,ele.clave) FINSI FIN Metodología de la Programación. Curso 2002/03. Pág. 107 Consideraciones acerca de la operación de imprimir. • Recorrer un árbol es "visitar" todos sus nodos para llevar a cabo algún proceso como por ejemplo imprimir los elementos que contiene. • ¿Cómo imprimir los elementos de un árbol? ¿en qué orden?. Metodología de la Programación. Curso 2002/03. Pág. 108 • Para recorrer un árbol binario en general (de búsqueda o no), podemos hacerlo de tres formas distintas: a) Recorrido InOrden. 1) Recorrer el subárbol izquierdo en InOrden Pasos: 2) "Visitar" el valor del nodo raiz y procesarlo 3) Recorrer el subárbol derecho en InOrden b) Recorrido PreOrden. 1) "Visitar" el valor del nodo raiz y procesarlo Pasos: 2) Recorrer el subárbol izquierdo en PreOrden 3) Recorrer el subárbol derecho en PreOrden c) Recorrido PostOrden. 1) Recorrer el subárbol izquierdo en PostOrden Pasos: 2) Recorrer el subárbol derecho en PostOrden 3) "Visitar" el valor del nodo raiz y procesarlo Metodología de la Programación. Curso 2002/03. Pág. 109 PROC Imp_InOrden(↓arbol:TABB) INICIO SI (¬ABBVacio(arbol)) ENTONCES Imp_InOrden(IzqABB(arbol)) ImpNodo(InfoABB(arbol)) Imp_InOrden(DerABB(arbol)) FINSI FIN PROC Imp_PreOrden(↓arbol:TABB) INICIO SI (¬ABBVacio(arbol)) ENTONCES ImpNodo(InfoABB(arbol)) Imp_PreOrden(IzqABB(arbol)) Imp_PreOrden(DerABB(arbol)) FINSI FIN Metodología de la Programación. Curso 2002/03. Pág. 110 PROC Imp_PostOrden(↓arbol:TABB) INICIO SI (¬ABBVacio(arbol)) ENTONCES Imp_PostOrden(IzqABB(arbol)) Imp_PostOrden(DchABB(arbol)) ImpNodo(InfoABB(arbol)) FINSI Fin PROC ImprimirABB(↓arbol:TABB; ↓rec:TRecorrido) Inicio CASE rec SEA inorden: Imp_InOrden(arbol) preorden: Imp_PreOrden(arbol) postorden: Imp_PostOrden(arbol) FINCASO Fin Fin /* MArbolBinarioBusqueda */ Metodología de la Programación. Curso 2002/03. Pág. 111 Ejemplo: P S F Y B H R Z T G W • El recorrido InOrden mostraría: BFGHPRSTWYZ • El recorrido PreOrden: PFBHGSRYTWZ • El recorrido PostOrden: BGHFRWTZYSP Metodología de la Programación. Curso 2002/03. Pág. 112 Nivel de utilización • Aplicaciones en las que estén implicas operaciones de búsqueda de elementos • Ejemplo: Supongamos que deseamos implementar un diccionario inglés/español en que la búsqueda de la traducción de una palabra inglesa sea rápida. Para ello podemos usar un árbol binario de búsqueda en el que el tipo elemento sea un registro con la palabra en inglés (que será la clave) y la palabra en español. Metodología de la Programación. Curso 2002/03. Pág. 113 ALGORITMO Diccionario DESE MABB IMPORTA TABB, CrearABB, DestruirABB, BuscarABB, InsertarABB, SuprimirABB, ImprimirABB CONSTANTES MAXCAD = 20 TIPOS TCadena = ARRAY [0..MAXCAD-1] DE CARÁCTER TDic = TABB Tclave = TCadena TElemento = REGISTRO clave:TClave // Palabra inglés traducción: TCadena // Palabra Español FINREGISTRO Metodología de la Programación. Curso 2002/03. Pág. 114 PROC InsPalDic(↓↑d:Tdic; ↓pal: TElemento) INICIO InsertarABB(d,pal) FIN PROC BuscaPalDic(↓d:TDic; ↓inglés:TClave ; ↑pal: TElemento; ↑encontrado:LÓGICO) INICIO BuscarABB(d,inglés,pal,encontrado) FIN PROC BorrarPalDic(↓↑d:TDic; ↓inglés:TClave) INICIO SuprimirABB(d,inglés) FIN Metodología de la Programación. Curso 2002/03. Pág. 115 • [DALE89b] DALE, N y LILLY, S. C. Pascal y Estructuras de Datos. Segunda Edición. McGraw-Hill/Interamericana de España, 1989. • [JOYA00] JOYANES, L. Programación en C++. Algoritmos, estructuras de datos y objetos. McGraw Hill, 2000. • [SAVI00] SAVICH, W. Resolución de problemas con C++. Segunda Edición. Prentice Hall, 2000. • [STRO01] STROUSTRUP, B. El lenguaje de programación C++. Edición Especial, Adisson-Wesley, 2001. Metodología de la Programación. Curso 2002/03. Pág. 116