tipos abstractos de datos y algoritmos - ldc.usb.vemeza/ci-2616/guia1.pdf · de algoritmos, los...

197
Tipos Abstractos de Datos y Algoritmos Emely Arraiz Edelmira Pasarella Cristina Zoltan Dpto de Computaci¶ on y Tecnolog¶ ³a de la Informaci¶ on Universidad Sim¶ on Bol¶ ³var Caracas, Venezuela e-mail: arraiz,pasarella,[email protected] 16 de enero de 2002

Upload: lamthien

Post on 20-Sep-2018

225 views

Category:

Documents


0 download

TRANSCRIPT

Tipos Abstractos de Datos y Algoritmos

Emely ArraizEdelmira Pasarella

Cristina ZoltanDpto de Computaci¶on y Tecnolog¶³a

de la Informaci¶onUniversidad Sim¶on Bol¶³var

Caracas, Venezuelae-mail: arraiz,pasarella,[email protected]

16 de enero de 2002

2

¶Indice General

Prefacio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . i

1 Introducci¶on al An¶alisis de Algoritmos 11.1 Marco Conceptual . . . . . . . . . . . . . . . . . . . . . . . . 11.2 Crecimiento asint¶otico . . . . . . . . . . . . . . . . . . . . . . 2

1.2.1 Ejemplo 1 . . . . . . . . . . . . . . . . . . . . . . . . . 31.2.2 Ejemplo 2 . . . . . . . . . . . . . . . . . . . . . . . . . 51.2.3 Ejemplo 3 . . . . . . . . . . . . . . . . . . . . . . . . . 5

1.3 Algebra de O(g) . . . . . . . . . . . . . . . . . . . . . . . . . . 61.4 Complejidad de familias de algoritmos . . . . . . . . . . . . . 61.5 Resumen del cap¶³tulo 1 . . . . . . . . . . . . . . . . . . . . . . 91.6 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101.7 Bibliograf¶³a . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

2 Tipos Concretos de Datos 132.1 Marco Conceptual . . . . . . . . . . . . . . . . . . . . . . . . 132.2 La Noci¶on de Variable . . . . . . . . . . . . . . . . . . . . . . 13

2.2.1 Asignaci¶on . . . . . . . . . . . . . . . . . . . . . . . . . 142.3 Tipos Simples . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

2.3.1 Tipo Entero . . . . . . . . . . . . . . . . . . . . . . . . 152.3.2 Tipo Real . . . . . . . . . . . . . . . . . . . . . . . . . 162.3.3 Tipo L¶ogico o Boolean . . . . . . . . . . . . . . . . . . 172.3.4 Tipo Car¶acter . . . . . . . . . . . . . . . . . . . . . . . 17

2.4 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182.5 Tipos Estructurados . . . . . . . . . . . . . . . . . . . . . . . 19

2.5.1 Arreglos . . . . . . . . . . . . . . . . . . . . . . . . . . 192.5.2 Registros . . . . . . . . . . . . . . . . . . . . . . . . . . 202.5.3 Listas . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

2.6 Resumen del cap¶³tulo 2 . . . . . . . . . . . . . . . . . . . . . . 21

3

4

2.7 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222.8 Bibliograf¶³a . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

3 Tipos Abstractos de Datos (TAD). Representaciones 233.1 Marco Conceptual . . . . . . . . . . . . . . . . . . . . . . . . 233.2 Especi¯caci¶on de TADs . . . . . . . . . . . . . . . . . . . . . . 243.3 Sobre los TADs y sus Representaciones en el Computador . . . 31

3.3.1 Implementaci¶on del TAD Conjunto . . . . . . . . . . . 323.3.2 Representaci¶on Din¶amica . . . . . . . . . . . . . . . . . 35

3.4 Resumen del cap¶³tulo 3 . . . . . . . . . . . . . . . . . . . . . . 363.5 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 373.6 Bibliograf¶³a . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

4 TAD Secuencia. Especializaciones 454.1 Marco Conceptual . . . . . . . . . . . . . . . . . . . . . . . . 454.2 Especi¯caci¶on del TAD Secuencia . . . . . . . . . . . . . . . . 464.3 Implementaci¶on del TAD Secuencia . . . . . . . . . . . . . . . 50

4.3.1 Representaci¶on Est¶atica . . . . . . . . . . . . . . . . . 514.3.2 Representaci¶on Din¶amica . . . . . . . . . . . . . . . . . 52

4.4 Especializaci¶on del TAD Secuencia . . . . . . . . . . . . . . . 544.4.1 Especi¯caci¶on del TAD Pila . . . . . . . . . . . . . . . 544.4.2 Ejemplo de uso . . . . . . . . . . . . . . . . . . . . . . 564.4.3 Especi¯caci¶on del TAD Cola . . . . . . . . . . . . . . . 564.4.4 Ejemplo de uso: Invertir una cola . . . . . . . . . . . . 574.4.5 Ejemplo . . . . . . . . . . . . . . . . . . . . . . . . . . 584.4.6 Especi¯caci¶on del TAD Dipolo . . . . . . . . . . . . . . 61

4.5 Resumen del cap¶³tulo 4 . . . . . . . . . . . . . . . . . . . . . . 624.6 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 624.7 Bibliograf¶³a . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67

5 El problema de la B¶usqueda 695.1 Marco Conceptual . . . . . . . . . . . . . . . . . . . . . . . . 69

5.1.1 B¶usqueda Secuencial . . . . . . . . . . . . . . . . . . . 695.1.2 B¶usqueda Binaria . . . . . . . . . . . . . . . . . . . . . 715.1.3 An¶alisis del algoritmo de bisecci¶on . . . . . . . . . . . 73

5.2 Posici¶on de los Elementos . . . . . . . . . . . . . . . . . . . . 735.2.1 Posici¶on seg¶un la B¶usqueda Secuencial . . . . . . . . . 745.2.2 Posici¶on seg¶un la B¶usqueda Binaria . . . . . . . . . . . 75

5

5.3 Resumen del cap¶³tulo 5 . . . . . . . . . . . . . . . . . . . . . . 765.4 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 775.5 Bibliograf¶³a . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77

6 Ordenamiento de una Secuencia 796.1 Marco Conceptual . . . . . . . . . . . . . . . . . . . . . . . . 79

6.1.1 Estabilidad de los algoritmos de ordenamiento . . . . . 806.1.2 Ejemplo . . . . . . . . . . . . . . . . . . . . . . . . . . 81

6.2 M¶etodos de ordenamiento de Secuencias . . . . . . . . . . . . 826.2.1 por Selecci¶on . . . . . . . . . . . . . . . . . . . . . . 836.2.2 Ordenamiento por Inserci¶on . . . . . . . . . . . . . . . 856.2.3 Burbuja . . . . . . . . . . . . . . . . . . . . . . . . . . 876.2.4 HeapSort . . . . . . . . . . . . . . . . . . . . . . . . . 89

6.3 An¶alisis de los algoritmos presentados . . . . . . . . . . . . . . 916.3.1 An¶alisis de los M¶etodos de Ordenamiento sin Precon-

dicionamiento . . . . . . . . . . . . . . . . . . . . . . . 916.3.2 An¶alisis del HeapSort . . . . . . . . . . . . . . . . . . . 96

6.4 Otros algoritmos de ordenamiento . . . . . . . . . . . . . . . . 976.4.1 Merge Sort . . . . . . . . . . . . . . . . . . . . . . . . 976.4.2 Quick sort . . . . . . . . . . . . . . . . . . . . . . . . . 98

6.5 Resumen del cap¶³tulo 6 . . . . . . . . . . . . . . . . . . . . . . 996.6 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 996.7 Bibliograf¶³a . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102

7 TAD Diccionario 1057.1 Marco Conceptual . . . . . . . . . . . . . . . . . . . . . . . . 1057.2 Especi¯caci¶on del TAD Diccionario . . . . . . . . . . . . . . . 1077.3 Representaci¶on Mediante Tablas de Hash . . . . . . . . . . . 108

7.3.1 Hashing Abierto . . . . . . . . . . . . . . . . . . . . . . 1097.3.2 Hashing Cerrado . . . . . . . . . . . . . . . . . . . . . 111

7.4 Res¶umen del cap¶³tulo 7 . . . . . . . . . . . . . . . . . . . . . . 1137.5 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1147.6 Bibliograf¶³a . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117

8 ¶Arboles 1198.1 Marco Conceptual . . . . . . . . . . . . . . . . . . . . . . . . 1198.2 Especi¯caci¶on del TAD Arbol (¶Arboles Ordenados) . . . . . . 122

8.2.1 ¶Arboles Ordenados . . . . . . . . . . . . . . . . . . . . 122

6

8.2.2 Conceptos de ¶arboles . . . . . . . . . . . . . . . . . . . 1248.3 Recorrido en ¶Arboles . . . . . . . . . . . . . . . . . . . . . . . 124

8.3.1 Recorrido en Preorden . . . . . . . . . . . . . . . . . . 1268.3.2 Recorrido en Postorden . . . . . . . . . . . . . . . . . . 1278.3.3 Recorrido en Inorden . . . . . . . . . . . . . . . . . . . 127

8.4 ¶Arboles Binarios . . . . . . . . . . . . . . . . . . . . . . . . . 1288.4.1 ¶Arboles Binarios de B¶usqueda . . . . . . . . . . . . . . 1308.4.2 ¶Arboles Equilibrados . . . . . . . . . . . . . . . . . . . 133

8.5 Otros ¶arboles . . . . . . . . . . . . . . . . . . . . . . . . . . . 1408.6 Res¶umen del cap¶³tulo 8 . . . . . . . . . . . . . . . . . . . . . . 1408.7 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1418.8 Bibliograf¶³a . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143

A Implementaci¶on 145A.1 Conjunto Est¶atico . . . . . . . . . . . . . . . . . . . . . . . . . 145A.2 Conjunto Din¶amico . . . . . . . . . . . . . . . . . . . . . . . . 150A.3 Secuencia Est¶atica . . . . . . . . . . . . . . . . . . . . . . . . 153A.4 Secuencia Din¶amica . . . . . . . . . . . . . . . . . . . . . . . . 155A.5 Pila Est¶atica . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158A.6 Pila Din¶amica . . . . . . . . . . . . . . . . . . . . . . . . . . . 160A.7 Cola Est¶atica . . . . . . . . . . . . . . . . . . . . . . . . . . . 163A.8 Cola Din¶amica . . . . . . . . . . . . . . . . . . . . . . . . . . 165A.9 ¶Arbol Binario . . . . . . . . . . . . . . . . . . . . . . . . . . . 167A.10 ¶Arbol de B¶usqueda . . . . . . . . . . . . . . . . . . . . . . . . 170A.11 ¶Arbol AVL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172

B Estructuraci¶on de los Tipos Abstractos de Datos 177

C ¶Indice de materias 181

¶Indice de Figuras

1.2 Algoritmo de ordenamiento . . . . . . . . . . . . . . . . . . . 7

8.1 Organigrama . . . . . . . . . . . . . . . . . . . . . . . . . . . 1208.2 ¶arbol geneal¶ogico . . . . . . . . . . . . . . . . . . . . . . . . . 1218.3 ¶arbol de altura 2 . . . . . . . . . . . . . . . . . . . . . . . . . 1258.4 ¶Arbol AVL de 5 elementos . . . . . . . . . . . . . . . . . . . . 1348.5 ¶Arbol AVL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1368.6 ¶Arbol de la ¯g. 8.5 luego de la inserci¶on . . . . . . . . . . . . 1368.7 Desbalanceo en ¶arbol izquierdo del ¶arbol izquierdo . . . . . . . 1388.8 Resultado de balancear el ¶arbol de la ¯gura 8.7 . . . . . . . . 1388.9 Caso II . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1388.10 Balanceo Usando el axioma II . . . . . . . . . . . . . . . . . . 1388.11 Desbalanceo en ¶arbol derecho del ¶arbol izquierdo . . . . . . . 1398.12 Resultado de balancear el ¶arbol de la ¯gura 8.11 . . . . . . . . 1398.13 Caso ID . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1398.14 Balanceo Usando el axioma ID . . . . . . . . . . . . . . . . . . 139

A.1 Arreglo de elementos con repetici¶on . . . . . . . . . . . . . . . 147A.2 Secuencia de elementos . . . . . . . . . . . . . . . . . . . . . 153A.3 Representaci¶on de la pila vac¶³a . . . . . . . . . . . . . . . . . . 160A.4 Agregando un NODO a la PILA . . . . . . . . . . . . . . . . . 162A.5 Eliminando el elemento TOPE . . . . . . . . . . . . . . . . . . 162A.6 Cola din¶amica . . . . . . . . . . . . . . . . . . . . . . . . . . . 165A.7 Sumar un elemento a la Cola . . . . . . . . . . . . . . . . . . . 167A.8 Remueve un elemento del frente . . . . . . . . . . . . . . . . . 167

B.1 Relaciones entre los TDA . . . . . . . . . . . . . . . . . . . . . 178B.2 ¶Arboles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179

7

8

¶Indice de Tablas

1.1 Algunas funciones y sus valores . . . . . . . . . . . . . . . . . 9

2.1 ENTEROS . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

7.1 Almacenamiento . . . . . . . . . . . . . . . . . . . . . . . . . 1107.2 Almacenamiento de valores . . . . . . . . . . . . . . . . . . . . 1127.3 Resultado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113

9

10

Prefacio

Alcance del libro

El tema central de este libro es algoritmia. El conocimiento de los algoritmoscl¶asicos que se utilizan para resolver problemas en forma mecanizada cons-tituye el coraz¶on de la disciplina, mitad arte y mitad tecnolog¶³a, llamadaInform¶atica. La algoritmia es un tema que si bien est¶a normalmente aso-ciado a los computadores, puede verse simplemente como una disciplina quese ocupa de conocer y poder comunicar en forma precisa y sin ambigÄuedadesmecanismos de soluci¶on de problemas.

Si bien el lenguaje de programaci¶on es el mecanismo de comunicaci¶onentre el hombre y la m¶aquina, existen principios y modelos que han perduradoen el proceso de describir al computador lo que debe ejecutar para resolverun problema dado.

La evoluci¶on de los lenguajes de programaci¶on iniciaron su existenciaapegados al computador mismo (lenguajes ensambladores) y fueron evolu-cionando hasta llegar a la categor¶³a de lenguajes portables, independientesdel computador que ejecutar¶a el algoritmo a tal punto que podremos asegurartener los mismos resultados independientemente del hardware utilizado.

En la primera etapa, se debi¶o traducir el problema a resolver a la es-tructura del computador que lo resolver¶³a. En la actualidad, se modelan losproblemas, se modelan las soluciones y es posible en base a esos modelosexpresar soluciones en el lenguaje de programaci¶on. En este proceso de ex-presar las soluciones se ha sentido la necesidad de disponer de bibliotecasy el elemento principal de las bibliotecas es tener mecanismos para asistiral lector a encontrar lo que busca en la biblioteca. La expresi¶on de la so-luci¶on no es ¶unica, podemos hablar de familias de soluciones de un mismoproblema, donde los diferentes miembros de la familia poseen caracter¶³sticasque los hacen mas o menos aptos para la soluci¶on del problema particular

i

ii

que se esta tratando de mecanizar, aptitud que depender¶a de consideracionesambientales. Es en este punto donde se evidencia la necesidad de conoceren forma precisa los elementos (componentes de software), y con ese conoci-miento poder elegir correctamente a ¯n de realizar la implementaci¶on de lasoluci¶on al problema que nos ocupa.

Este libro se ocupa de presentar los elementos b¶asicos de la descripci¶onde algoritmos, los Tipos Abastractos de Datos (TAD), las propiedades ent¶erminos de su e¯ciencia para ser usados como la materia prima en la soluci¶onde problemas.

Uso del libro

Este libro est¶a destinado principalmente a estudiantes de Computaci¶on queposean algun conocimiento instrumental de un lenguaje de programaci¶on.Un curso usando este libro como texto, debe estar acompa~nado de un talleren que los estudiantes realicen tareas con implementaciones de los tipos abs-tractos de¯nidos (TAD)1.

El libro presenta un cat¶alogo de tipos abstractos, relacionandolos entreellos 2. Los TAD se presentan de manera precisa haciendo uso de axiomas quedescriben sus propiedades. Este libro cubre solamente parte de los modelosimportantes dejando el modelo de grafos como material para un siguientecurso.

Las recetas de cocina han sido usadas innumerables veces como contraejemplo de algoritmo. No es que lo sean en absoluto, solamente que en laliteratura culinaria se parte de un cierto conocimiento b¶asico com¶un. Todaslas personas que ingresan a la cocina por primera vez, provistas de un librode cocina, con la certeza de poder realizar un plato suculento id¶entico aaquel que estan observando en la fotograf¶³a, suelen fracasar. En general loserrores se deben a la interpretaci¶on de frases tales como Agregar un pizcade sal, o derrita 250 gramos de chocolate que son sumamente ambigÄuas yaque ni la sal ni el chocolate son id¶enticos en todos los lugares del mundo, sinmencionar la interpretaci¶on de pizca. El cocinero profesional interpreta masacertadamente las frases de una receta, sin embargo la prueba varias vecesantes de ofrecerla en una comida.

1Gu¶³a de taller de algoritmos y estructuras II, Reporte CI-1995-003, Pasarella et al.Dpto Computaci¶on y tecnolog¶³a de la informaci¶on Universidad Sim¶on Bol¶³var, Caracas

2En el Ap¶endice B se da un esquema de esas relaciones

Prefacio iii

Los ingredientes del computista son sus tipos (abstractos o concretos),objetos con los que modela la realidad, y el algoritmo es el equivalente de lareceta del cocinero, pero una receta de ¶³ndole industrial: debe ser totalmentelibre de ambigÄuedades que permita asegurar que el producto ¯nal tenga e-xactamente las propiedades que espera el consumidor. En la elaboraci¶on deun producto alimenticio industrial no hay lugar a frases del tipo Hoy result¶oun poco salado.

Los tipos constituyen los bloque b¶asicos, que deben conocerse a cabali-dad, de manera de poder hacer uso de ellos con exacto conocimiento de susfortalezas y debilidades.

El libro inicia con el Cap¶³tulo 1 donde se presenta una introducci¶on b¶asicaa los modelos de an¶alisis de algoritmos que ayudar¶an a hacer un estudiosistem¶atico de los algoritmos presentados en el resto del libro. Cuando serealiza un desarrollo se debe conocer el comportamiento de cada uno de loscomponentes del mismo. Este conocimiento permitir¶a hacer optimizacionesen los puntos que resulten cr¶³ticos.

En el Cap¶³tulo 2 se revisan los Tipos Concretos de Datos, que corres-ponden a los tipos de datos (objetos b¶asicos) que suelen tener los lenguajesde programaci¶on, correspondiendo a los bloques mas elementales de los tiposde datos. Estos tipos concretos, var¶³an entre los lenguajes de programaci¶on,sin embargo est¶an presentes de una u otra forma en todos los lenguajes.

Los tipos mas elaborados, suelen ser de¯nidos para la aplicaci¶on parti-cular. En los lenguajes actuales, est¶an representados por las librer¶³as, quesuelen ser librer¶³as orientadas al tipo de problema que se est¶a resolviendocomo librer¶³as de ¯nanzas, librer¶³as de juegos instruccionales, librer¶³as depresentaciones.

En el cap¶³tulo 3 se introducen la forma en que ser¶an presentados los tiposabstractos en el libro usando como ejemplo el tipo conjunto y multiconjuntocomo una variante del primero haciendo el enlace a las implementaciones delos TAD usando tipos concretos.

En el cap¶³tulo 4 se introducen un re¯namiento del TAD multiconjun-to, donde se organiza el conjunto asignando puestos a los elementos que loconstituyen.

En los Cap¶³tulos 5 y 6 se estudian dos problemas para los cuales el com-putador ha resultado muy e¯ciente: la b¶usqueda y el ordenamieto.

En los Cap¶³tulos 7 y 8 se presentan TAD mas elaborados que estan enfo-cados principalmente a algoritmos mas e¯cientes de b¶usqueda.

El ap¶endice A recoge ejemplos de las implementaciones de algunos tipos,

iv

mientras que el ap¶endice B recoge la descripci¶on de las relaciones que existenentre los tipos abstractos revisados en este libro.

Para cada TAD, revisa una variedad de problemas que pueden resolversefacilmente usando el TAD, analizando los comportamientos de las solucio-nes, estableciendo cotas de e¯ciencia derivadas de la estrategia de soluci¶ony analizando el comportamiento de cada algoritmo de acuerdo a las im-plementaciones de los tipos abstractos. Cada cap¶³tulo incluye ejercicios ybibliograf¶³a.

AgradecimientosEl agradecimiento va principalmente a los estudiantes de Ingenier¶³a de Com-putaci¶on que cursaron Algoritmos y Estructuras II durante varios a~nos enla Universidad Sim¶on Bol¶³var usando notas y fotocopias de fotocopias. Elagradecimiento va para la Coordinaci¶on de Ingenier¶³a de la Computaci¶on yal Departamento de Computaci¶on y Tecnolog¶³a de la Informaci¶on de la Uni-versidad Sim¶on Bol¶³var que nos di¶o la oportunidad de dictar la asignaturapese a la oposici¶on de parte del profesorado. El tiempo hizo su trabajo.

Finalmente la gracias van para Donald Knuth y Leslie Lamport por haberpuesto a LATEX en manos de la gente. Gracias.

Cap¶³tulo 1

Introducci¶on al An¶alisis deAlgoritmos

1.1 Marco Conceptual

Dado que en general un problema que se desea resolver mediante el uso delcomputador tiene una colecci¶on de algoritmos que lo resuelven, es convenienteconocer el costo de cada uno de ellos y su comportamiento frente al conjuntode datos para seleccionar el algoritmo m¶as apropiado al problema que seest¶e resolviendo. El conocimiento de familias de algoritmos que resuelven unmismo problema nos permite hacer la selecci¶on adecuada.

La evaluaci¶on del costo de un algoritmo se hace calculando cu¶anto demora(tiempo de ejecuci¶on) y/o cu¶anto espacio requiere. Seg¶un el problema aresolver, el costo depender¶a de las caracter¶³sticas de los datos de entrada.

Muy frecuentemente, cuando se escribe un programa para resolver unproblema, se hace con la intenci¶on de que ¶este sea utilizado muchas veces,por lo que resulta conveniente caracterizarlo seg¶un su tiempo de ejecuci¶ony la calidad de la respuesta. Cuando estudiamos algoritmos es muy impor-tante caracterizar la soluci¶on que se obtiene de cada algoritmo a ¯n de estarseguros que dos algoritmos son equivalentes (para un mismo valor de entradadan exactamente el mismo resultado) o son similares (pueden dar resultadosdiferentes, pero desde el punto de vista del problema que estamos resolviendosomos indiferentes a cualquiera de los resultados). Por esta raz¶on uno de loscriterios m¶as importantes para seleccionar un programa es evaluar el tiempoque demora en ejecutarse, que de ahora en adelante llamaremos costo del

1

2

programa. Para analizar el costo de un algoritmo, adoptaremos un modelocomputacional, que nos dice cual de los recursos usados por la implemen-taci¶on del algoritmo son importantes para su desempe~no. La complejidadde un algoritmo bajo un modelo computacional es la cantidad de recursosen tiempo o espacio, que la implementaci¶on del algoritmo usa para resolverel problema dado. Por ejemplo en el algoritmo para hallar la potencia deun n¶umero, usando multiplicaciones, la cantidad de multiplicaciones es elrecurso utilizado. El esquema del algoritmo es:

x0 = 1

xk = x ¤ x(k¡1) ; k > 0

Vemos que el n¶umero de multiplicaciones que deba realizar el algoritmo est¶arelacionado con k, y dependiendo de la implementaci¶on que se haga del mismohar¶a k o k ¡ 1 multiplicaciones.

Veamos 2 implementaciones de la funci¶on Y = Xk

If K = 0 then Y:=1else

beginY:=1for i = 1 to KY:=Y * X

endfin

If K = 0 then Y:=1else

beginY:=Xfor i = 2 to K

Y:=Y * Xend

fin

1.2 Crecimiento asint¶otico

En general un algoritmo ser¶a utilizado repetidas veces y el tiempo que demoredepender¶a del computador en que se ejecute pero tambi¶en de una medida deltama~no de los datos. En el ejemplo anterior de la potencia el tama~no quenos interesa es el valor de la potencia y no suele tener importancia el valordel n¶umero que estamos elevando a la potencia. Otro ejemplo de tama~nodel problema, puede ser el encontrar el titular de una tarjeta de d¶ebito. Eltiempo requerido puede depender del n¶umero total de tarjeta-habientes.

An¶alisis de Algoritmos 3

Para analizar un algoritmo y calcular su costo, se consideran los siguientescasos:

Peor caso: Los casos de datos de entrada que hacen demorar m¶as al algo-ritmo.

Mejor caso: Los casos de datos de entrada que hacer ejecutar m¶as r¶api-damente al algoritmo.

Caso Promedio: En esta medida tomamos en cuenta una posible distri-buci¶on de los datos de entrada.

Debe notarse que en el primer (segundo) caso se caracterizan los datosde entrada que hacen demorar m¶as (menos) al algoritmo considerado. Eltercer caso se basa en hip¶otesis sobre la distribuci¶on estad¶³stica del conjuntode todos los valores de entrada que puedan ser ingresados al algoritmo. Enel ejemplo del c¶alculo de la potencia de un n¶umero los 3 casos son iguales yaque para valores de entrada x ; k los 2 algoritmos hacen respectivamente k yk ¡ 1 multiplicaciones.

1.2.1 Ejemplo 1Veamos un algoritmo para buscar un cierto valor en un conjunto y haremosel an¶alisis del mismo para los diversos tipos de entrada.

BUSCAR ( dado un vector V de N elementos, busca si el elemento X estao no en el vector)

1.esta =`no'2. I = 13. while I <= N and (esta =`no')3.1 if V[I] = X

then esta :=`'else I := I + 1

4. write(`valor de', X, esta, ` fue encontrado')5. fin

Observando el algoritmo vemos que el menor trabajo (menor ejecuci¶on deoperaciones) lo realizar¶a cuando ingrese el menor n¶umero de veces al while dela l¶³nea 3, independientemente del valor de N. Vemos que esto suceder¶a si la

4

primera vez que veri¯ca la condici¶on en la l¶³nea 3.1 esta resulta verdadera, conlo cual el mejor caso para este algoritmo es que el valor buscado se encuentreen la primera posici¶on del vector. Para este caso el algoritmo realiza unacantidad constante de operaciones (no depende de N).

Por analog¶³a podemos ver que el peor caso es que ingrese N veces a laiteraci¶on, y en el ¶ultimo ingreso la condici¶on de la l¶³nea 3.1 sea verdadera. Esosigni¯ca que los valores que hacen que el algoritmo realice la mayor cantidadde trabajo es un vector en el cual el valor buscado esta en la ¶ultima posici¶on.Para este caso el algoritmo realiza una cantidad de operaciones proporcionalal tama~no del vector (c*N).

Para hacer el an¶alisis del caso promedio usaremos la hip¶otesis que cual-quier vector tiene la misma posibilidad que cualquier otro. Nos pregunta-remos cu¶antos vectores distinguibles podemos tener. En un vector de Nposiciones el valor buscado puede estar en cualquiera de ellas o no estar. Porlo tanto debemos considerar N+1 casos. Para los casos en que el elementobuscado est¶a, el trabajo realizado es proporcional a la posici¶on donde se en-cuentra el elemento, y para el caso en que no se encuentra es pr¶acticamenteigual al caso de encontrarse en el ¶ultimo puesto. Por lo tanto sumaremosla funci¶on que describe el comportamiento en cada uno de los casos y lodividiremos por el n¶umero total de casos.

(§Ni=1c ¤ i+ c ¤N )=(N + 1) = c ¤N(N + 3)=(2 ¤ (N + 1))

A trav¶es de las medidas tenemos informaci¶on sobre el comportamientoesperado de un algoritmo, dependiendo de la entrada. Lo que debemos plan-tearnos cuando queremos desarrollar una aplicaci¶on particular, es identi¯carun algoritmo e¯ciente en tiempo de ejecuci¶on, por lo que requerimos conocerel per¯l de los datos de entrada. Este proceso de selecci¶on tambi¶en implicaconocer una variedad de algoritmos que resuelvan el problema dado.

Hasta ahora hemos hablado de conjuntos de algoritmos que resuelven unmismo problema. Ahora usaremos otro criterio de organizar conjunto dealgoritmos: pertenecer a una misma clase de complejidad.

De¯nici¶on: f es O(g). Sean f; g dos funciones con dominio en los natu-rales (correspondiente al tama~no de la entrada) diremos que \f es O(g)" (que se lee f es de orden g) o \f = O(g)00 (f es orden g) si existen constantespositivas c y n0 tal que f(n) · c ¤ g(n) para todo n ¸ n0.

An¶alisis de Algoritmos 5

De¯nici¶on: f es £(g) De¯nimos el conjunto de funciones £(g) (conjuntode funciones del mismo orden o de igual complejidad) como todas aquellasfunciones f tales que f = O(g) y g = O(f ).

De¯nici¶on alterna: Dos funciones f y g son del mismo orden si

limn!1(f (n)=g(n)) = c

para c > 0.

1.2.2 Ejemplo 2En el ejemplo del c¶alculo de la potencia, los dos algoritmos son de igualcomplejidad. Sea f la funci¶on de complejidad para uno de ellos y g la funci¶onde complejidad del otro. Del an¶alisis resulta que:

f(k) = k

g(k) = k ¡ 1

por lo que limk!1(f (k)=g(k)) = limk!1kk¡1 = 1 siendo c = 1 y c > 0.

1.2.3 Ejemplo 3Para el caso de la b¶usqueda de un elemento en un vector, vimos que el casopromedio result¶o la expresi¶on c ¤N(N + 3)=(2 ¤ (N + 1)), que es de orden N.Si considemos

f(N) = c ¤N(N + 3)=(2 ¤ (N + 1))

yg(N) = N

tendremos que

limk!1

((c ¤N (N + 3)=(2 ¤ (N + 1)))=N ) = limk!1

c2¤ N + 3N + 1

=c2

por lo que tenemos que la b¶usqueda de un elemento cualquiera en un vectorde N elementos es de O(N).

6

1.3 Algebra de O(g)

En general, por la forma de expresi¶on de los algoritmos, podemos calcular elcosto de una parte y luego utilizar el ¶agebra de ¶ordenes para el c¶alculo delorden de un algoritmo particular.

Podemos dar algunas reglas para el formalismo de O(g), reglas que sepueden derivar de la de¯nici¶on (y dejamos al lector su demostraci¶on) quepueden sernos ¶utiles en el estudio de crecimiento de ciertas funciones.

f (n) = O(f (n));c ¤O(f(n)) = O(f (n))O(O(f(n))) = O(f (n))

O(f(n)) ¤O(g(n)) = O(f(n) ¤ g(n))O(f (n) ¤ g(n)) = f(n) ¤O(g(n))

Otras ecuaciones ¶utiles son

np = O(nm); donde p · mO(f(n)) +O(g(n)) = O(j f (n) j) +O(j g(n) j)

1.4 Complejidad de familias de algoritmos

En lo que concierne a la complejidad, podemos atacar como problema en-contrar la complejidad de un algoritmo particular o encontrar cotas para lacomplejidad de una familia de algoritmos que resuelven un problema dado.En el primer caso, nuestro punto de partida es un algoritmo particular con-creto, mientras que en el segundo tomamos un problema y analizamos lafamilia de algoritmos que lo resuelven, pudiendo llegar a conclusiones talescomo:

Sea un computador de una cierta velocidad de c¶omputo v, para todoalgoritmo que resuelve el problema P, de tama~no n, el tiempo requeridopara su soluci¶on es mayor que n2. Veamos un ejemplo:

Es bien conocido el algoritmo de buscar el m¶aximo de una colecci¶on deelementos. Pero si nos planteamos buscar el m¶aximo de una colecci¶onde elementos que no est¶an estructurados entre ellos, sabemos que de-bemos revisarlos a todos para estar seguros que el elemento que demoses el m¶aximo de la colecci¶on. Entonces, si la colecci¶on es de tama~no n,

An¶alisis de Algoritmos 7

tendremos que revisarlos a todos antes de dar una respuesta, diremosque la funci¶on de costo f (n) = O(n).

En el ejemplo anterior vemos que pudiera haber algoritmos mejores siestructuramos los datos.

Veremos ahora el caso de los algoritmos de clasi¯caci¶on que utilizan comomodelo de computaci¶on las comparaciones (y los intercambios) para logrartener una presentaci¶on ordenada de N valores de entrada. En la ¯gura 1.2se muestra un algoritmo en el que se usan comparaciones entre los elementosx,y,z para decidir cu¶al permutaci¶on de estos elementos da una secuenciaordenada. En cada c¶³rculo se dan los pares de elementos que se comparany cada salida de las comparaciones est¶a etiquetada por el resultado de lacomparaci¶on. Finalmente, en los nodos sin salida se indica la permutaci¶onque corresponde a los elementos ordenados.

Figura 1.2: Algoritmo de ordenamiento

Supongamos inicialmente que todos los valores de entrada son diferentes.Por lo tanto, la variedad posible de entradas diferentes en cuanto al desorden

8

son todas las permutaciones de N elementos (N !), una sola de las cualesest¶a ordenada. Cada comparaci¶on tiene dos resultados posibles, por lo quedespu¶es de k comparaciones tendremos 2k resultados posibles. Para que estosresultados sean al menos el n¶umero de casos posibles deber¶a veri¯carse

2k ¸ (N !)

k ¸ lnN !

y por la f¶ormula de Stirling resulta que

k ¸ C ¤ (N lnN)

.Como vemos en el ejemplo anterior, cualquier algoritmo de clasi¯caci¶on

que use comparaciones para lograr su objetivo, necesariamente requerir¶a ha-cer un n¶umero de comparaciones mayor o igual que N lnN El alcance de estelibro se limita al estudio de problemas cuyos algoritmos tienen una comple-jidad dada por funciones del tipo Nk, llamadas funciones polinomiales. Untratamiento mas extenso puede encontrarse en la referencia bibliogr¶a¯ca 7.

La tabla 1.1 se muestra el n¶umero de operaciones requeridas seg¶un lafunci¶on de complejidad del algoritmo, indicada en las ¯las y el tama~no de laentrada, indicada en las columnas.

En particular existe una gran variedad de problemas para los que no seconoce algoritmos e¯cientes. Para ampliar la idea de la importancia de lae¯ciencia de los algoritmos elegidos para la soluci¶on de un problema con-sideraremos una aplicaci¶on desarrollada para un establecimiento peque~no,supongamos que manejan 10 art¶³culos. Esta aplicact¶on incluye un algoritmode O(n3) para un procesamiento de los 10 art¶³culos. El negocio crece, au-mentando el n¶umero de art¶³culos, y aspirando poder manejar 1.000.000 deart¶³culos. Suponiendo que el computador en que se realiza el procesamien-to requiere 1 nanosegundo (un millard¶esimo de segundo), para cada opera-ci¶on, el algoritmo de procesamiento de art¶³culos tardar¶³a aproximadamente32 a~nos.

An¶alisis de Algoritmos 9

10 50 100 300 10005N 50 250 500 1500 5000

N £ log2N 33 282 665 2469 9966N2 100 2500 10000 90000 1 mill¶on

(7 d¶³gitos)

N3 1000 125000 1 mill¶on 27 millones 1 millardo

(7 d¶³gitos) (8 d¶³gitos) (10 d¶³gitos)

2N 1024 un n¶umero un n¶umero un n¶umero un n¶umero

de 16 d¶³gitos de 31 d¶³gitos de 91 d¶³gitos de 302 d¶³gitos

N! 3.6 millones un n¶umero un n¶umero un n¶umero muy grande

de 7 d¶³gitos de 65 d¶³gitos de 161 d¶³gitos de 623 d¶³gitos

NN10 millardos un n¶umero un n¶umero un n¶umero muy grande

de 11 d¶³gitos de 85 d¶³gitos de 201d¶³gitos de 744 d¶³gitos

Tabla 1.1: Algunas funciones y sus valores

1.5 Resumen del cap¶³tulo 1En este cap¶³tulo hemos revisado los elementos que nos permiten evaluar elcosto de un cierto algoritmo. Es muy importante tener claro el costo de lasoperaciones que usamos para resolver mec¶anicamente un problema. Cuan-do se desarrolla una aplicaci¶on, los programadores parecen dividirse en dosactitudes extremas:

² \No debo preocuparme por la e¯ciencia de mi soluci¶on, ya que bastar¶aque se disponga de un computador su¯ciente potente para soportar estaaplicaci¶on".

² \Cada l¶³nea de c¶odigo debe ser revisada para optimizar el tiempo de laaplicaci¶on".

Infortunadamente ninguno de los dos extremos es saludable ya que lasmayor¶³a de las aplicaciones suelen obedecer a la regla del 90-10, que diceque el 90% del tiempo de ejecuci¶on se consume en el 10% del c¶odigo. Sien-do extremos, si optimizamos con el ¯n de reducir a la mitad el tiempo deejecuci¶on, sobre la parte del c¶odigo que corresponde al 10% de la ejecuci¶on,habremos tenido una ganancia neta del 5%, lo cual no parece efectivo dadoel costo invertido en la optimizaci¶on.

10

Si embargo el material de este cap¶³tulo nos permite saber cu¶ales procesosde complejidad alta deben tratar de excluirse de ese c¶odigo que se utiliza90% del tiempo de ejecuci¶on de la aplicaci¶on.

1.6 Ejercicios

1. Haga un algoritmo que encuentre al individuo m¶as alto del mundo ycalcule la complejidad del algoritmo obtenido.

2. Realice una implementaci¶on del problema de las torres de Hanoi, quereciba como par¶ametro el n¶umero de discos y que calcule el tiempodesde el inicio hasta el ¯n de la ejecuci¶on del algoritmo. Usando laimplementaci¶on realizada, haga una tabla de la funci¶on n¶umero dediscos, tiempo de ejecuci¶on.

3. Obtenga el orden de los tiempos de ejecuci¶on para el peor caso de lossiguientes procedimientos:

(a) procedure prod-mat(n:integer);var i,j,k: integer;begin

for i:=1 to n dofor j:=1 to n do begin

c[i,j]:=0;for k:=1 to n do

c[i,j]:= c[i,j]+a[i,k]*b[k,j]end

end;

(b) procedure misterio(n:integer);var i,j,k:integer;begin

for i:=1 to n-1 dfor j:= i+1 to n do

for k:=1 to j dop; /* p es O(1) */

end;

An¶alisis de Algoritmos 11

4. Ordene las siguientes funciones de acuerdo a su velocidad de crecimien-to:

(a) n

(b)pn

(c) logn

(d) log logn

(e) n log n

(f) (3=2)2

(g) nn

5. Agrupe la siguientes funciones de acuerdo a su complejidad:

(a) n2 + log(n)

(b) n!

(c) ln(n)

(d) log(n)

(e) n2

6. Muestre que las siguientes a¯rmaciones son verdaderas:

(a) 17 es O(1)

(b) n(n¡ 1)=2 es O(n2)

(c) max(n3; 10n2) es O(n3)(d)

nX

i=1ik

es O(nk+1) para k entero.

(e) Si P (x) es cualquier polinomio de grado k donde el coe¯ciente delt¶ermino de mayor grado es positivo, entonces la complejidad decalcular el polinomio en n es O(nk)

12

7. Para los siguientes pares de funciones de complejidad, correspondientesa los algoritmos A y B, respectivamente:

A BN2 100£N £ log2NN=2 4£ log2N

(a) Encontrar el m¶³nimo entero positivo para el cual el algoritmo Bes mejor que el algoritmo A. Justi¯que.

(b) Indique el orden para cada funci¶on de complejidad dada. Justi¯-que.

1.7 Bibliograf¶³a1. AHO, Alfred, HOPCROFT, John & ULLMAN, Je®rey. \Data Struc-

tures and Algorithms". Addison Wesley, 1985.

2. BAASE, Sara. \Computer Algorithms. Introduction to Design andAnalysis". Addison Wesley, 1978.

3. BINSTOCK, Andrew & REX, John. \Practical algoritms for Program-mers".Addison Wesley, 1995.

4. GRAHAM Ronald, KNUTH, Donald & PATASHNIK, Oren. \Concre-te Mathematics". Addison Wesley, 1989.

5. TREMBLAY, Jean-Paul & SORENSON, Paul. \ An Introduction toData Structures with Applications". 2nd. MacGraw Hill.

6. KALDEWAIJ, Anne. \Programming: The Derivation of Algorithms".Prentice Hall International Series in Computerr Science 1990.

7. BORODIN,A.B., MUNRO, I \Programming: The Derivation of Algo-rithms".American Elsevier, New York 1985.

Cap¶³tulo 2

Tipos Concretos de Datos

2.1 Marco ConceptualLos algoritmos generalmente manipulan datos, que poseen propiedades queson explotadas por esos algoritmos. Llamaremos tipo de datos a una clase dela cu¶al conocemos sus caracter¶³sticas y la forma de manipularla. En general,un tipo de datos consiste de un rango de valores y las operaciones que puedenrealizarse sobre ellos. Clasi¯caremos los tipos en Concretos y Abstractos.

Un tipo concreto es un tipo provisto por el lenguaje de programaci¶oncon que se implementa el algoritmo y de ellos hablaremos en la pr¶oximassecciones. Estos tipos, seg¶un los requerimientos de memoria para representarlos valores, se dividen en simples y estructurados. Los tipos abstractos dedatos, los de¯niremos en el siguiente cap¶³tulo.

2.2 La Noci¶on de Variable

Cuando resolvemos un problema algoritmicamente y pretendemos implemen-tar las soluci¶on en un computador, nos encontramos con la necesidad dealmacenar los datos que utiliza el algoritmo, por ejemplo, los datos de en-trada, de salida e intermedios (privados). Es por esto que surge la noci¶onde variable en computaci¶on como una caja donde se pueden almacenar da-tos. F¶³sicamente una variable corresponde a una o varias localidades de lamemoria del computador. Para referirnos a las variables en un algoritmo oprograma, podemos identi¯carlas con un nombre llamado identi¯cador oestar en capacidad de calcular el identi¯cador correspondiente. Durante la

13

14

ejecuci¶on de un programa, los datos almacenados en las variables correspon-den a los valores de las mismas.

Generalmente, para acceder al valor de una variable basta con nombrar-la por su identi¯cador. Este m¶etodo de acceso se llama acceso inmediato odirecto. Existen otros m¶etodos de acceso que mencionaremos en seccionesposteriores. El contenido (valor) de una variable puede cambiar potencial-mente en cada paso del algoritmo.

2.2.1 Asignaci¶on

La asignaci¶on es un operador binario que permite cambiar el valor de unavariable y frecuentemente 1 se denota como sigue:

v := Expresi¶on

La sem¶antica de la asignaci¶on es almacenar en la variable v el resultadode evaluar Expresi¶on. N¶otese que el argumento de la izquierda debe ser unavariable. Algunos ejemplos de asignaci¶on son los siguientes:

1. v := 2

2. v := x + y

3. v := sqr(a) - log(b)

4. v := v + 1

En una asignaci¶on las variables son interpretadas posicionalmente. Elvalor de la variable que ocurre a la izquierda del operador `:=' puede serdiferente antes y despu¶es de ejecutarse la asignaci¶on mientras que los valoresde las que ocurren a la derecha se mantienen iguales, s¶olo son leidos y usadospara calcular el valor que debe almacenarse en la variable de la izquierda.

Una variable desde el punto de vista computacional es diferente a unavariable en matem¶aticas donde representa un valor desconocido de un domi-nio en una expresi¶on. En computaci¶on una variable es un objeto que cambiade estado a trav¶es de la operaci¶on de asignaci¶on. Analicemos lo que hace la

1Historicamente se us¶o el operador = , luego a partir de ALGOL 60 := y JAVA usanuevamente el operador =, pero con un signi¯cado totalmente distinto.

Tipos Concretos de Datos 15

asignaci¶on del ¶ultimo ejemplo: lee el valor de v antes de ejecutarse la asigna-ci¶on, lo incrementa en uno y el resultado lo almacena en v. En matem¶aticasuna expresi¶on an¶aloga con la igualdad no tiene sentido.2

Dependiendo del lenguaje de implementaci¶on, el dominio de valores quepuede tomar una variable se ¯ja antes de la ejecuci¶on (de¯nici¶on est¶atica).Ese dominio de valores se denomina el tipo de la variable y en estos casoslas variables se clasi¯can seg¶un sus tipos . Tambi¶en es posible de¯nir el tipode una variable durante la ejecuci¶on (de¯nici¶on din¶amica) pero estos casosest¶an fuera del alcance de este libro. De ahora en adelante nos referiremos avariables con tipos de¯nidos est¶aticamente.

Para que una asignaci¶on est¶e bien de¯nida es necesario que la evaluaci¶onde la expresi¶on de la derecha d¶e un valor que pertenezca al tipo de la variablede la izquierda (consistencia de tipos).

2.3 Tipos SimplesLos tipos simples son aquellos cuyos valores s¶olo requieren una localidadde memoria.3 Una variable de un tipo simple corresponde exactamente auna localidad (casilla,direcci¶on) de memoria. Entre los tipos simples m¶asfrecuentes tenemos enteros, reales, l¶ogicos y caracteres.

2.3.1 Tipo EnteroEl tipo entero de¯ne un subconjunto de Z. Generalmente es un rango[¡maxent::maxent¡ 1], donde maxent es una constante tan grande como lopermita los mecanismos de direccioonamiento del computador. Los lenguajesde programaci¶on permiten, en general, manejar diversa variedad de enteros:2 bytes (16 bits), 4 bytes (32 bits), etc. Los valores correspondientes paramaxent se muestran en la tabla 2.1.4

Par este tipo se de¯nen los operadores

+ Suma2En particular esta expresi¶on se considera frecuente y diversos lenguaje han tratado de

darle sintaxis mas compactas: en el lenguaje C es v += 1 y en JAVA puede escribirse v++3Cuando nos referimos a localidad queremos expresar que su recuperaci¶on se hace

mediante una sola direcci¶on de memoria, independientemente del espacio que ocupe4Los lenguajes de programaci¶on tienden a independidarse de la estructura f¶³sica de los

computadores, buscando la portabilidad de las aplicaciones desarrolladas.

16

Tama~no de almacenamiento Maxent8 bits 12816 bits 3276832 bits 214748364864 bits 9223372036854775808

Tabla 2.1: ENTEROS

- Resta

* Multiplicaci¶on

div Divisi¶on Entera

mod Resto de una Divisi¶on Entera

Adem¶as en las especi¯caciones del lenguaje se establece un orden de evalua-ci¶on entre los operadores para evitar ambigÄuedades al evaluar expresionescomo:

2*3/1+2

cuyo resultado podr¶³a ser: 2, 8 o 10.

2.3.2 Tipo RealDado a que el tama~no de la memoria de un computador es ¯nito, el conjuntode reales que se puede representar tambi¶en es ¯nito. Para representar a losreales se utiliza lo que se conoce como representaci¶on de punto °otante en lacual cada n¶umero real r es representado como un par < e;m > siendo e y menteros tal que

r = m£Be ¡ E < e < E ¡M < m < M

5 donde m es la mantisa, e es el exponente, B es la base de la representaci¶onpunto °otante (en general se utiliza como base una potencia peque~na de 2)y E y M son constantes caracter¶³sticas de la representaci¶on que dependen

5Estas condiciones son aproximadas y dependen de la arquitectura particular del com-putador

Tipos Concretos de Datos 17

generalmente del hardware. Sin embargo se ha establecido un estandardllamado IEEE 754 para el tipo punto °otante.

El tipo real provee todos los operadores aritm¶eticos mencionados en lasecci¶on anterior pero hay que tener en consideraci¶on que debido a la represen-taci¶on dejan de cumplirse algunas propiedades aritm¶eticas conocidas. Estostipos num¶ericos suelen estar apegados a la arquitectura del computador.Los lenguajes de programaci¶on dejaban sus sem¶antica sin de¯nir, por lo queprogramas escritos en un mismo lenguaje pod¶³an tener una comportamientodiferente. 6

Par este tipo se de¯nen los operadores

+ Suma

- Resta

* Multiplicaci¶on

Divisi¶on

2.3.3 Tipo L¶ogico o BooleanLa variables del tipo l¶ogico pueden tomar valores de verdad true o false 7. Eltipo provee operaciones l¶ogicas b¶asicas, como por ejemplo:

and (^)

or (_)

not (:)

2.3.4 Tipo Car¶acterEste tipo de¯ne un conjunto ordenado de caracteres codi¯cados. Inicialmen-te los computadores usaron el c¶odigo ASCII (American Standard Code forInformation Interchange). Los caracteres ASCII se dividen en imprimiblesy no imprimibles. Originalmente eran 128 = 27 caracteres por lo que s¶olo

6Algol 68 de¯ne los tipos por primera vez y luego este detalle es olvidado para serretomado por JAVA.

7Algunos lenguajes permit¶³an una interpretaci¶on entera de estos valores. Esto da lugara errores de programaci¶on

18

se requer¶³a 7 bits para almacenar un car¶acter en memoria. Luego se us¶o latabla ASCII extendida, 256=28 caracteres, que requiere 8 bits. En la actua-lidad, dado que los software deben estar preparados para el manejo de variosidiomas, se utiliza el c¶odigo UNICODE que utiliza 16 bits para almacenarun car¶acter.

Los operadores que provee son los siguientes:

ord(c), que retorna el n¶umero que ocupa el car¶acter c en la tablaUNICODE

char(n), que retorna el car¶acter que ocupa la posici¶on n en la tablaUNICODE

succ(c), pred(c), sucesor y predecesor, respectivamente, del car¶acterc.

La posiciones de los caracteres en la tabla UNICODE establecen un ordenentre ellos.

2.4 Referencias

Las referencias son una familia de tipos cuyos valores nos permiten \referir-nos" a elementos de un determinado tipo. Es por eso que decimos que sonuna familia ya que podemos de¯nir referencias para cada uno de los tiposde¯nidos.

Dado que las referencias no poseen una aritm¶etica son pocas las opera-ciones que pueden realizarse con ellos8.

Los operadores que provee son los siguientes:

a := b la asignaci¶on de referencias de un mismo tipo

En la siguiente secci¶on se ver¶a otros operadores para las referencias 9

8Algunos lenguajes admiten una aritm¶etica para las referencias, sin embargo es unrecurso que puede introducir inestabilidad en los programas

9Este tipo de datos se introdujo en ciertos lenguajes argumentando que se pod¶³a lograrprogramas mas e¯cientes. En general su uso se convirti¶o en fuente de errores. JAVA utilizaeste concepto internamente y no es un tipo del lenguaje.

Tipos Concretos de Datos 19

2.5 Tipos EstructuradosLos tipos estructurados son aquellos cuyos valores poseen una estructurainterna y requieren m¶as de una casilla de memoria para su representaci¶on.

2.5.1 ArreglosLos arreglos constituyen un tipo estructurado, siendo una caracter¶³stica quetodos los elementos que los componen son del mismo tipo. Por lo que alde¯nir un arreglo deber¶a indicarse el tipo de los elementos que lo componen(tipo base): enteros, reales, referencias a reales, etc y el rango de enteros conlos que se identi¯car¶an los elementos que lo componen. Cuando el n¶umerode elementos es ¯jo se denominan arreglos est¶aticos y cuando este n¶umeropuede variar de denominan arreglos din¶amicos. El rango de valores es porlo tanto una n-tuplas (donde n es el numero de elementos del arreglo) deelementos tipo base.

Algunos ejemplos de tuplas son los siguientes:1. (2,3,9,0,12,32) un arreglo de seis componentes de enteros.

2. (2.7,67.5) un arreglo con dos componentes reales.

Otra caracter¶³stica de este tipo es el acceso directo a cada una de sus com-ponentes, denominadas elementos de un arreglo. La implementaci¶on de losarreglos en los lenguajes de programaci¶on se realiza en general reservandoleun bloque de memoria para su almacenamiento.

Si un arreglo ha sido de¯nido teniendo un rango de valores entre [i; j]; i ·j entonces 8k i < k < j el k-¶esimo elemento del arreglo estar¶a ubicado enmemoria entre el elemento k ¡ 1 y el elemento k + 1.

Los operadores que provee son los siguientes:A[i], que retorna el valor de la i-esima componente del arreglo, cuandoes usado en una expresi¶on. Esto permite usar todo los operadores deltipo base.

A[i] := expresion , que asigna el valor de la expresi¶on a la i-¶esimacomponente del arreglo.

Algunos lenguajes de programaci¶on asocian los arreglos a vectores y porextensi¶on a matrices de m¶as de una dimensi¶on y proveen las operacionesasociadas a esos tipos matem¶aticos: suma , multiplicaci¶on, producto escalar,producto vectorial, inversa de una matriz, etc.

20

2.5.2 RegistrosLos registros constituyen un tipo estructurado, que a diferencia de los arre-glos no requieren que sus componentes sean del mismo tipo. Otro elementoque lo caracteriza es que las componentes no se identi¯can por la posici¶oncomo en los arreglos, sino que se identi¯can por nombre y por lo tanto puedenno almacenarse en posiciones contiguas.

Un registro posee un nombre y cada componente a su vez tiene nombre.La variedad de valores puede asociarse a tuplas de pares ordenados, donde elprimer elemento de cada par es el identi¯cador de la componente y el segundosu valor.

Algunos ejemplos de tuplas son los siguientes:

1. ((nombre,J),(apellido,P), (c¶edula,12867456))registro que pudiera llamarse persona de tres componentes: nombreapellido y c¶edula.

2. ((peso,2.7),(altura,67.5),(identificador,e))registro con tres componentes, dos de ellas reales (peso y altura) y latercera de tipo car¶acter denominada identi¯cador.

Los operadores que provee son los siguientes:

persona.nombre, que retorna el valor de nombre del registro cuando esusado en una expresi¶on. Esto permite usar todo los operadores del tipobase.

persona.apellido := expresion , que asigna el valor de la expresi¶ona la componente apellido del registro persona.

2.5.3 ListasLas listas son tipos estructurados, pudiendo ser homogeneas (todos sus ele-mentos son del mismo tipo), o no homogeneas. Una caracter¶³stica de laslistas es que los elementos poseen referencias a elementos de la lista comoparte del elemento. En contraposici¶on a los arreglos, donde el operador paraacceder a un elemento ( o al siguiente en un recorrido) es ¯jo y asociado a laestructura de datos, en las listas un elemento posee como parte de s¶³ mismola referencia al siguiente. Es de hacer notar que esta noci¶on de siguiente noes ¶unica, puede haber varios siguientes.

Tipos Concretos de Datos 21

En un arreglo A de enteros, de una dimensi¶on, el elemento contiguo delelemento A[i] es el elemento A[i+1] , lo que corresponde a una ley constantede acceso al elemento siguiente. En las listas, se levanta esta rigidez haciendoque el elemento de la lista posee como parte de s¶³ mismo la referencia aun siguiente (o a varios siguientes). Siguiendo con la comparaci¶on con losarreglos, si un arreglo A ha sido de¯nido teniendo un rango de elementosentre [i; j], sabemos que el primer elemento de la estructura ser¶a A[i] y el¶ultimo A[j]. En las listas no hay direccionamiento directo a los elementosde la lista, deber¶a existir un mecanismo de acceso al primer elemento dela lista (generalmente conocida como la cabeza de la lista) y cada elementode la lista dir¶a cual es el siguiente. Deberemos disponer de un valor de lareferencia para indicarnos que no existe el siguiente (valor NIL) 10.

2.6 Resumen del cap¶³tulo 2

En este cap¶³tulo revisamos los tipos concretos que proveen los lenguajes deprogramaci¶on. Se debe tener presente que si bien los lenguajes parecen pro-veer los tipos b¶asicos que usamos en matem¶aticas, en realidad de lo que sedispone en los lenguajes es de un modelo ¯nito de los objetos in¯nitos talescomo los enteros y los reales. En particular, propiedades de los objetos ori-ginales no se conservan en estos modelos ¯nitos, propiedades tales como laasociatividad o la conmutatividad. Esto impone restricciones en el desarrollode las aplicaciones y no tenerlo en cuenta suele ser el origen de problemasen la etapa de validaci¶on de una aplicaci¶on. Una aplicaci¶on puede validar-se en un ambiente, pero con el tiempo puede haber variaciones que haganperder la validez de las hip¶otesis usadas en la validaci¶on. Como ejemplosde estos problemas podemos mencionar la aparici¶on de discos duros de grantama~no, el problema de Y2K, la in°aci¶on, etc. El factor com¶un de todosestos problemas es el modelo de datos utilizado.

10En particular JAVA no posee referencias y por lo tanto no puede manejar listas comose han presentado en esta secci¶on. Sin embargo si la estructura de lista se requiere paraalguna implementaci¶on particular siempre se pueden implementar usando arreglos y siendolas referencias posiciones dentro del mismo. Este esquema hace relocalizable los c¶odigos,mientras que con referencias no necesariamente lo son

22

2.7 Ejercicios1. Sea § un operador unario cuyo ¶unico operando es un arreglo. La in-

terpretaci¶on de este operador es tal que devuelve la suma de todos loselementos del arreglo. Utilice su lenguaje de programaci¶on favorito pa-ra demostrar que diferentes implementaciones de este operador puedendar resultados distintos al aplicarlo al mismo argumento. Comiencecon arreglos de reales, sabiendo que la operaci¶on de suma de reales esasociativa y conmutativa. Demuestre con sus implementaciones queestas propiedades no son v¶alidas en la suma de reales representables enel computador.

2. Realice al menos dos implementaciones del mismo operador para arre-glos de enteros y demuestre que la suma de enteros en el computadortampoco satisface la propiedad de asociatividad y conmutatividad.

3. Dado como par¶ametro la ubicaci¶on del primer elemento de un arreglode dos dimensiones, dise~ne el algoritmo para obtener la ubicaci¶on delelemento con sub¶³ndices i, j.

2.8 Bibliograf¶³a1. FLANAGAN, D. \Java in a nutshell". O'Reilly. Segunda edici¶on. pp

23-33. 1997

2. HAREL, D. \Algoritmics, The spirit of Computing". Addison Wesley.S, pp 36-37. 1997

Cap¶³tulo 3

Tipos Abstractos de Datos(TAD). Representaciones

3.1 Marco Conceptual

Supongamos que queremos resolver un problema bastante complejo desdeel punto de vista tanto de su funcionalidad como de la organizaci¶on de susdatos. Al tratar de dar una soluci¶on nos encontramos con que hay quecontrolar demasiados detalles y esto hace que la tarea sea realmente ardua.En estos casos, es conveniente reducir la complejidad o los detalles que van aser considerados a un mismo tiempo. Una manera de lograr esto es a trav¶esde un proceso de abstracci¶on: abstracci¶on procedural y abstracci¶on de datos.

La abstracci¶on procedural se re¯ere a la de¯nici¶on de funciones abstrac-tas (que se implementan como procedimientos) que separan el \qu¶e" hacela funci¶on del \c¶omo" lo hace. Una t¶ecnica usualemente usada para hacerabstracci¶on procedural es el re¯namiento paso a paso.

La abstracci¶on de datos, a diferencia de la procedural, permite la des-cripci¶on de objetos abstractos. Es decir, se establecen las clases de objetosdel problema, independiente de c¶omo estos objetos van a ser representados(obviando los detalles). Como producto de la abstracci¶on de datos se espe-ci¯can los nombres y los dominios de las operaciones asociadas a cada clasede objetos y se de¯nen los signi¯cados abstractos de las mismas.

Un Tipo Abstracto de Datos (TAD) corresponde a una clase deobjetos establecida en el proceso de abstracci¶on de datos y viene dado porsu especi¯caci¶on y una implementaci¶on que la satisfaga.

23

24

Cualquier aplicaci¶on que requiera utilizar TADs, puede hacerlo conocien-do solamente las especi¯caciones; es decir, no es necesario esperar hasta queel tipo est¶e totalmente implementado ni es necesario comprender las imple-mentaciones.

Para implementar un TAD se requiere que el lenguaje de implementaci¶onsoporte encapsulamiento, es decir, que brinde la posibidad de crear unidadesde programas donde se coloquen juntos la representaci¶on de los objetos y elc¶odigo asociado a cada operaci¶on. Adem¶as, debe soportar ocultamiento deinformaci¶on que se re¯ere a la posibidad de permitir el uso de los operacionessin que el usuario pueda ver la representaci¶on de los objetos ni el c¶odigo delas operaciones.

Hay muchos lenguajes de programaci¶on que soportan TADs (CLU , ALP-HARD, EUCLID, JAVA), sin embargo, es posible utilizar TADs como unat¶ecnica de programaci¶on cuando se programa con lenguajes como PASCALque no tienen el soporte adecuado para implementarlos.

Es conveniente hacer la especi¯caci¶on de un TAD utilizando un lenguajeformal. Esto nos libera de las ambigÄuedades propias del lenguaje natural.El lenguaje utilizado para hacer la descripci¶on de un TAD lo llamaremosformalismo para especi¯car TADs.

3.2 Especi¯caci¶on de TADsEn una especi¯caci¶on, las diversas partes que la componen contribuyen deforma diferente en la descripci¶on de una clase de objetos que pueden crearse,transformarse o descomponerse.

Un componente de una especi¯caci¶on de un TAD son los operadores,dando en la secci¶on titulada sintaxis la forma de escribirlos (la descrip-ci¶on de su sintaxis). Como son operadores, daremos cu¶al es el tipo de losoperandos y del resultado (dominio y rango). Ejm:

insertar : Multiconjunto£Elemento)Multiconjunto

donde insertar es el nombre del operador, y utilizando la notaci¶on defunciones, indicamos el producto cartesiano de los dominios de los operandos,seguido de una °echa ()) que separa el tipo del resultado que da el operador.

En el ejemplo que nos ocupa estamos indicando que insertar es un ope-rador binario, cuyo primer argumento es un multiconjunto y el segundo unelemento. El resultado de la operaci¶on es un multiconjunto. De igual manera

Tipos Abstractos de Datos 25

daremos la sintaxis de la operaci¶on coseno que transforma ¶angulos en realesen el intervalo [-1,1].

coseno : Angulo) [¡1; 1]

Paralelamente a la sintaxis de los operadores se da una de¯nici¶on de losmismos; esto lo haremos en la secci¶on titulada sem¶antica que est¶a consti-tu¶³da por un conjunto de proposiciones, en l¶ogica de primer orden, llamadasaxiomas.

Usualmente daremos algunas propiedades que nos permitan comprendery describir el signi¯cado del operador que estamos de¯niendo. En matem¶ati-cas, en ocasiones damos completamente la de¯nici¶on de una funci¶on (funci¶ontotal) y otras veces, se de¯ne parcialmente la funci¶on (funci¶on parcial). Porejemplo, si de¯nimos la funci¶on inversa sobre los racionalesQ con la siguientesintaxis:

inversa : Q ) Qpodemos expresar la sem¶antica como sigue:

8q(q 2 Q^ q6= 0! inversa(q) ¤ q = 1)

Hemos usado para de¯nir el operador inversa el operador de multipli-caci¶on de los racionales y la identidad de los mismos. Vemos que hemosde¯nido la funci¶on inversa parcialmente ya que no sabemos lo que pasa siq = 0. Debe notarse que esta de¯nici¶on no es constructiva ya que no nos daidea de c¶omo conseguir el valor que corresponde a inversa(q). Sin embar-go, cualquier implementaci¶on debe dar un resultado que veri¯que el axiomainversa(q) ¤ q = 1.

Para los ¯nes de de¯nir la sem¶antica de de las operaciones de un tipo, po-demos dejar inde¯nido el valor o completar la funci¶on con valores arbitrarioso convenientes a la implementaci¶on.

En las especi¯caciones presentadas en este libro veremos que con granfrecuencia que apelamos a de¯niciones incompletas, indicando que somos in-diferentes a la forma en que se completen. No hay que olvidarse que encomputaci¶on se deben evitar los casos de evaluaci¶on de operadores con ar-gumentos para los cuales no est¶an de¯nidos. Esto puede lograrse de variasformas: estableciendo claramente las precondiciones de los programas asocia-dos a cada operador a ¯n de que las aplicaciones se encarguen de ¯ltrar sus

26

argumentos antes de usar el operador, o haciendo un manejo de excepcionesde los argumentos para los cuales el operador no est¶a de¯nido.

Podemos resumir diciendo que la especi¯caci¶on de un TAD T , es unaterna

ESPT = (D;O;E)

donde D es el conjunto de dominios, O el conjunto de operadores y E esel conjunto de expresiones de l¶ogica de primer orden que constituyen losaxiomas. Cuando describimos un TAD, daremos el dominio (D), en la partetitulada sintaxis se da la forma de los operadores y en la parte sem¶antica seda el conjunto E.

TAD Conjunto Un conjunto es una colecci¶on de Elementos donde cadauno de ellos ocurre a lo sumo una vez. A continuaci¶on presentamos la espe-ci¯caci¶on del TAD Conjunto. A algunos axiomas se les coloca un t¶³tulo quedescribe la intenci¶on del mismo.

TAD Conjunto[Elemento]

D = fBoolean; Conjunto; ElementogSintaxis

vacio : ) Conjuntoesvacio : Conjunto ) Booleaninsertar : Conjunto£ Elemento ) Conjuntoeliminar : Conjunto£ Elemento ) Conjuntopertenece : Conjunto£ Elemento ) Boolean

Sem¶antica8c 2 Conjunto; e; e1; e2 2 Elemento; e6=elemento e1; e1 6=elemento e2;

1. esvacio(vacio) = true

2. esvacio(insertar(c; e)) = false

3. esvacio(eliminar(insertar(vacio; e); e)) = true

4. esvacio(c)! pertenece(c; e) = false

5. pertenece(insertar(c; e); e) = true

Tipos Abstractos de Datos 27

6. pertenece(insertar(c; e); e1) = pertenece(c; e1)

7. pertenece(eliminar(insertar(vacio; e); e1); e2) = (e =Elemento e2)

8. Axioma de Conmutatividad:esvacio(c)! pertenece(eliminar(insertar(c; e); e1); e2) =pertenece(insertar(eliminar(c; e1); e); e2)

9. Axioma de Unicidad:esvacio(c)! pertenece(eliminar(c; e); e) = false

Fin-Conjunto;

En la de¯nici¶on nos estamos re¯riendo a Elemento donde identi¯camosa los objetos que constituir¶an un conjunto. Debe resaltarse que no esta-mos caracterizando a los elementos, en particular pueden ser cualquier tipode elementos (enteros, reales, sillas, elefantes). Mas adelante veremos unarestricci¶on para estos elementos1.

A continuaci¶on daremos una lectura de los axiomas que se utilizan paradar la sem¶antica a los operadores.

La primera l¶³nea despu¶es de la palabra Sem¶antica, describe los tipos delas variables y algunas propiedades, como por ejemplo, e 6=Elemento e1. Esde hacer notar que en esta l¶³nea tambi¶en se indica que todas las variablesque ocurren en los axiomas est¶an cuanti¯cadas universalmente, satisfaciendolas propiedades asociadas a las variables. Esto hace que los axiomas no serecarguen tanto.

Axiomas 1,2 y 3

² esvacio(vacio) = true

² esvacio(insertar(c; e)) = false

² esvacio(eliminar(insertar(vacio; e); e)) = true

De¯nen al operador esvacio indicando que aplicado al conjunto llamadovacio da como resultado true (axioma 1), al aplicarlo a cualquier conjunto que

1En especial podemos pedir que los elementos sean ordenables o siendo mas formalesposean una relaci¶on de orden total entre ellos.

28

sea el resultado de una operaci¶on insertar, da como resultado false (axioma2) y al aplicarlo al conjunto resultante de eliminar el ¶unico elemento de unconjunto unitario da como resultado true. Podemos concluir que esvacio esun predicado que distingue al conjunto vacio de los dem¶as conjuntos ya queun conjunto al que se le insert¶o un elemento no es vac¶³o2.

Axiomas 4 y 5

² esvacio(c)! pertenece(c; e) = false

² pertenece(insertar(c; e); e) = true

De manera similar a los anteriores, estos axiomas de¯nen al predicadopertenece que nos indicar¶a si un cierto elemento ( segundo operando deloperador pertenece), es miembro del conjunto (primer operando).

El axioma 4 indica que independientemente del elemento a buscar (e), esfalso que sea miembro del conjunto vacio (corresponde al conocido axiomade conjuntos).

El axioma 5 indica que una vez que agregamos un elemento a un conjunto,este pertenece al conjunto.

Si bien puede pensarse que se ha de¯nido completamente al operadorpertenece, no se sabe que sucede cuando se le aplica, a un conjunto que esel resultado de agregar un elemento (e1 6=Elemento e). Esto se de¯ne en losaxiomas 6 y 7.

Axiomas 6 y 7

² pertenece(insertar(c; e); e1) = pertenece(c; e1)

² pertenece(eliminar(insertar(vacio; e); e1); e2) = (e =Elemento e2)

2Los axiomas 1 y 3 parecer¶³an decir lo mismo, pero lo que establecemos en el axioma 3 esque las implementaciones no requiere veri¯car que eliminar(insertar(vacio; e); e) = vacio,dej¶andole mayor grado de libertad a la implementaci¶on.

Tipos Abstractos de Datos 29

Axioma 6 En este axioma se indica que si un conjunto (c) es el resultadode agregar un elemento (e), la operaci¶on pertenece sobre ese conjunto y e1

(con la hip¶otesis e1 6=Elemento e), ser¶³a igual al operador pertenece aplicado alconjunto original (c), buscando al mismo elemento.

Axioma 7

² pertenece(eliminar(insertar(vacio; e); e1); e2) = (e =Elemento e2)

Dado que el operador eliminar no est¶a de¯nido para conjuntos vac¶³os yque e6=Elemento e1, este axioma indica que el elemento e2 est¶a en el conjuntounitario considerado si es igual al ¶unico elemento del conjunto, es decir, iguala e. En este axioma aparece la restricci¶on sobre los elementos ya que serequiere que los elementos puedan ser comparados con un operador de igual-dad (=Elemento). En los ejemplos usados anteriormente deber¶³amos podercomparar enteros, reales, sillas o elefantes.

Axioma 8

² Axioma de Conmutatividad:esvacio(c)! pertenece(eliminar(insertar(c; e); e1); e2) =pertenece(insertar(eliminar(c; e1); e); e2)

Este axioma indica que siempre que el conjunto a considerar (c) no seavac¶³o, el orden en que se agregan los elementos no tiene importancia.

Axioma 9

² Axioma de Unicidad:esvacio(c)! pertenece(eliminar(c; e); e) = false

Este axioma llamado de Unicidad, indica que la eliminaci¶on de un ele-mento (e), no deja rastros en el conjunto considerado. Es de hacer notar queen todos los axiomas se utiliza la igualdad de los booleanos (resultado depertenece, o la igualdad de los elementos (e =Elemento e2)). No hay igualda-des entre conjuntos, pues no hemos de¯nido ese operador para el TAD. Esto

30

signi¯ca que usando la de¯nici¶on de conjunto no podemos tener conjuntoscuyos elementos sean conjuntos.

A continuaci¶on, de¯niremos un tipo abstracto muy similar al de conjunto.

TAD Multiconjunto Un multiconjunto se de¯ne como una colecci¶on deElementos donde cada uno de ellos puede ocurrir m¶as de una vez. Debidoa esta propiedad los conjuntos son un caso particular de multiconjuntos.

TAD Multiconjunto[Elemento]

D = fBoolean; Conjunto; ElementogSintaxis

vacio : ) Multiconjuntoesvacio : Multiconjunto ) Booleaninsertar : Multiconjunto£ Elemento ) Multiconjuntoeliminar : Multiconjunto£ Elemento ) Multiconjuntopertenece : Multiconjunto£ Elemento ) Boolean

Sem¶antica8c 2 Conjunto; e; e1; e2 2 Elemento; e6=elemento e1; e1 6=elemento e2;

1. esvacio(vacio) = true

2. esvacio(insertar(m; e)) = false

3. esvacio(eliminar(insertar(vacio; e); e)) = true

4. esvacio(c)! pertenece(c; e) = false

5. pertenece(insertar(m; e); e) = true

6. pertenece(insertar(m; e); e1) = pertenece(m; e1)

7. pertenece(eliminar(insertar(vacio; e); e1); e2) = e =Elemento e2

8. Axioma de Conmutatividad:esvacio(m)! pertenece(eliminar(insertar(m; e); e1); e2) =pertenece(insertar(eliminar(m; e1); e); e2)

Tipos Abstractos de Datos 31

9. Axioma de No-Unicidadpertenece(m; e)! pertenece(eliminar(insertar(m; e); e); e) = true

Fin-Multiconjunto;

N¶otese que en las especi¯caciones de los TAD's Conjunto y Multiconjunto,el axioma 9 de cada TAD establece la diferencia entre el comportamiento delos objetos de cada tipo, en particular para los conjuntos, el axioma 9 deconjuntos indica que con la eliminaci¶on de un elemento, no quedan rastrosde ¶el en el conjunto resultado, mientras que para el caso de multiconjuntos,el axioma 9 indica que un multiconjunto puede albergar m¶ultiples copias deun elemento.

3.3 Sobre los TADs y sus Representacionesen el Computador

La axiom¶atica de los tipos abstractos nos permite conocer sus propiedadesy los operadores que permiten actuar sobre ellos. Sin embargo la tecnolog¶³ade la computaci¶on a¶un no permite que usemos este lenguaje para de¯nirestos objetos sobre los cuales queremos hacer algoritmos que los utilicen. Enparticular la presentaci¶on axiom¶atica que hemos hecho nos dice QUE sonlas propiedades que tienen que veri¯car nuestros tipos, pero no dice nada deC¶OMO lograr que se comporten de esa manera. Veamos con un ejemploconocido la diferencia entre QUE y COMO. Dado un n¶umero entero X,podemos de¯nir que el operador DIVIDIDO2(X) de la siguiente manera:DIVIDIDO es un operador que toma un argumento entero y devuelve unresultado entero y si X = 2 ¤ Z o X = 2 ¤ Z + 1 entonces DIVIDIDO2(X)= Z. Esta de¯nici¶on del operador no nos dice como es que calcularemos elresultado. Una forma puede ser dividiendo por dos (usando el operador dedivisi¶on de enteros) o puede hacerse con una operaci¶on de traslaci¶on a laderecha aprovechando la representaci¶on binaria de los enteros. Hay variasmaneras de implementar COMO el QUE.

Implementar: Acci¶on de construir programas (generalmente en un len-guaje de programaci¶on) que permitan programar los operadores indicados enla especi¯caci¶on de tal manera que las acciones dadas en el c¶odigo rveri¯quenlos axiomas dados en la parte sem¶antica de la especi¯caci¶on. En ciertas

32

especi¯caciones los operadores no est¶an totalmente de¯nidos, por lo que laimplementaci¶on deber¶a completarlos.

A continuaci¶on veremos varias formas de representar conjuntos en el com-putador. Cada una de las formas puede tener ventajas o desventajas respectoa la e¯ciencia de ciertos operadores, pero cualquiera de las implementacionesdeber¶a veri¯car los axiomas de la especi¯caci¶on y por lo que cualquier sistemaque utilice las propiedades de la especi¯caci¶on puede hacer uso de cualquierimplementaci¶on o intercambiarlas. Se debe resaltar que las especi¯cacionesque hemos visto hasta ahora se caracterizan por dar valores de verdad a loselementos que pueden ser observados. Los axiomas son independientes dela representaci¶on y en general no son constructivos. En ciertos casos parecendar un procedimiento para realizar la operaci¶on, pero una implementaci¶onno est¶a obligada a seguir los mismos pasos. Basta que los resultados de losoperadores para iguales operandos sean iguales.

3.3.1 Implementaci¶on del TAD Conjunto

Representaci¶on Est¶atica 1: Arreglo de Booleanos

Si conocemos la variedad de los elementos que pueden pertenecer al conjun-to, lo que equivale a decir el conjunto Universal y este es FINITO y ra-zonablemente peque~no, podemos, como puede hacerse con todo conjunto¯nito, hacer una correspondencia entre los elementos del conjunto Universaly los naturales de manera que cada posici¶on de un arreglo corresponda a unelemento del conjunto Universal.

Si el conjunto Universal fuera fazul,rojo,verdeg, representar¶³amos un con-junto por un arreglo de 3 elementos booleanos. El conjunto presentado acontinuaci¶on (despu¶es de hacer corresponder a la primera posici¶on el verde,a la segunda el azul y a la tercera el rojo) ser¶³a el conjunto que tiene elelemento verde pero no el azul ni el rojo.

false falsetrue

azul rojoverde

En el caso en que el Universo es ¯nito y peque~no, vimos que se puedeimplementar el conjunto con un arreglo de tama~no del Universo. El tiemporequerido, en esta implementaci¶on de las operadores de pertenece, insertar,

Tipos Abstractos de Datos 33

eliminar son de tiempo constante mientras que el operador esvacio es detiempo proporcional al tama~no del Universo. Puede hacerse una modi¯ca-ci¶on de la estructura de datos, llevando adicionalmente la cuenta de la car-dinalidad del conjunto, de manera tal que todas las operaciones se realicen atiempo constante.

En el caso de Universo ¯nito, esta representaci¶on puede interpretarsecomorepresentar cada conjunto con la funci¶on caracter¶³stica del conjunto:

F : A! Boolean

F (x) =(true si x 2 Afalse si no

En el Ap¶endice A se presenta una implementaci¶on.

Representaci¶on Est¶atica 2: Arreglo con pol¶³tica de no permitirduplicados

En el caso en que el Universo es ¯nito pero muy grande (por ejemplo unsubconjunto de enteros) y los conjuntos con los que se trabaja tienen unacantidad peque~na de elementos( relativa al tama~no del Universo) no parececonveniente dedicar tanta memoria para almacenar un conjunto, ya que lamayor¶³a de las posiciones tendr¶a valor de falso. Un procedimiento es almace-nar los valores de los elementos en el arreglo o referencias a ellos, ocupandolas primeras posiciones del mismo y llevando la cuenta de las posiciones ocu-padas del arreglo. La implementaci¶on propuesta hace que un conjunto seaun par (¶³ndice, arreglo), donde el arreglo puede ser de tipo elemento o detipo referencia a elemento.

² La operaci¶on de inserci¶on puede hacerse mediante el agregado del ele-mento en la primera posici¶on libre del arreglo, revisando que no est¶eya presente (tiempo proporcional al tama~no del arreglo).

² La operaci¶on de veri¯car si es vac¶³o (esvacio) consistir¶a en revisar sila primera posici¶on libre del arreglo coincide con la primera posici¶on(tiempo constante).

² La implementaci¶on del operador pertenece puede ser la de recorrer elarreglo hasta encontrar el valor buscado (respuesta true) o hasta la

34

¶ultima posici¶on ocupada (respuesta false). El tiempo de este operadorser¶a proporcional al tama~no del conjunto.

² La operaci¶on de eliminar puede implementarse como recorrido del vec-tor desde la primera posici¶on. En caso de encontrarse el elemento sedeber¶a desplazar los elementos hacia la izquierda o mover el ¶ultimoelemento del vector a la posici¶on que se libera, corrigiendo el valor dela posici¶on libre del arreglo. Esta operaci¶on tendr¶a un tiempo propor-cional al tama~no del arreglo.En el Ap¶endice A se presenta una implementaci¶on.

Representaci¶on Est¶atica 3: Arreglo con pol¶³tica de permitir dupli-cados

Esta implementaci¶on busca mejorar el tiempo de inserci¶on respecto a la im-plementaci¶on anterior.

² La operaci¶on de inserci¶on puede hacerse mediante el agregado del ele-mento en la primera posici¶on libre del arreglo (tiempo constante).

² La operaci¶on de veri¯car si es vac¶³o consistir¶a en revisar si la prime-ra posici¶on libre del arreglo coincide con la primera posici¶on (tiempoconstante).

² La implementaci¶on del operador pertenece puede ser la de recorrer elarreglo hasta encontrar el valor buscado (respuesta true) o hasta la¶ultima posici¶on ocupada (respuesta false). El tiempo de este operadorser¶a proporcional al tama~no del conjunto.

² La operaci¶on de eliminar es la m¶as costosa de esta representaci¶on. Elelemento a ser eliminado puede estar repetido en el vector ya que pa-ra abaratar el operador de inserci¶on no revisamos si el elemento yapertenec¶³a al conjunto, por lo que una implementaci¶on posible es elrecorrido del vector desde la primera posici¶on. En caso de encontrarseel elemento a ser eliminado se podr¶a usar uno de los dos mecanismossiguientes:

{ Se deber¶a disponer de dos cursores para completar el recorrido,uno para registrar la posici¶on que se est¶a revisando y otro paraindicar a cual posici¶on debe desplazarse el elemento revisado para

Tipos Abstractos de Datos 35

lograr eliminar todas las apariciones del elemento que se deseaeliminar.

{ Se reemplazar¶a el elemento a eliminar por el ¶ultimo del arreglo(reduciendo el valor del lugar libre), y se continuar¶a el recorridohasta agotar el arreglo.

Esta operaci¶on tendr¶a un tiempo proporcional al tama~no del arreglo.

Esta representaci¶on es muy conveniente para las aplicaciones que usanconjuntos que tienen una cantidad reducida de eliminaciones. Sin embargola operaci¶on de pertenece parece tener un costo alto para conjuntos grandes.En el Cap¶³tulo 7 veremos soluciones mas e¯cientes para este operador.En el Ap¶endice A se presenta una implementaci¶on.

3.3.2 Representaci¶on Din¶amicaLos ConjunTO se representan a trav¶es de estrucuturas simplemente encade-nadas mediante referencias (o apuntadores). Cada elemento est¶a representa-do como un nodo de la forma siguiente

SigEntrada

Nodo

-

De tal forma la estructura puede ser declarada como

TypeApunt-Nodo = ^NodoNodo = recordentrada: Tipo-ElemSig-Nodo:Apunt-Nodo

end

Un ConjunTO vac¶³o lo vamos a representar con un apuntador en NIL. Enel ap¶endice A se presentan algunas implementaciones.

² La operaci¶on de inserci¶on puede hacerse mediante el agregado del ele-mento en la primera posici¶on dela lista (tiempo constante).

36

² La operaci¶on de veri¯car si es vac¶³o consistir¶a en revisar si la lista esvac¶³a(tiempo constante).

² La implementaci¶on del operador pertenece puede ser la de recorrer lalista hasta encontrar el valor buscado (respuesta true) o hasta el ¶ultimoelemento de la lista (respuesta false). El tiempo de este operador ser¶aproporcional al tama~no del conjunto.

² La operaci¶on de eliminar consistir¶a en una b¶usqueda del elemento aeliminar, recordando el que lo precede en la lista y al encontrarlo, cam-biar el enlace del que lo precede a apuntar al que suced¶³a al elementoa eliminar.

3.4 Resumen del cap¶³tulo 3

En este cap¶³tulo hemos presentado dos tipos abstractos, el conjunto y elmulticonjunto, con los operadores b¶asicos usados en teor¶³a de conjuntos. Po-demos ver que las presentaciones se centran en establecer el qu¶e y no elc¶omo. En general las presentaciones de los TAD no son constructivas. Enlas secciones siguientes se muestran algunas implementaciones posibles deltipo conjunto. No hemos desarrollado la parte correspondiente a las valida-ciones de las implementaciones por no recargar el material del cap¶³tulo. Sinembargo debe mencionarse que las implementaciones deben veri¯car todos ycada uno de los axiomas de la especi¯caci¶on. La implementaci¶on tendr¶a pro-piedades adicionales, o casos en que la implentaci¶on es v¶alida. Por ejemplo,la implementaci¶on usando la funci¶on caracter¶³stica para representar un con-junto est¶a restringida a la representaciones de subconjuntos de un universo¯nito y manejable. La segunda implementaci¶on parece m¶as efectiva cuandolos conjuntos a manipular son peque~nos respecto al Universo. Sin embargocuando se dise~nan aplicaciones usando conjuntos se deber¶a hacer sin pensaren la implementaci¶on de los mismos. Una vez probada la aplicaci¶on puedepasarse a la fase de elegir la implementaci¶on que m¶as se ajuste a las nece-sidades de la aplicaci¶on (tomando en cuenta la variedad y frecuencia de usode los operadores en la aplicaci¶on).

Tipos Abstractos de Datos 37

3.5 EjerciciosEn los ejercicios se piden acciones que de¯nimos a continuaci¶on:

² Implementar un TAD consiste en darle una representaci¶on concretaen un lenguaje de programaci¶on. La representaci¶on concreta consta dedos partes

1. Representaci¶on de los objetos que constituyen el TAD medianteuna estructura de datos soportada por el lenguaje.

2. Representaci¶on de los operadores del TAD mediante programasque veri¯can los axiomas establecidos en la sem¶antica del TAD.Las operaciones parciales debber¶an ser completadas.

² Extender un TAD: Se re¯ere a agregar operadores (sintaxis) y sudescripci¶on (sem¶antica) que re°eja el comportamiento esperado. Unaextensi¶on de

ESPT = (D;O;E)

ser¶a

ESP 0T = (D;O [ O0; E [E0)

donde O0 corresponde a los nuevos operadores y E' corresponde a losaxiomas que de¯nen su¯cientemente a los operadores de O0.

1. Implemente el TAD Conjunto.

2. Extienda el TAD Conjunto con las operaciones del algebra de conjuntos(uni¶on, intersecci¶on y diferencia).

3. Implemente el TAD Multiconjunto.

4. Considere la siguiente la siguiente extensi¶on para ESPMulticonjunto =(D;O [ f#ocurrg; E [ fE1; E2; E3g), con

E1 : #ocurr(vacio; e) = 0E2 : #ocurr(insertar(m; e); e) = 1 + #ocurr(m; e)E3 : #ocurr(insertar(m; e); e1) = #ocurr(m; e1)

38

Proponga una representaci¶on para el TAD Multiconjunto que permitarealizar e¯cientemente el operador #ocurr.

5. Considere ESPComplejo como sigue:

TAD Complejo

D = fReal; ComplejogSintaxis

comp : Real £Real ) Complejosumar : Complejo£ Complejo ) Complejorestar : Complejo£ Complejo ) Complejomult : Complejo£ Complejo ) Complejodiv : Complejo£ Complejo ) Complejoreal : Complejo ) Realimag : Complejo ) Real

Sem¶antica8c1; c2 2 Complejo;

1 real(comp(r1; r2)) = r1

2 imag(comp(r1; r2)) = r2

3 sumar(c1; c2) = sumar(c2; c1)

4 real(sumar(c1; c2)) = real(c1) + real(c2)

5 imag(sumar(c1; c2)) = imag(c1) + imag(c2)

Fin-Complejo;

(a) Indique cu¶ales son los conjuntos D;O y E de la terna

ESPComplejo = (D;O;E).

(b) Usando sus conocimientos sobre n¶umeros complejos, escriba losaxiomas correspondiente a los operadores restar, mult y div delTAD Complejo.

(c) Implemente el TAD Complejo:

Tipos Abstractos de Datos 39

(c.1) Utilice representaci¶on cartesiana(c.2) Utilice representaci¶on polar

(d) Extienda ESPComplejo con los operadores opuesto y conjugado,dando la sintaxis y la sem¶antica.

6. Considere ESPRacional como sigue:

TAD RacionalD = fEntero; Racionalg

Sintaxis

rac : Entero£ Entero ) Racionalsumar : Racional £Racional ) Racionalrestar : Racional £Racional ) Racionalmult : Racional £Racional ) Racionaldiv : Racional £Racional ) Racionalnumerador : Racional ) Enterodenominador : Racional ) Entero

Sem¶antica8r; r1; r2 2 Racional; e; e1; e2 2 Entero;

1 sumar(r1; r2) = sumar(r2; r1)

2 numerador(rac(e1; e2)) = e1

3 denominador(rac(e1; e2)) = e2

4 denominador(r)6= 0

Fin-Racional;

(a) Indique cu¶ales son los conjuntos D;O y E de la terna

ESPRacional = (D;O;E).

(b) Escriba los axiomas correspondientes a los operadores restar, multy div del TAD Racional.

(c) Implemente el TAD Racional.

40

7. Considere ESPPolinomio como sigue:

TAD Polinomio[Real]

D = fReal; Polinomio;Boolean;Naturalg

Sintaxis

cero : ) Polinomioescero : Polinomio ) Booleandefterm : Polinomio£Natural £Real ) Polinomiomultterm : Polinomio£Natural £Real ) Polinomiocoef : Polinomio£Natural ) Realgrado : Polinomio ) Natural

Sem¶antica8p; p1; p2 2 Polinomio;n;n1 2 Natural; r; r1 2 Real;

1 escero(cero) = true

2 escero(p) = true$ coef (p; n) = 0

3 escero(p) = true! escero(multterm(p; n; r)) = true

4 multterm(defterm(p; n; r); n1; r1) =defterm(multterm(p; n1; r1); n + n1; r ¤ r1)

5 coef(defterm(p; n; r); n) = r

6 escero(p) = false! coef (defterm(p; n; r); n1) = coef(p; n1)

7 escero(p) = true! grado(p) = 0

8 escero(p) = true! grado(defterm(p; n; r)) = n

9 n > grado(p)! grado(defterm(p; n; r)) = n

10 n < grado(p)! grado(defterm(p; n; r)) = grado(p)

Fin-Polinomio;

(a) Implemente el TAD Polinomio.

Tipos Abstractos de Datos 41

(b) ExtiendaESPPolinomio = (D;O[fsumar;multiplicar; derivarg;E[E0), donde E0 es el conjunto de axiomas correspondiente a los o-peradores de suma,multiplicaci¶on y derivaci¶on de polinomios. Ud.debe dar el conjunto E0.

8. Considere la siguiente especi¯caci¶on para funciones de dominios ¯nitos(f : A! B):

TAD Funcion[A;B]

D = fFuncion;A;Bg

Sintaxis

new : ) Funciondef : Funcion£ A£B ) Funcionaplicar : Funcion £A ) B [ f?gpreimagen : Funcion £B ) Conjunto[A]definida? : Funcion £A ) Booleaninyectiva? : Funcion ) Boolean

Sem¶antica8a; a1 2 A; b; b1 2 B; f; f1 2 Funcion;

1 f 6= new ^ aplicar(f; a) = b ^ aplicar(f; a) = b1 ! b = b1

2 aplicar(new; a) = ?3 aplicar(def(f; a; b); a) = b

4 a6= a1 ! aplicar(def(f; a; b); a1) = aplicar(f; a1)

5 aplicar(f; a) = b! pertenece(preimagen(f; b); a) = true

6 definida?(f; a) = (aplicar(f; a)6= ?)

7 (aplicar(f; a) = aplicar(f; a1) ! a = a1) $ (inyectiva?(f) =true)

Fin-Funcion;

(a) Proponga una representaci¶on concreta para el TAD Funcion[A;B].

42

(b) Utilizando la representaci¶on propuesta, implemente los operadoresdel TAD.

(c) Complete la siguiente tabla con los ¶ordenes de cada uno de losoperadores, utilizando la representaci¶on propuesta:

new def aplicar preimagen de¯nida? inyectiva?

(d) Extienda el TAD Funcion[A;B] con los siguientes operadores:

(a) Composici¶on de funciones.(b) Determinar si una funci¶on es sobreyectiva.(c) Restricci¶on del dominio de la funci¶on, es decir, f : A ! B y

C ½ A entonces de¯nir f jC .

En cada caso, d¶e la sintaxis y la sem¶antica de los operadores.

9. De¯nici¶on: Una expresi¶on en postorden sobre los naturales en se de-¯ne como sigue:

(a) 8a 2 Z, a es una expresi¶on en postorden (expresi¶on constante).

(b) Si E1 y E2 son expresiones en postorden y op 2 f+;¡;£; =g,entonces E1E2 op es una expresi¶on en postorden.

Considere la siguiente especi¯caci¶on del TAD ExpPost:

TAD ExpPost[Natural]

D = fExpPost; Operador;Natural; 1; 2g

Sintaxis

ctte : Natural ) ExpPostesctte : ExpPost ) Booleandefexp : ExpPost£ ExpPost£Operador ) ExpPostsubexp : ExpPost£ f1; 2g ) ExpPostoperador : ExpPost ) Operador

Tipos Abstractos de Datos 43

Sem¶antica

8e1; e2 2 ExpPost;n 2 Natural; p 2 f1; 2g; op 2 Operador;

1 esctte(ctte(n)) = true

2 esctte(defexp(e1; e2; op)) = false

3 subexp(defexp(e1; e2; op); 1) = e1

4 subexp(defexp(e1; e2; op); 2) = e2

5 operador(defexp(e1; e2; op)) = op

Fin-ExpPost;

(i) Implemente en el TAD ExpPost.

(ii) De¯na un algoritmo para evaluar expresiones que satisfaga la si-guiente especi¯caci¶on:

evaluar : ExpPost) Natural(e1) evaluar(ctte(n)) = n(e2) evaluar(defexp(e1; e2; op)) = aplicar(op; evaluar(e1);

evaluar(e2))

3.6 Bibliograf¶³a1. EHRIG, H. MAHR,B. & OREJAS, F. \Introduction to Algebraic Spe-

ci¯cations. Part 1: Formal Methods for Software Development". TheComputer Journal. Vol. 35. #5. pp. 460-467. 1992.

2. EHRIG, H. MAHR,B. & OREJAS, F. \Introduction to Algebraic Spe-ci¯cations. Part 2: From Classical View to Foundations of SystemSpeci¯cations". The Computer Journal. Vol. 35. #5. pp. 468-477.1992.

3. GUTTAG, John. \ Abstract Data Types and the Development of DataStructures". Comm. of ACM. Vol. 20, No. 6, June1977.

4. GUTTAG, John, HOROWITZ,Ellis & MUSSER,David. The Design ofData Speci¯cations en \Current Trends in Programming Methodology.Vol IV". Yeh Editor, 1978.

44

5. GUTTAG, John. Notes on Type Abstraction en \Software Speci¯cationTechniques". International Computer Science Series. Addison Wesley,1986.

6. LIN, Huimin. \Procedural Implementations of Algebraic Speci¯cations".ACM TOPLAS, Vol. 15, No. 5, Nov. 1993. pp.876-895.

Cap¶³tulo 4

TAD Secuencia.Especializaciones

4.1 Marco Conceptual

En esta secci¶on nos ocuparemos del tipo de datos con estructura. Estosobjetos, conocidos como secuencias poseen la propiedad de ser elementos queest¶an organizados linealmente. Ejemplos de secuencias son:

(i) < blanco; azul; rojo; verde >

(ii) < 1; 2; 4; 8; 12; 14 >

(iii) < 7; 6; 5; 4; 3; 2; 1 >

(iv) < 7; 5; 5; 4; 3; 3; 1 >

Como vemos en los ejemplos, una secuencia puede tener elementos igualesen las diferentes posiciones, pero todos los elementos son del mismo tipo(homog¶enea), por lo que podemos considerar una secuencia como una posiblepresentaci¶on de un multiconjunto.

En la secci¶on siguiente se dar¶a el TAD Secuencia y se analizar¶an algunasde sus posibles representaciones. Cada una de las representaciones tendr¶acomportamientos diferentes para las operaciones del TAD.

45

46

4.2 Especi¯caci¶on del TAD SecuenciaEn esta secci¶on, de¯nimos el TAD Secuencia que nos permite manejar obje-tos estructurados de la forma:

s =< e1; e2; :::; en >

Intuitivamente podemos caracterizar estos objetos como sigue:

1. Todos los elementos en la secuencia son del mismo tipo (secuenciashomog¶eneas).

2. 8i; ei ocupa la i-¶esima posici¶on en la secuencia, por lo que hay un puestoasociado a cada elemento que ocurra en una secuencia.

3. Una secuencia puede crecer y decrecer din¶amicamente (no existe untama~no ¯jo).

A continuaci¶on presentamos ESPSecuencia:

TAD Secuencia[Elemento]

D = fSecuencia; Elemento;NaturalgSintaxis

vacia : ) Secuenciaesvacia : Secuencia ) Booleaninsertar : Secuencia£Natural £ Elemento ) Secuenciaeliminar : Secuencia£Natural ) Secuenciaproyectar : Secuencia£Natural ) Elementoesta : Secuencia£ Elemento ) Booleanlong : Secuencia ) Natural

Sem¶antica8s 2 Secuencia; p; p1 2 Natural; e; e1 2 Elemento;

1. esvacia(vacia) = true

2. 0 < p · long(s) + 1! esvacia(insertar(s; p; e)) = falso

3. 0 < p · long(s) + 1!proyectar(insertar(s; p; e); p) = e

TAD Secuencia 47

4. 0 < p1 < p · long(s) + 1!proyectar(insertar(s; p; e); p1) =

proyectar(s; p1)

5. 0 < p < p1 · long(s) + 1!proyectar(insertar(s; p; e); p1) = proyectar(s; p1 ¡ 1)

6. 0 < p1 < p · long(s)!proyectar(eliminar(s; p); p1) = proyectar(s; p1)

7. 0 < p < p1 · long(s) ¡ 1!proyectar(eliminar(s; p); p1) = proyectar(s; p1 + 1)

8. 0 < p · long(s) + 1!proyectar(eliminar(insertar(s; p; e); p); p1) = proyectar(s; p1)

9. esta(vacia; e) = falso

10. 0 < p · long(s) + 1! esta(insertar(s; p; e); e) = true

11. e6= e1 ^ 0 < p < long(s) + 1!esta(insertar(s; p; e); e1) = esta(s; e1)

12. 0 < p · long(s) + 1!esta(eliminar(insertar(s; p; e); p); e1) = esta(s; e1)

13. long(vacia) = 0

14. 0 < p · long(s) + 1! long(insertar(s; p; e)) = 1 + long(s)

15. 0 < p · long(s) + 1!long(eliminar(insertar(s; p; e); p)) = long(s)

Fin-Secuencia;

N¶otese que cuando se da la sem¶antica de los operadores no se dice nadaen relaci¶on a las inserciones donde la posici¶on p > long(s)+ 1, donde long(s)es la longitud de la secuencia s.

Una de las diferencias entre conjuntos y las secuencias, es que en ¶estashay una posici¶on asociada a cada elemento lo que llamamos en Ap¶endice Bposici¶on espacial.

48

Hemos presentado operaciones asociadas a un TAD, de una manera algoabstracta. El lenguaje natural es naturalmente ambiguo y si se utiliza parade¯nir operadores puede ser una fuente de error al momento de desarrollaraplicaciones usando los operadores, veamos un ejemplo:

Se quiere agregar una operaci¶on para borrar al tipo Secuencia. Se propo-ne la siguiente: Sintaxis

borrar : Secuencia£ Secuencia ) Secuencia

(a) borrar(s; s1) borra todas las ocurrencias de s1 en s, siendo s; s1 secuen-cias.

Analizando la de¯nici¶on dada para el operador borrar, vemos que la de-¯nici¶on es ambigua debido a la palabra ocurrencia, ya que pudiera ser in-terpretada como: Sem¶antica

² Las ocurrencias de s1 existentes en s

Ej: borrar(< b; a; b; a; l; a; l; a >;< b; a; l; a >) =< b; a; l; a >

² Todas las ocurrencias de s1 ya sean porque originalmente estaban en sy aquellas que se generen al hacer eliminaciones de la secuencia s1.

Ej: borrar(< b; a; b; a; l; a; l; a >;< b; a; l; a >) = vacia

Para trabajar este ejemplo generalizaremos el operador esta de secuencias

esta : Secuencia£ Secuencia ) Secuencia

con la sem¶antica:esta(s2 k s1 k s3; s1) = verdadero siendo k el operador de concatenaci¶on

de secuencias.Con esta de¯nici¶on adicional podemos establecer la sem¶antica para los

casos:

² esvacia(s1)! s2 k s1 = s2

² esvacia(s1) = false ! s2 k s1 = insertar(s2; proyectar(s1; 1) keliminar(s1; 1)

² esta(s; s1) = falso! borrar(s; s1) = s

² borrar(s2 k s1 k s3; s1) = borrar(borrar(s2; s1) k borrar(s3; s1); s1)

TAD Secuencia 49

² esta(borrar(s; s1); s1) = falso

Antes de pasar a estudiar algunas representaciones del TAD Secuencia,consideremos el siguiente problema:

Problema: Escriba una funci¶on que dada una secuencia de letras genereuna secuencia de 26 enteros, donde la i-¶esima posici¶on de la misma corres-ponde al n¶umero de ocurrencias de la letra que ocupa esa posici¶on en elalfabeto.

A continuaci¶on presentamos dos soluciones, la primera de ellas ( Soluci¶on1) resuelve el problema eligiendo un car¶acter y eliminando de la secuenciatodas las apariciones de ese car¶acter y contando la cantidad de caractereseliminados.

Soluci¶on 1:

function ContarLetras(s: Secuencia[Char]): Secuencia[Natural];var s1: Secuencia[Natural];

c: Char; cont,i: Natural;begin

s1 := SecCero(26);while not(esvacia(s)) dobegin

c := proyectar(s,1);cont := 1;s := eliminar(s,1);while esta(s,c) dobegin

cont := cont + 1;i := 1;while (c<>proyectar(s,i)) do

i := i + 1;s := eliminar(s,i)

end;s1 := insertar(eliminar(s1,PosABC(c)),PosABC(c),cont)

end;return(s1)

end;

50

La Soluci¶on 2 consiste en recorrer una sola vez la secuencia y dependiendodel car¶acter que se observa, se suma 1 al contador correspondiente a esecar¶acter.

Soluci¶on 2:

function ContarLetras(s: Secuencia[Char]): Secuencia{Entero];var s1: Secuencia[Entero];

i,len,p,c: Entero;

begins1 := SecCero(26);len := long(s);for i:= 1 to len do

p := PosABC(proyectar(s,i));c := proyectar(s1,p) + 1;s1 := insertar(eliminar(s1,p),p,c)

od;return(s1)

end;

La funci¶on PosABC recibe un car¶acter y devuelve su posici¶on en el alfabeto.La funci¶on SecCero(i) devuelve una secuencia de i ceros.

En la siguiente secci¶on se presentan algunas implementaciones del TADSecuencia y para cada una de ellas se analizan las dos soluciones propuestasarriba.

4.3 Implementaci¶on del TAD Secuencia

A continuaci¶on se presentan dos formas de representar el TAD Secuencia.Para la implementaci¶on se requiere de¯nir c¶omo ser¶a representado en la me-moria del computador el conjunto soporte del tipo. En este caso particular,debemos saber c¶omo se representa la secuencia vac¶³a y el resto de las secuen-cias. Seguidamente se deben programar las operaciones del tipo abstractohaciendo uso de la estructura de datos establecida para la representaci¶on delas secuencias.

TAD Secuencia 51

La implementaci¶on de las operaciones deben satisfacer los axiomas da-dos en la sem¶antica de la especi¯caci¶on. Las representaciones que se dana continuaci¶on corresponden a posibles implementaciones en lenguajes deprogramaci¶on donde el manejo de memoria se deja al programador 1.

4.3.1 Representaci¶on Est¶aticaCuando una secuencia se representa mediante un arreglo, se dice que la re-presentaci¶on es est¶atica. Este tipo de representaci¶on se caracteriza porquelos elementos de la secuencia se encuentran en posiciones de almacenamien-to de memoria f¶³sicamente contiguas. En PASCAL podemos representarest¶aticamente el tipo secuencia como sigue:

Type Secuencia = recordCasillas: array[1..N] of Elemento;Ult:0..N

end;

Donde N es una constante prede¯nida, Casillas es el arreglo donde sealmacenan los elementos y Ult indica la posici¶on del ¶ultimo elemento de lasecuencia dentro del arreglo. La secuencia estar¶a almacenada en las prime-ras posiciones del arreglo ya que la longitud de la secuencia coincide con laposici¶on del arreglo donde se almacena el ¶ultimo elemento de la secuencia.Hay que hacer notar que si la de¯nici¶on del arreglo dentro del registro tuvieseotro rango lo anterior no ser¶³a v¶alido.

En el ap¶endice A se presenta una implementaci¶on del TAD Secuencia enPASCAL utilizando representaci¶on est¶atica.

Ventajas

² Acceso directo a cada elemento de la secuencia, por lo que el costo esO(1).

² La implementaci¶on del operador long es O(1). En esta implementaci¶onel operador long ser¶a long(s) = s.Ult.

1El tipo que aqui de¯nimos puede ser realizado en JAVA utilizando la clase ja-va.util.Vector

52

Desventajas

² Desperdicio de memoria. La de¯nici¶on asigna a cada secuencia unarreglo de tama~no prede¯nido y este s¶olo se aprovecha hasta la posici¶onUlt. La representaci¶on de la secuencia vac¶³a ser¶a aquella donde Ulttiene el valor cero.

² Rigidez para el tama~no de las secuencias. El tama~no m¶aximo permitidosera igual al tama~no del arreglo.

² Di¯cultades para hacer inserciones y eliminaciones. La estructura debereorganizarse constantemente por lo que las operaciones de inserci¶ony eliminaci¶on tienen una complejidad lineal respecto al tama~no de lasecuencia.

4.3.2 Representaci¶on Din¶amicaCuando una secuencia se representa din¶amicamente, cada elemento de la listaes un registro que consta de dos campos, el primero almacenar¶a el elemento,y el segundo la direcci¶on del pr¶oximo elemento de la secuencia. Este ¶ultimocampo se denomina referencia o apuntador. Una caracter¶³stica fundamentalde este tipo de representaci¶on es que los elementos no ocupan, necesaria-mente, posiciones contiguas en memoria. Adem¶as, los elementos (instanciasdel registro) se van creando a medida que se van insertando elementos a lasecuencia.

T¶³picamente en PASCAL, el tipo Secuencia se representa din¶amicamentecomo sigue:

Type Secuencia = ^Casilla;Casilla = record

Elem:Elemento;Sig:Secuencia

end;

En este caso, un objeto de tipo Secuencia, es un apuntador a una sucesi¶onde Casillas. Este apuntador se denomina cabeza de la lista y es el que seutiliza para la representaci¶on de la secuencia vac¶³a.

Este encadenamiento de elementos es lo que com¶unmente se denomina lis-tas lineales; de tal forma que podemos decir que representar din¶amicamente

TAD Secuencia 53

una secuencia es equivalente a representarla utilizando listas con una cabeza.Para crear un nuevo elemento de una lista en PASCAL, se utiliza el procedi-miento prede¯nido new(p), que busca en memoria un espacio acorde al tipodel elemento apuntado por p y devuelve en p la direcci¶on de memoria obte-nida. Claro est¶a, p debe ser de tipo apuntador a los objetos que constituyenla secuencia (en el ejemplo de tipo Casilla).

Adem¶as, PASCAL tiene una constante prede¯nida llamada nil, que re-presenta la direcci¶on nula. Si se hace la siguiente declaraci¶on:

Var s: Secuencia;

y inicializa s como una secuencia vac¶³a de la siguiente manera:

s := vacia();

luego de ejecutarse esa instrucci¶on, s tendr¶a como valor nil.

En el ap¶endice A se presenta una implementaci¶on del TAD Secuencia enPASCAL utilizando representaci¶on din¶amica.

Ventajas

² Utilizaci¶on e¯ciente de la memoria ya que la memoria utilizada es pro-porcional al tama~no de la secuencia.

² Elimina la necesidad de limitar el tama~no de las secuencias ya que ell¶³mite ser¶a la memoria disponible en el computador.

Desventajas

² Mayor costo en el acceso a los elementos ya que hay que recorrer losei, 8i · p, para acceder a ep por lo que la proyecci¶on es un operadorde complejidad la longitud de la secuencia.

² se aumenta la memoria requerida para almacenar un elemento debidoa la adici¶on del campo Sig en el registro Casilla.

Las operaciones de inserci¶on y eliminaci¶on (al igual que en la repre-sentaci¶on est¶atica) son de complejidad proporcional a la longitud de lasecuencia.

54

4.4 Especializaci¶on del TAD SecuenciaComo se ha visto hasta ahora, el TAD Secuencia es un tipo muy generaly puede considerarse el punto de partida para la de¯nici¶on de otros tiposcuyos objetos son secuencias con esquemas espec¶³¯cos de crecimiento y de-crecimiento. Tal es el caso de los tipos Cola y Pila que estudiaremos en laspr¶oximas secciones. Estos tipos son considerados especializaciones del TADSecuencia, ya que restringen el conjunto de operaciones que lo caracterizan,para adquirir un comportamiento propio 2.

Otro ejemplo de especializaci¶on del TAD Secuencia es el TAD Dipolo.Un dipolo es una secuencia en la cual s¶olo se permite insertar y eliminarelementos tanto al principio como al ¯nal de la secuencia.

4.4.1 Especi¯caci¶on del TAD PilaEl TAD Pila es una secuencia, donde la forma de insertar y eliminar elementosde la misma, sigue una pol¶³tica LIFO (Last In First Out), lo que signi¯caque cuando se elimina un elemento, este es el ¶ultimo que fue insertado. Estoquiere decir que toda inserci¶on de elementos se har¶a por el extremo ¯nal otope y que la supresi¶on de un elemento corresponde al ubicado en su extremo¯nal (¶ultimo elemento insertado). Esto se re°eja en los axiomas donde usandola noci¶on de de¯nir un nuevo tipo abstracto como especializaci¶on de otro tipoabstracto (TAD Pila < Secuencia[Elemento] , Pila como especializaci¶on(<) de secuencia). Es por ser una especializaci¶on que los operadores delnuevo tipo ser¶an de¯nidos usando algunos de los operadores del TAD base.

TAD Pila < Secuencia[Elemento]

D = fPila; ElementogSint¶axis

vaciaP : ) PilaesvaciaP : Pila ) Booleanempilar : Pila£ Elemento ) Piladesempilar : Pila ) Pilatope : Pila ) Elemento

2En JAVA se llama extensiones (java.util.Stack es una extensi¶on de java.util.Vector)pero las especializaciones consideradas en este libro se re¯ere a un subconjunto del dominioque puede ser creado mediante el uso de los operadores pero con ciertas restricciones

TAD Secuencia 55

Sem¶antica8p 2 Pila; e 2 Elemento;

1. esvaciaP (p) = esvacia(p)

2. empilar(p; e) = insertar(p; 1; e)

3. :esvaciaP (p)! desempilar(p) = eliminar(p; 1)

4. :esvaciaP (p)! tope(p) = proyectar(p; 1)

Fin-Pila;

La sem¶antica dada considera que la pila se simula haciendo los ingresos yegresos de elementos en la primera posici¶on de la secuencia. Otra sem¶anticaalternativa ser¶³a la de considerar que las operaciones de empilar y desempilarse realizan por el ¯n de la secuencia:

Sem¶antica8p 2 Pila; e 2 Elemento;

1. esvaciaP (p) = esvacia(p)

2. empilar(p; e) = insertar(p; long(e) + 1; e)

3. :esvaciaP (p)! desempilar(p) = eliminar(p; long(e))

4. :esvaciaP (p)! tope(p) = proyectar(p; long(e))

Implementaci¶on del TAD Pila

En esta secci¶on presentamos el TAD Pila como una especializaci¶on del TADSecuencia por lo que se puede utilizar cualquiera de las representaciones quese utilizan para Secuencia. Si consideramos la representaci¶on est¶atica dadaen la secci¶on 4.3.1, el campo Ult del registro correspoder¶³a al tope de la pilay ser¶³a conveniente empilar en la posici¶on Ult+1 para garantizar O(1) en estaoperaci¶on. En cuanto a la representaci¶on din¶amica dada en la secci¶on 4.3.2,bastar¶³a con empilar en la cabeza de la lista para garantizar O(1). En elap¶endice A se encuentran las implementaciones mencionadas arriba para elTAD Pila.

56

4.4.2 Ejemplo de uso

Invertir una secuencia utilizando una pila

precond: sec = < x1; x2; :::xn >

postcond: Invertir-Sec = < xn; xn¡1; :::x1 >

function Invertir-Sec ( sec :secuencia) : secuenciavar p: PILAi: Integerp = vaciap();while not( esvacia(sec)) dop := empila(p,proyectar(sec,1))sec := eliminar(sec,1)

odi := 1while not (esvaciap(p)) dosec := insertar(sec,i,tope(p));i := i+1;p := desempilar(p)

odreturn(sec)

4.4.3 Especi¯caci¶on del TAD Cola

El TAD Cola por su parte, es al igual que el TAD Pila, una especializaci¶onde una secuencia, cuya pol¶³tica de manejo es FIFO (First In First Out) , esdecir, el primer elemento que entra es el primero en salir (se elimina el m¶asantiguo en la cola). Esto se re°eja en los axiomas.

TAD Cola < Secuencia[Elemento]

D = fCola; Elementog

Sint¶axis

TAD Secuencia 57

vaciaC : ) ColaesvaciaC : Cola ) Booleanencolar : Cola£ Elemento ) Coladesencolar : Cola ) Colafrente : Cola ) Elemento

Sem¶antica8c 2 Cola; e 2 Elemento;

1. esvaciaC(c) = esvacia(c)

2. encolar(c; e) = insertar(c; long(c) + 1; e)

3. :esvaciaC(c)! desencolar(c) = eliminar(c; 1)

4. :esvaciaC(c)! frente(c) = proyectar(c; 1)

Fin-Cola;

4.4.4 Ejemplo de uso: Invertir una cola

Implementaci¶on recursiva

function Invertir-Cola(col:Cola): Cola

precond: col = < x1; x2; :::xn >postcond: Invertir-Cola = < xn; xn¡1; :::x1 >

var X : Elementoif esvaciac(col)

Invertir-Cola := vaciac()else

X := frente(col);Invertir-Cola := encolar(Invertir-Cola(desencolar(col)),X)

¯

58

Implementaci¶on iterativa

function Invertir-Cola(col:Cola): Cola

precond: col = < x1; x2; :::xn >postcond: Invertir-Cola = < xn; xn¡1; :::x1 >

var X : Elementosec : secuencia;col-aux : Cola;col-aux = Copiar-cola(col);sec := vacia();

while not( esvaciac(col-aux)) doX := frente(col-aux);sec := insertar(sec,1,X);col-aux := desemcolar(col-aux);

odwhile (long(sec) 6= 0) do

X := proyectar(sec,1);col-aux := encolar(col-aux,X);sec := eliminar(sec,1);

odInvertir-Cola := col-auxend

4.4.5 Ejemplo

Supongamos que un funcionario en una taquilla recibe planillas que entregaal p¶ublico; los usuarios las llenan y las devuelven. Las planillas entregadaspor los usuarios ser¶an revisadas, ¯rmadas y devueltas al p¶ublico. Esta ope-raci¶on la realiza el empleado en las horas en que la taquilla no est¶a abiertaal p¶ublico. Para facilitar la b¶usqueda en el momento de entregar las pla-nillas el funcionario ha decidido tenerlas apiladas de manera tal que todaslas planillas de solicitantes cuyo apellido empiece por una misma letra, est¶encontiguas, pero que se conserve el orden por d¶³a y hora de llegada. Conside-remos primero una soluci¶on manual a este problema:

Inicialmente el empleado puede \apilar" las planillas con lo cual conserva

TAD Secuencia 59

el orden de llegada de las planillas. Conclu¶³do el horario de recepci¶on, puededistribuir la pila en 26 pilas de acuerdo a la inicial del primer apellido. Enestas pilas las planillas estar¶an en orden inverso al orden de llegada. Si acontinuaci¶on recorre las pilas (en orden alfab¶etico) y las coloca en un archi-vador (cola), esta cola tendr¶a dentro de cada letra el orden de llegada a lataquilla.

A continuaci¶on presentamos el programa asociado al proceso descrito a-rriba.

procedure Taquilla(HorasRecepcion: Integer);

{ Los procedimientos ``espera_evento'', ``avanza_reloj'' y``recibe_planilla'', se encargan de detectar la ocurrenciade los eventos de reloj o de entrega de planilla, actualizarla hora, y registrar los datos en un formulario, respectivamente.}

const reloj: 0;entrega: 1;

type Formulario = recordApellido: String;Hora: 0..23;Minutos: 0..59

end;Letras: `A'..`Z';

var P: Pila[Formulario];Piletas: array[Letras] of Pila[Formulario];Archivador: Cola[Formulario];F: Formulario; HorasTranscurridas : Integer;Evento: reloj..entrega; l: Letras;

begin

{ Inicializaciones}

HorasTranscurridas := 0; P := vacia;Archivador := vacia;for l:= `A' to `Z' do

60

Piletas[l] := vaciaod;

{ Recepcion de planillas}

while (HorasTranscurridas <= HorasRecepcion) doevento := espera_evento;case evento ofreloj: avanza_reloj(HorasTranscurridas);entrega: begin

F := recibe_planilla;empilar(P,F)

endendcase;

od;

{ Organizacion de las planillas en orden alfabetico y de llegada,ya que ha transcurrido el horario de atencion al publico }

while not(esvacia(P)) doF := tope(P);desempilar(P);empilar(Piletas[Inicial(F.Apellido)],F);

od;for l:= `A' to `Z' do

while not(esvacia(Piletas[l]) doF := tope(Piletas[l]);desempilar(Piletas[l]);encolar(Archivador,F)

odod;

end;{ Los formularios quedan en el archivador en el orden deseado }

Es de hacer notar que a este c¶odigo est¶a expresado usando solamenteoperadores del TAD y este es el momento en que deban analizar diversasimplementaciones de los TAD's Pila y Cola a ¯n de identi¯car cuales sonm¶as apropiadas teniendo en cuenta la frecuencia del uso de los operadores

TAD Secuencia 61

en la aplicaci¶on, sin que el c¶odigo deba ser alterado.

4.4.6 Especi¯caci¶on del TAD Dipolo

El TAD Dipolo es una secuencia, cuya pol¶³tica de manejo es que tanto losingresos como los egresos a la secuencia se realizan en los extremos de lasecuencia. Esto se re°eja en los axiomas.

TAD Dipolo < Secuencia[Elemento]

D = fDipolo; Elemento; Boolleang

Sint¶axis

vaciaD : ) DipoloesvaciaD : Dipolo ) BooleaningresarFin : Dipolo£Elemento ) DipoloegresarInicio : Dipolo ) DipoloingresarFin : Dipolo£Elemento ) DipoloegresarInicio : Dipolo ) Dipolofrente : Dipolo ) Elementofin : Dipolo ) Elemento

Sem¶antica8d 2 Dipolo; e 2 Elemento;

1. esvaciaD(d) = esvacia(d)

2. ingresarF in(d; e) = insertar(d; long(d) + 1; e)

3. ingresarInicio(d; e) = insertar(d; 1; e)

4. :esvaciaD(d)! egresarFin(d) = eliminar(d; long(d))

5. :esvaciaD(d)! egresarInicio(d) = eliminar(d; 1)

6. :esvaciaD(d)! ingresarFin(d) = insertar(d; long(c) + 1; e)

7. :esvaciaD(d)! ingresarInicio(d) = insertar(d; 1; e))

8. :esvaciaD(d)! frente(d) = proyectar(d; 1)

62

9. :esvaciaD(d)! fin(d) = proyectar(d; long(d))eliminar

Fin-Dipolo;En todo los casos de especializaciones del TAD secuencia, utilizamos los

operadores de secuencias, con valores pre¯jados para describir la sem¶anticade las operaciones del nuevo tipo.

4.5 Resumen del cap¶³tulo 4El TAD secuencia es el tipo abstracto mas utilizado para organizar una colec-ci¶on de elementos que requieran estar linealmente organizados (organizaci¶onespacial). Es por eso que podemos considerar a la secuencia como un en-riquecimiento de los multiconjuntos, ya que el operador pertenece llamadoesta puede combinarse con el operador proyectar para obtener el elementoy eliminar para quitarlo de la secuencia.

Debe recordarse siempre el ingrediente requieran estar linealmente organi-zados ya que es muy com¶un el uso de este tipo para representar simplementeconjuntos. No se debe utilizar tipos que posean propiedades por encima delas requeridas ya que esto restringe las implementaciones que se puedan usar.

Entre las colecciones que requieran estar linealmente organizadas, pode-mos distinguirlas seg¶un la pol¶³tica de ingreso y egreso de elementos, siendola secuencia la mas libre de las pol¶³ticas, la de cola la que re°eja la ordena-ci¶on de los elementos por el orden de aparici¶on de los mismos en el sistemay la pila que ha demostrado su utilidad en procesos de evaluaci¶on de pro-cedimientos recursivos, en la evaluaci¶on de expresiones algebraicas. En estecap¶³tulo mostramos que PILA y COLA son especializaciones del tipo secuen-cia ( sub-¶algebra), ya que pueden ser expresadas sus operaciones en funci¶onde los operadores de secuencia instanciando en forma constante alguno desus operandos.

4.6 Ejercicios1. Calcule la complejidad de la soluci¶on al problema del ejemplo.

2. Considere la siguiente funci¶on:

function F(s: Secuencia[Entero]): Secuencia[Entero];

TAD Secuencia 63

var e,e1,i,j,len,x: Entero;begin

len := long(s);for i := len downto 1 do

x := 0;e := proyectar(s,i);for j := 1 to i-1 do

e1 := proyectar(s,j);if (e1 <= e) then

x := x + e1fi

od;s := insertar(s,i+1,x)

od;return(s)

end;

(a) D¶e la secuencia resultante para la siguiente entrada:

s =< 67; 10; 4; 18; 15 >

(b) Calcule el T (N ) de la funci¶on F si el TAD Secuencia[Entero] est¶aimplementado mediante:

(b.1) Representaci¶on Est¶atica.(b.2) Representaci¶on Din¶amica.

(c) Justi¯que con razones de e¯ciencia el uso de las variables localese, e1 y len en la funci¶on F.

3. Considere la siguiente funci¶on:

function MisterioSecuencial(s: Secuencia[Natural]):Secuencia[Natural];vars1: Secuencia[Natural];a,i,j,k,len: Natural;

begini := 1; len := long(s);vacia(s1); k := 0;repeat

64

j := i+1; a := 0;while (proyectar(s,i)<>proyectar(s,j)) and (j<len) dobegin

a := a + proyectar(s,j); j := j+1end;k := k+1;if (proyectar(s,i) = proyectar(s,j)) then

insertar(s1,k,a)else insertar(s1,k,0);i := i+1;

until (i=len);return(s1)

end;

(a) D¶e la secuencia resultante para la siguiente entrada:

s =< 4; 1; 3; 7; 4; 3; 1; 3 >

(b) D¶e la caracterizaci¶on de la secuencia de entrada para el peor caso.Calcule el orden del T (N) para la caracterizaci¶on de s dada arribaen los siguientes casos:

(b.1) La secuencia est¶a representada est¶aticamente.(b.2) La secuencia est¶a representada din¶amicamente.

4. El TAD String es un caso particular del TAD Secuencia:

TAD String = Secuencia[Caracter]

(a) Extienda ESPString con los operadores:

#ocurr : String £ String ) Naturalconcatenar : String £ String ) Stringpalindrome : String ) Boolean

donde

(a.1) #ocurr(s; s1) determina el n¶umero de ocurrencias del strings1 en el string s.

(a.2) concatenar(s; s1) concatena los strings argumentos.

TAD Secuencia 65

(a.3) palindrome(s) es true si s es pal¶³ndromo, es decir, si se leeigual de izquierda a derecha y de derecha a izquierda. Ejm:arepera.

(b) Implemente los operadores de¯nidos en (a).

5. Especi¯que el TAD Dipolo en t¶erminos de los axiomas del TAD Se-cuencia. Sugiera una representaci¶on din¶amica. Justi¯que.

6. Extienda la especi¯caci¶on dada del TAD Secuencia como sigue:

ESPSecuencia = (D;O [ fagrupar; invertirg; E [E0)

donde

(a) agrupar(s) reorganiza los elementos de s, de forma tal que todoslos duplicados ocurran en posiciones contiguas de s,

(b) invertir(s) invierte los elementos de s.

(c) E0 es el conjuntos de axiomas correspondiente a agrupar e invertir

7. Usando el axioma 5 de la especi¯caci¶on de Secuencia y el axioma 4 dela especi¯caci¶on de Pila, obtener:

tope(desempilar(empilar(p; e)) = tope(p)

8. Usando el axioma 2 de la especi¯caci¶on de Secuencia y el axioma 2 dela especi¯caci¶on de Pila, obtener:

esvacia(empilar(p; e)) = falso

9. En la editorial \La Estrella" tienen un problema. El encargado delan¶alisis de los textos literarios, aunque es muy bueno analizando, noes muy cuidadoso al momento de hacer citas textuales y generalmenteolvida o abrir las comillas o cerrar las comillas para una cita. Por estaraz¶on, se desea que Ud. implemente un algoritmo que, utilizando elTAD Pila, veri¯que si las comillas est¶an balanceadas en un texto dado.Recuerde que existen comilla-derecha y comilla-izquierda. Recuerdeque una cita puede contener citas.

66

(a) Realizar el ejercicio sin utilizar aritm¶etica (enteros, reales).

(b) Realizar el ejercicio utilizando enteros.

10. D¶e un ejemplo donde sea preferible utilizar el TAD Cola al TAD Pila.

11. D¶e un ejemplo donde sea preferible utilizar el TAD Pila al TAD Cola.

12. Para organizar un conjunto de objetos que van a ser despachados sepuede utilizar una organizaci¶on de secuencia (o alguna especializaci¶on).Describa un proceso seg¶un el cual, organizando los objetos en una cola,existir¶an objetos que nunca ser¶³an despachados.

13. Se desea que implemente en PASCAL el TAD Cola[Estudiante] quedesean solicitar tickets del Comedor. Notar que los datos importantesdel estudiante, en este caso, son el carnet y el n¶umero de tickets quesolicita.

14. Sea ESPCola = (DCola; OCola; ECola). Especi¯que el TAD ColaconCo-leados como

ESPColaconColeados = (DCola; OCola [ fcolearg; ECola [E0),dondeE0 es el conjunto de axiomas correspondientes al operador colear.

colear(c; i; e) \colea" al elemento e delante de la i-¶esima posici¶on en c.Complete la especi¯caci¶on.

15. Sea ESPPila = (DPila;OPila; EPila). Especi¯que el TAD PilaconInter-calados como

ESPPilaconIntercalados = (DPila; OPila [ fintercalarg; EPila [E0),donde E' es el conjunto de axiomas correspondientes al operador inter-calar.

intercalar(p; i; e) \intercala" al elemento e sobre de la i¶esima posici¶onp.

16. Se quiere agregar una operaci¶on para editar al tipo String. Se proponela siguientes:

(b) reemplazar(s; s1; s2) reemplaza en el string s, las ocurrencias delstring s1 por el string s2.

TAD Secuencia 67

Sin embargo,la descripcion es ambigÄua. Proponga de¯niciones no am-bigÄuas compatibles con la de¯nici¶on.

17. Dada una secuencia de 7 elementos que representa los 7 primeros t¶erminosde una progresi¶on geom¶etrica:

(a) Calcular la raz¶on.

(b) Calcular 5 t¶erminos adicionales.

4.7 Bibliograf¶³a1. AHO, HOPCROFT & ULLMAN,\Data Structures and Algorithms".

Addison Wesley Series in Computer Science.

2. KNUTH, D.,\The Art of Computer Programming. Vol 1. FundamentalAlgorithms". Addison Wesley.

3. WIRTH, N.,\Algorithms+Data Structures=Programs". Prentice Hall

4. Manuales de PASCAL describiendo estructuras din¶amicas (pointers).

68

Cap¶³tulo 5

El problema de la B¶usqueda

5.1 Marco Conceptual

Consideremos el problema de implementar el operador esta del TAD Secuen-cia, de¯nido en la secci¶on 4.2 del cap¶³tulo 4. Este problema tiene bastanteimportancia ya que la b¶usqueda en una secuencia de gran tama~no puedetener un costo proporcional al tama~no de la secuencia (O(N )), que puederesultar una operaci¶on costosa 1.

5.1.1 B¶usqueda Secuencial

Una manera de implementar el operador esta es realizar una b¶usqueda se-cuencial del elemento en la secuencia. Este m¶etodo se basa en la idea de quepara determinar si un elemento ocurre en una secuencia, se deben revisaruno a uno los elementos de ¶esta hasta encontrar el elemento o hasta agotarla(no est¶a). De esta forma, si el elemento buscado ocupa la posici¶on p, antesde encontrarlo, se habr¶an revisado los p¡ 1 elementos que ocurren antes que¶el en la secuencia.

Podemos considerar este m¶etodo de b¶usqueda como un proceso repetitivodonde se mantiene una secuencia de elementos por revisar (originalmentela secuencia completa) y el resto son los elementos revisados (inicialmentela secuencia vac¶³a) y que en cada paso de la b¶usqueda se logra acortar lasecuencia por revisar.

1Si consideramos a la secuencia una forma de realizaci¶on del conjunto o multiconjunto,el an¶alisis del operador esta es equivalente a analizar el operador pertenece

69

70

long(Revisada)z }| {Revisada

long(s)¡long(Revisada)z }| {PorRevisar

"1ra pos. por revisar

Una soluci¶on al problema planteado es la siguiente:

function BusqSecuencial(PorRevisar:Secuencia;e:Elemento): Boolean;

beginif (esvacia(PorRevisar)) then

return(false)else

if (e = proyectar(PorRevisar,1)) thenreturn(true)

elsereturn(BusqSecuencial(eliminar(PorRevisar,1),e))

fifi

end;

La funci¶on BusqSecuencial(s,e), busca el elemento e en la secuencia s.El proceso termina ya que en cada nueva instancia de la funci¶on, la se-

cuencia sobre la que se hace la b¶usqueda es de tama~no menor, en una unidad,que la secuencia de la instancia anterior. El proceso puede decidir si el ele-mento buscado estaba en la secuencia original ya que s¶olo se elimina unelemento de la secuencia a revisar cuando se tiene la certeza de que no es elelemento buscado.

Es de hacer notar que en este algoritmo no se hace uso de relaciones quepudieran existir entre los elementos. S¶olo se requiere poder decidir si doselementos son iguales que es la expresi¶on usada en el segundo condicional.

En la secci¶on siguiente se requerir¶a que sobre los elementos se puedaestablecer un orden total.

El Problema de la B¶usqueda 71

5.1.2 B¶usqueda BinariaConsideremos ahora el caso particular en el cual la secuencia est¶a ordenadacrecientemente, seg¶un Á 2. Esta caracterizaci¶on de la secuencia, ofrece ciertasventajas que permiten implementar un m¶etodo de b¶usqueda m¶as inteligentellamado b¶usqueda binaria.

La idea de este m¶etodo es que la secuencia por revisar, de longitud N , sedivide en dos subsecuencias: una, de longitud [N=2]¡1, donde se encuentranelementos menores o iguales al que ocupa la posici¶on media, [N=2], y la otra,de longitud N ¡ [N=2] donde se encuentran elementos mayores o iguales:

· emed emed ¸ emed"elemento en la pos. media

Una vez particionada la secuencia por revisar de este modo, se comparasi el elemento buscado es mayor, menor o igual a emed para determinar si sedetiene la b¶usqueda (son iguales) o d¶onde debe seguir buscando. Note que adiferencia de la b¶usqueda secuencial, en cada paso, se acorta mucho m¶as lasecuencia por revisar.

Para dar el algoritmo correspondiente a la b¶usqueda binaria, consideremosuna nueva operaci¶on sobre las secuencias,

bisectar : Secuencia ) Secuencia£Elemento£ Secuencia

bisectar(s), retorna una terna (si;med; sd)Supongamos que est¶an de¯nidas las proyecciones sobre una terna y que

se llaman ¼1; ¼2 y ¼3, para la primera, segunda y tercera componente, res-pectivamente.

donde,

² med, es la posici¶on del elemento medio de la secuencia s.

long(s) > 1! ¼2(bisectar(s)) = proyectar(s; [long(s)=2])

² si, es la subsecuencia de s donde se encuentran elementos menores oiguales que proyectar(s;med).

2El s¶³mbolo Á correponde a una relaci¶on de orden v¶alida en el tipo elemento de lasecuencia

72

long(s) > 1 ^ si = ¼1(bisectar(s))!Vlong(si)j=1 (proyectar(si; j) = proyectar(s; j))

² sd, es la subsecuencia de s donde se encuentran elementos mayores oiguales que proyectar(s;med).

long(s) > 1 ^ sd = ¼3(bisectar(s))!Vlong(sd)j=1 (proyectar(sd; j) = proyectar(s; long(¼2(bisectar(s))) + j))

Una vez de¯nida la operaci¶on bisectar(s), presentamos el algoritmo deb¶usqueda binaria como sigue:

function BusqBinaria(PorRevisar:Secuencia;e:Elemento): Boolean;

var e_med:Elemento; t: Terna;begin

if (esvacia(PorRevisar)) thenreturn(false)

else if (long(s) = 1) thenreturn(proyectar(s,1) = e)

elset := bisectar(PorRevisar);e_med:= proyectar(PorRevisar,pi2(t));if (e = e_med) then return(true)else if (e < e_med) then

return(BusqBinaria(pi1(t),e))else

return(BusqBinaria(pi3(t),e))fi

fifi

fiend;

Donde pi1, pi2 y pi3, se deben interpretar como ¼1; ¼2 y ¼3, respectiva-mente, < como la relaci¶on Á y el tipo Terna = Secuencia £ Elemento £Secuencia .

El Problema de la B¶usqueda 73

5.1.3 An¶alisis del algoritmo de bisecci¶on

Haciendo el an¶alisis del algoritmo de la secci¶on anterior podemos deducir sucomplejidad.

Tbus(n) = Tproy(t) + Tbis(n) + (5.1)max(Tbus(long(pi1(t))); Tbus(long(pi3(t))))

donde long(pi¤(t)) corresponde a la longitud de la secuencia que va aser revisada en la b¶usqueda. Debido a que tenemos el m¶aximo (max), loconveniente es que las dos secuencia ¼1 y ¼3 tengan apr¶oximadamente lamisma longitud que representaremos por n=2. Adem¶as, considerando tproy(n)y Tbus(n) de tiempo constante, resulta:

Tbus(n) = c+ Tbus(n=2)= 2c+ Tbus(n=22)= rc+ Tbus(n=2r)

Haciendo n=2r < 1 tenemos r > log(n), por lo que la complejidad nosqueda:

Tbus(n) = c(log(n) + 1)

5.2 Posici¶on de los Elementos

Los algoritmos dados anteriormente, s¶olo determinan si un elemento e ocurreo no en una secuencia s. Sin embargo, en muchas aplicaciones es importante,recuperar la posici¶on que ocupa e en s; para lograr esto, podemos rede¯nirel operador buscar de la siguiente manera:

buscar : Secuencia£ Elemento ) Natural

Debido a que las posiciones en una secuencia se numeran a partir del uno,utilizaremos el cero para indicar que un elemento no ocurre en una secuencia.

74

5.2.1 Posici¶on seg¶un la B¶usqueda SecuencialPara resolver el problema de determinar la posici¶on del elemento, necesitamosconocer la posici¶on del primer elemento a ser revisado en la secuencia original:

long(revisada)z }| {revisada

long(s)¡long(revisada)z }| {por{revisar

"1ra pos. por revisarlong(revisada) + 1

Lo que hacemos es agregar un tercer par¶ametro, que mantenga en todomomento la longitud de la lista de elementos revisados, y de¯nimos la funci¶onBusqSecuencial1(s,e,p) como sigue:

function BusqSecuencial1(PorRevisar:Secuencia; e:Elemento;LongRev:natural): Natural;

beginif (esvacia(PorRevisar)) then

return(0)else if (e = proyectar(PorRevisar,1)) then

return(LongRev+1)else

return(BusqSecuencial(eliminar(PorRevisar,1),e,LongRev+1))

fifi

end;

La funci¶on BusqSecuencial se de¯ne como sigue:

function BusqSecuencial(s,e):Natural;begin

return(BusqSecuencial1(s,e,0))end;

debido a que en el par¶ametro formal por revisar se copia el valor de lasecuencia s, la primera posici¶on de la secuencia a ser revisada correspondeexactamente a la primera posici¶on de la secuencia original. De este modo, seresuelve el problema de recuperar la posici¶on del elemento e en la secuencias mediante b¶usqueda secuencial.

El Problema de la B¶usqueda 75

5.2.2 Posici¶on seg¶un la B¶usqueda BinariaConsideremos la bisecci¶on de la secuencia por revisar en un instante cualquie-ra de la ejecuci¶on del algoritmo: tanto a la izquierda como a la derecha de lasecuencia por revisar hay subsecuencias donde se ha descartado la b¶usquedaque llamaremos dizq y dder, respectivamente:

long(dizq)z }| {dizq s· emed s¸

long(dder)z }| {dder

"elemento en la pos. media

En este caso, el problema se resuelve nuevamente agregando un tercerpar¶ametro a la funci¶on que mantenga la longitud de la subsecuencia de ele-mentos descartados a la izquierda.

function BusqBinaria1(PorRevisar:Secuencia; e:Elemento;LongDizq:Natural): Natural;

var e_med:Elemento; t:Terna;begin

if (esvacia(PorRevisar)) then return(0)else if (long(s) = 1) then

if (proyectar(s,1) = e) then return(LongDizq+1)else return(0)fi

elset:= bisectar(PorRevisar);e_med:= proyectar(PorRevisar,pi2(t));if (e = e_med) then return(LongDizq +1)else if (e < e_med) then

return(BusqBinaria1(pi1(t)),e,LongDizq)else

return(BusqBinaria1(pi3(t),e,LongDizq+long(pi1(t)+1)))

fifi

fifi

end;

76

La funci¶on BusqBinaria se de¯ne como sigue:

function BusqBinaria(s,e):Natural;begin

return(BusqBinaria1(s,e,0))end;

Hasta este momento hemos analizado el problema de b¶usqueda en unasecuencia y con las implementaciones vistas hasta ahora, el orden de lab¶usqueda es O(n). Si podemos organizar la secuencia mediante un orden (ypodemos pagar por el costo de mantener ese orden en las inserciones) vimosque pod¶³amos reducir la b¶usqueda a O(log(n)). Para poblaciones grandeseste costo es muy alto. En cap¶³tulos posteriores (en particular en el cap.7), usaremos el recurso de organizar los elementos (en general, consumiendomemoria adicional) de manera de poder realizar la operaci¶on de b¶usquedam¶as e¯cientemente.

5.3 Resumen del cap¶³tulo 5

En este cap¶³tulo hemos comenzado el an¶alisis del problema de b¶usqueda, mo-tivado por la frecuencia del uso de ese operador y por que un enfoque ingenuode la soluci¶on puede dar tiempos inadmisibles para aplicaciones que requie-ran una respuesta a tiempo real (consulta en bancos, cajeros autom¶aticos,etc.). En particular se ataca el problema introduciendo la t¶ecnica del pre-condicionamiento que consiste en hacer un trabajo previo (en este caso elordenamiento de la secuencia) que si bien tiene un costo inicial alto haceque la operaci¶on de b¶usqueda pase de O(n) a O(ln(n)) lo que signi¯ca parapoblaciones grandes una reducci¶on dr¶astica en el tiempo requerido para laejecuci¶on de la b¶usqueda. Veremos sin embargo que hay casos en que estavelocidad no es su¯ciente o existen problemas con el mantenimiento del pre-condicionamiento (ordenamiento) que hacen buscar otros mecanismos masefectivo para la realizaci¶on de la operaci¶on de b¶usqueda como veremos enel cap. 7. Los algoritmos dados en este cap¶³tulo tienen una presentaci¶onrecursiva. Esta presentaci¶on hace mas f¶acil su comprensi¶on que la versi¶oniterativa y por sobre todo simpli¯ca la evaluaci¶on de su complejidad.

El Problema de la B¶usqueda 77

5.4 Ejercicios1. Dado el siguiente predicado:

ord(s) ´Los elementos de la secuencia s est¶an ordenados crecientemen-te seg¶un Á.

Decidir si son ciertas las siguientes proposiciones:

(a) ord(s)! BusqSecuencial1(s; e; 0) = BusqBinaria1(s; e; 0)

(b) ord(s)! proyectar(s; buscar1(s; e; 0)) =proyectar(s; BusqBinaria1(s; e; 0))

2. La compa~n¶³a \Distribuidora Las Am¶ericas C.A." mantiene un conjuntode clientes. Mensualmente, el n¶umero de clientes aumenta en un 5%, ydecrece en 2.5% con respecto al total. Adem¶as, el promedio de consultasen el mes es del 40% del n¶umero de clientes.

(a) Identi¯que el TAD asociado al conjunto de clientes.

(b) Haga un an¶alisis comparativo de las operaciones de ingreso, egresoy consulta de clientes, si el TAD se implementa como:

(b.1) Secuencia Ordenada(b.2) Secuencia no ordenada

En ambos casos, suponga que la secuencias se representan est¶ati-camente.

(c) Sugiera implementaciones alternas para el TAD. Haga un an¶alisiscomparativo.

3. Considere la ecuaci¶on (5.1) de la secci¶on 5.1.3.

(a) >Qu¶e ocurre si con la complejidad si Tproy(n) es de orden n.

(b) >Qu¶e ocurre en la misma ecuaci¶on si la funci¶on bisectar se cambiapor una funciu¶on cuya complejidad es lineal?

5.5 Bibliograf¶³a1. KNUTH, Donald. \The Art of Computer Programming. Vol 3. Sorting

and Searching.

78

2. WIRTH, Niklaus. \Algorithms + Data Structures = Programs". Pren-tice Hall.

Cap¶³tulo 6

Ordenamiento de una Secuencia

6.1 Marco ConceptualEl problema del ordenamiento de una secuencia de elementos de un dominioE, consiste en organizarlos ascendente o descendentemente seg¶un un ordentotal ¹ de¯nido sobre E . En este cap¶³tulo nos ocuparemos solamente delordenamiento ascendente utilizando el tipo abstracto secuencia de¯nido enel cap¶³tulo 4.

La funci¶on SORT transforma secuencias en secuencias

SORT : Secuencia! Secuencia

Es posible representar el problema del ordenamiento mediante una ex-presi¶on que de¯na el conjunto de soluciones. A esta expresi¶on la llamaremosespeci¯caci¶on del problema. En este sentido, los algoritmos de ordenamientohan sido planteados como una transformaci¶on de la secuencia a ordenar, x,para obtener una secuencia y, que satisfaga el predicado

y = SORT (x)) perm(x; y) ^ ord(y) (6.1)

donde perm(x,y) corresponde al predicado \La secuencia y es una permuta-ci¶on de la secuencia x" , y ord(y), al predicado \la secuencia y est¶a ordenada".

El primer predicado podemos caracterizarlo por

8i 9j ) proyectar(x; i) = proyectar(y; j) (6.2)

8i 9j ) proyectar(y; i) = proyectar(x; j) (6.3)

79

80

long(x) = long(y) (6.4)

Este segundo predicado podemos caracterizarlo como:

i · j ) proyectar(y; i) ¹ proyectar(y; j) (6.5)

En caso de existir claves repetidas, la expresi¶on (6.1) caracteriza un con-junto de operadores que veri¯can las dos propiedades requeridas, y comooperador no est¶a univocamete de¯nido. En realidad, caracteriza un conjuntode valores: la familia de operadores de clasi¯caci¶on.

Un m¶etodo particular de ordenamiento obtendr¶a un valor espec¶³¯co den-tro del conjunto soluci¶on usando un mecanismo determinado para obtener elelemento soluci¶on del problema.

6.1.1 Estabilidad de los algoritmos de ordenamientoCuando todas las claves por las que estamos ordenando son diferentes, cual-quier algoritmo de ordenamiento dar¶a el mismo resultado. Recordemos quemencionamos resultado y no el costo de alcanzar el resultado. No ocurre lomismo cuando tenemos claves repetidas. Sea las secuencias x y s con lassiguientes propiedades:

perm(x; s) y s =< s1; s2; : : : ; s8 >donde s veri¯ca

s1 < s2 < s3 = s4 = s5 < s6 < s7 < s8 > (6.6)

por lo tanto

perm(x; s) ^ ord(s)

Esta secuencia es soluci¶on de ordenar x, pero las secuencias

< s1; s2; s5; s4; s3; s6; s7; s8 >

< s1; s2; s5; s3; s4; s6; s7; s8 >

< s1; s2; s3; s5; s4; s6; s7; s8 >

< s1; s2; s4; s3; s5; s6; s7; s8 >

< s1; s2; s4; s5; s3; s6; s7; s8 >

Ordenamiento de una Secuencia 81

son tambien soluciones de ordenar x.Diremos que un m¶etodo de clasi¯caci¶on es estable cuando, para claves

iguales, preserva el orden que tenian los elementos en la secuencia de entrada.El m¶etodo ser¶a estable si la soluci¶on es la secuencia de la ecuaci¶on 6.6.

6.1.2 Ejemplo

Sea la secuencia a clasi¯car conformada por elementos que pertenecen alproducto cartesiano de:

Apellido£ Cedula£NivelEducacional £ExperienciaLaboral

donde un ejemplo de elemento puede ser:

(Perez; V ¡ 3181437; 4; 12)

Si desamos visualizar a los empleados ordenados por apellido y en el ca-so de igual apellido, ordenados en forma creciente por a~nos de experiencialaboral, el algoritmo de visualizaci¶on pudiera ser ordenar primero por a~nosde experiencia y luego por apellido. Si el m¶etodo de clasi¯caci¶on es establehabremos logrado el objetivo. Habiendo ordenado primero por a~nos de Ex-perienciaLaboral y luego por apellido, siendo el algoritmo estable, para todoslos empleados Perez, los ordenar¶a respetando el orden que tra¶³a la secuenciaoriginal, es decir en forma creciente de cantidad de a~nos de ExperienciaLa-boral. Si tomamos como secuencia de entrada

< s8; s6; s1; s4; s5; s3; s7; s2 >

y usando las relaciones de los elementos establecidas en 6.6por lo que s3 = s4 = s5, las ¶unicas secuencias resultados posible con un

ordenamiento estable ser¶an aquellas secuencias que tengan la subsecuencia< s4; s5; s3 > lo que equivale a la secuencia:

< s1; s2; s4; s5; s3; s6; s7; s8 >

Veremos en los m¶etodos de ordenamiento que la propiedad de estabilidades una propiedad de la implementaci¶on de un m¶etodo y no del m¶etodo en si.

82

6.2 M¶etodos de ordenamiento de Secuencias

En esta secci¶on nos ocuparemos de cuatro m¶etodos cl¶asicos para el ordena-miento de secuencias, todos ellos basados en la construcci¶on de la secuenciaordenada partiendo de la secuencia vac¶³a y aument¶andola hasta que la se-cuencia (y) veri¯que perm(x; y) ^ ord(y).

En la descripci¶on de los algoritmos utilizaremos el TAD Secuencia.Si bien en la presentaci¶on usaremos el TAD secuencia, esta familia de

algoritmos est¶a particularmente adaptada a una implementaci¶on est¶atica desecuencias, en que no requiere mas espacio que el requerido para almacenarla secuencia original.

Para todos los m¶etodos se inicia el algoritmo con dos secuencias, una deellas desordenada y la otra ordenada, y en cada paso de la transformaci¶onlo que se logra es acortar la secuencia desordenada y alargar la secuenciaordenada hasta lograr que la secuencia desordenada sea vac¶³a y la ordenadasea la soluci¶on al problema de ordenamiento.

B¶asicamente, los cuatro algoritmos di¯eren en la forma en que se eliminaen cada paso un elemento de la secuencia desordenada y c¶omo se inserta elmismo elemento en la secuencia ordenada. En cada caso, hay un costo aso-ciado a la eliminaci¶on y a la inserci¶on. Veremos, en diversas representaciones,que cuando se reduce uno de ellos se incrementa el otro.

DESORDENADA [1::i] ORDENADA[i+ 1::n]

Inicialmente la secuencia ordenada es vac¶³a ( i = n) (condici¶on inicial) yla condici¶on ¯nal de los algoritmos ser¶a que la secuencia desordenada se havaciado ( i = 0) y todos los elementos de la secuencia original han ingresadoen la secuencia ordenada.

Un invariante de estos m¶etodos es, llamando n a la cardinalidad de lasecuencia

long(DESORDENADA) + long(ORDENADA) = n (6.7)

Ordenamiento de una Secuencia 83

6.2.1 por Selecci¶on

El mecanismo para el m¶etodo de selecci¶on es tomar un elemento, eliminarlode la secuencia desordenada e insertarlo en la secuencia ordenada, lograndoas¶³ aumentar en uno la longitud de la secuencia ordenada. Por lo que de-be repetirse este proceso hasta que no sea posible elegir un elemento de lasecuencia desordenada ( ya que esta ser¶a vac¶³a). Una forma de facilitar lainserci¶on, es seleccionar el m¶aximo de la secuencia desordenada, y se colocacomo primer elemento de la secuencia ordenada (ya que en cada selecci¶on, elelemento escogido es menor o igual que todos los elementos de la secuenciaordenada).

function Seleccion(desordenada,ordenada:Secuencia):Secuencia;beginif esvacia(desordenada) then retornar(ordenada)else return(

Seleccion(eliminar(desordenada,max(desordenada)),insertar(ordenada,1,

proyectar(desordenada,max(desordenada)))))

fiend;

Para ordenar una secuencia A, se realizar¶a una llamada a:

x = Seleccion(A,vacia)

En este algoritmo el operador max toma una secuencia y devuelve la po-sici¶on donde se encuentra el elemento m¶aximo.

Haciendo un an¶alisis del algoritmo, vemos que efectivamente el algoritmopresentado es un algoritmo de clasi¯caci¶on. Requerimos de operadores auxi-liares para el an¶alisis. Sea conc el operador de concatenaci¶on de secuencias.La precondici¶on del algoritmo es:

perm(A; conc(desordenada; ordenada)) (6.8)

ya que inicialmente, llamandolo con

x = Seleccion(A; vacia); conc(A; vacia) = A

84

por lo que el predicado (6.8) se veri¯ca. Asimismo(6.3) es un invariante delalgoritmo, ya que cada nueva llamada, lo que se ha transformado es que unelemento se elimina de la secuencia desordenada y se incluye en la secuen-cia ordenada, por lo que la concatenaci¶on de ambas secuencia sigue siendouna permutaci¶on de la secuencia original. Para asegurar que el algoritmoordena efectivamente la secuencia deberemos demostrar que ord(ordenada)es verdadero.

Para todo par i,j ¶³ndices v¶alidos para las secuencias

proyectar(desordenada; i) · max(desordenada)proyectar(desordenada; i) · proyectar(ordenada; j)max(desordenada) · proyectar(ordenada; j)

Usando la propiedad de ord dada en (6.5) tendremos

max(desordenada) · proyectar(ordenada; j)

y luego de insertar elmax(desordenada) en la primera posici¶on de ordenadaresultara:

max(desordenada) · proyectar(insertar(ordenada; 1;max(desordenada)); j)

por lo la nueva ordenada veri¯ca la propiedad (6.5).En cada momento de la recursi¶on, la concatenaci¶on del primer par¶ametro

y el segundo corresponden a una permutaci¶on de la secuencia inicial de en-trada, ya que que el elemento que es eliminado de la primera es insertado enla segunda. Por lo que se veri¯ca

perm(A; conc(desordenada; ordenada))

conc se re¯ere al operador de concatenaci¶on de secuencias.Finalmente, dado que desordenada es vac¶³a tenemos que el resultado veri-

¯ca el predicado anterior y dada la construcci¶on de ordenada tambi¶en veri¯cael predicado

ord(ordenada)

.

Ordenamiento de una Secuencia 85

Estabilidad

Como hemos dicho en 6.1.1, la estabilidad del algoritmo de ordenamientoreside en preservar el orden relativo que tenian los elementos en la secuenciade entrada:

Si x =< x1; x2; : : : ; xn > y perm(x; s) ^ ord(s)

(a) s1 · s2 · s3 · ¢ ¢ ¢ · sn

(b) si = si+1 ¢ ¢ ¢ = sj

(c) Si si = xksi+1 = xr k < rsi+2 = xl r < l...sj = xu siendo u = maxtfxk = xtg

En el algoritmo de selecci¶on, el elemento seleccionado es el max(desordenada),por lo que para lograr que el algoritmo sea estable requerimos que se extrai-ga como max, el elemento de desordenada con mayor ¶³ndice, cuando sea elcaso de claves repetidas. Bastar¶³a con recorrer desde el principio la secuenciadesordenada y cambiando la elecci¶on del m¶aximo siempre que el nuevo ele-mento fuera mayor o igual que el m¶aximo ya previamente seleccionado. Otroenfoque puede lograrse recorriendo la secuencia desordenada desde el ¶ultimoelemento hasta el primero.

6.2.2 Ordenamiento por Inserci¶onEl mecanismo para el m¶etodo de inserci¶on es tomar un elemento (en principiocualquiera), eliminarlo de la secuencia desordenada e insertarlo ordenada-mente en la secuencia ordenada, logrando as¶³ hacer crecer en uno la longitudde la secuencia ordenada. Por lo que debe repetirse este proceso hasta que nosea posible elegir un elemento de la secuencia desordenada ( ya que esta ser¶avac¶³a). Para simpli¯car la operaci¶on de selecci¶on el elemento que se elige es el¶ultimo de la secuencia desordenada. Esta simpli¯caci¶on es v¶alida para el casode la implementaci¶on de secuencias usando arreglos. Si la implementaci¶onde secuencias es listas simplemente enlazadas, la operaci¶on mas econ¶omicaes tomar el primero de la lista desordenada.

86

function Insercion(desordenada,ordenada:Secuencia):Secuencia;beginif esvacia(desordenada) then return(ordenada)else return(

Insercion(eliminar(desordenada,long(desordenada)),InsertOrd(ordenada,

proyectar(desordenada,long(desordenada)))))

fiend;

Donde la funci¶on InsertOrd inserta en la secuencia (primer argumento)el elemento (segundo argumento) de manera que si la secuencia de entradaestaba ordenada el resultado ser¶a una secuencia ordenada, que incluye alelemento insertado.

function InsertOrd(ordenada:Secuencia,e:Elemento):Secuencia;beginif esvacia(ordenada) then

return(insertar(ordenada,1,e))else i:=1;

while (i <= long(ordenada)) and(proyectar(ordenada,i) < e) doi := i + 1

od;

return(insertar(ordenada,i,e))

fiend

El while se detiene en un puesto donde hay que insertar el nuevo elemento(caso i <= long(ordenada) y hay alg¶un elemento en la secuencia que es mayorque el que se quiere insertar , o con i > long(ordenada) lo que indica quetodos los elementos de la secuencia son menores que el elemento a insertar.Es por eso que i indica en cada uno de los caso el puesto donde debe insertarse

Ordenamiento de una Secuencia 87

el nuevo elemento para que la secuencia resultado este ordenada 1

Para ordenar una secuencia A, se realizar¶a una llamada a:

x = Insercion(A,vacia)

Otra versi¶on posible para insertar puede ser la de buscar el puesto dondedebe ser colocado el elemento mediante b¶usqueda binaria y luego insertarlo.

Es importante hacer resaltar que el esquema de los dos algoritmos pre-sentados es muy similar: en el primero (Selecci¶on) el trabajo de cada pasoconsiste en recorrer la parte desordenada para obtener el m¶aximo de los ele-mentos, mientras que en el segundo el trabajo de cada paso es recorrer laparte ordenada para insertar el nuevo elemento.

Estabilidad

Por la presentaci¶on del algoritmo de inserci¶on, este es naturalmente estable sien la implementaci¶on conserva la propiedad que el elemento elegido para in-sertar sea el ¶ultimo de la secuencia ordenada y que la operaci¶on insertarOrdinserte adelante del elemento que en el recorrido de izquierda a derecha, nosea menor que el seleccionado para insertar. Es de hacer notar el mecanis-mo sugerido para hacer mas econ¶omica la selecci¶on en listas simplementeenlazadas, da como resultado una implementaci¶on no estable del algoritmo.

Si se utiliza el mecanismo de b¶usqueda del puesto para insertar medianteb¶usqueda binaria, la estabilidad no es inmediata ya que si el elemento est¶a yaen la parte ordenada se deber¶³a buscar todos los elementos iguales de maneratal de insertar el nuevo elemento como primero del conjunto de elementosiguales.

6.2.3 BurbujaEl m¶etodo de la burbuja hace que la secuencia de entrada sufra transforma-ciones de tal forma que los elementos m¶as pesados suban acerc¶andose a suspuestos de¯nitivos. Esto se logra haciendo comparaciones de un elemento consu vecino en la secuencia desordenada y en el caso en que no est¶en ordenadosse intercambian.

1Esta presentaci¶on del algoritmo, si bien es muy compacta requiere elementos del len-guaje de programaci¶on en que sea implementada: que las expresiones booleanas no eval¶uentodos sus argumentos cuando el resultado parcial permita saber el valor de la expresi¶on.En el caso que nos ocupa si i > long(ordenada) proyectar no est¶a de¯nida

88

function Burbuja(desordenada,ordenada:Secuencia):Secuencia;beginif esvacia(desordenada) then

return(ordenada)else return(Burbuja(eliminar(Intercambio(desordenada),

long(Intercambio(desordenada))),insertar(ordenada,1,

proyectar(Intercambio(desordenada),long(desordenada))))))

fiend;

Y la funci¶on Intercambio, se de¯ne como sigue:

function Intercambio(s: Secuencia): Secuencia;beginif (long(s) > 1) then

if (proyectar(s,1) > proyectar(s,2)) thenreturn(insertar(Intercambio(eliminar(s,2)),1,

proyectar(s,2)))else

return(insertar(Intercambio(eliminar(s,1)),1, proyectar(s,1)))

fielse

return(s)fi

end;

N¶otese que en una implementaci¶on usando arreglos, la eliminaci¶on del¶ultimo elemento en la primera secuencia y la inserci¶on en la segunda setraducir¶³an en cambiar la frontera entre ambas.

Una propiedad que puede tomarse como post-condici¶on de la invocaci¶ony:=Intercambio(s) es que

1 · j · long(y) proyectar(y; j) · proyectar(y; long(y)) (6.9)

Explotando esta propiedad es podemos aseverar que

Ordenamiento de una Secuencia 89

8 (j; k) proyectar(desordenada; j) · proyectar(ordenada; k) (6.10)

y debido a la forma de hacer crecer desordenada tenemos que otro inva-riante es

ord(ordenada) (6.11)

Con lo anterior demostramos que construimos usando el m¶etodo de laburbuja la secuencia ordenada.

Puede reconocerse nuevamente en este algoritmo, la partici¶on de la se-cuencia en dos subsecuencias, la de la izquierda desordenada y la de la derechaordenada.

DESORDENADA [1..i+1] ORDENADA[i+2..n]

Estabilidad

Si la implementaci¶on del algoritmo de la burbuja toma en cuenta no inter-cambiar elementos iguales, el m¶aximo elemento de la secuencia desordenadaocupar¶a la ¶ultima posici¶on de la secuencia desordenada. Asimismo, si estevalor esta duplicado, estos valores estar¶an en las posiciones anteriores con-servando el orden relativo que ten¶ian en la entrada.

6.2.4 HeapSortEste m¶etodo de ordenamiento usa el mismo principio de comenzar con unasecuencia vac¶³a que va creciendo hasta tener todos los elementos de la secuen-cia inicial, diferenci¶andose de los m¶etodos anteriores en que no se inicia elproceso de crecimiento de la secuencia ordenada a partir de una secuencia de-sordenada cualquiera sino de una semi-ordenada: un heap, lo cual constituyeuna pre-condici¶on para la funci¶on MetodoHeap.

De¯nici¶on: Un heap es una secuencia < h1; h2; :::; hn >, que cumple lasiguiente propiedad:

8i 1 · i < n=2 (hi · h2i ^ hi · h2i+1)

90

Un ejemplo de heap de 9 elementos ( este caso ser¶a 4 < n=2):

a =< 3; 5; 7; 9; 11; 14; 8; 10; 10 >

ya que para todo ¶³ndice entre 1; : : : ; 4:

a1 · a2 y a1 · a3

a2 · a4 y a2 · a5

a3 · a6 y a3 · a7

a4 · a8 y a4 · a9

Que una secuencia tenga una organizaci¶on de heap no signi¯ca que es-te ordenada, pero por las propiedades de heap, el primer elemento de lasecuencia es el min(a).

En general, un heap corresponde a un ¶arbol parcialmente ordenado porlo que el primer elemento suele llamarse ra¶³z del heap. Estos objetos losestudiaremos en el cap¶³tulo 8

function MetodoHeap(heap,ordenada:Secuencia):Secuencia;begin

if esvacia(heap) then return(ordenada)else

return(MetodoHeap(heapify(sacar(heap)),insertar(ordenada,long(ordenada)+ 1,

proyectar(heap,1)))fi

end;

La funci¶on sacar devuelve una secuencia donde se ha reemplazado elprimer elemento del heap por el elemento que ocupaba la ¶ultima posici¶on.N¶otese que la secuencia desordenada decrece al aplicarsele esta operaci¶on.

function sacar(s: Secuencia): Secuencia;var s': Secuencia; l': Natural;begin

s' := eliminar(s,1);l' := long(s');

Ordenamiento de una Secuencia 91

return(insertar(eliminar(s',l'),1,proyectar(s',l')))end;

N¶otese que la secuencia resultante podr¶³a no ser un heap. La funci¶onheapify devuelve un heap construido a partir de la secuencia resultante dela funci¶on sacar.

El algoritmo de ordenamiento de una secuencia consistir¶a en transfor-mar la secuencia desordenada en un heap y luego utilizar MetodoHeap paracompletar el ordenamiento.

function HeapSort(desordenada:Secuencia):Secuencia;begin

return(MetodoHeap(HacerHeap(desordenada),vacia)))end;

Donde HacerHeap recibe una secuencia y devuelve una secuencia queveri¯ca las propiedades de un heap, dejando en el primer elemento de lasecuencia el m¶³nimo del conjunto.

Estabilidad

El m¶etodo es inestable. Esta propiedad lo hace ¶util solamente cuando se est¶aordenando una sola vez una secuencia.

6.3 An¶alisis de los algoritmos presentados

6.3.1 An¶alisis de los M¶etodos de Ordenamiento sinPrecondicionamiento

En los dos primeros algoritmos (Inserci¶on y Selecci¶on), el esquema de soluci¶ones id¶entico: se chequea la condici¶on de parada, y si no se cumple, se hacehace una llamada recursiva, modi¯cando las dos secuencias de entrada, comose ve en los siguientes trozos de c¶odigo:

Seleccion(eliminar(desordenada,max(desordenada)),insertar(ordenada,1,proyectar(desordenada,

max(desordenada))))

92

Insercion(eliminar(desordenada,long(desordenada)),InsertOrd(ordenada,proyectar(desordenada,long(desordenada))))

considerando que el m¶aximo se obtiene una sola vez, la complejidad delalgoritmo Seleccion, Ts(n), estar¶a dada por la evaluaci¶on de los argumentosy el costo de la llamada recursiva:

Ts(n) =

8><>:

c si n = 0

Te(n) + Tm(n) + Ti(N ¡ n; 1) + Tp(n) + Ts(n¡ 1) si n > 0

donde Te(n), Tm(n), y Tp(n) corresponden a las funciones de complejidadde las funciones eliminar, max, y proyectar, respectivamente. Ti(N ¡n; 1), corresponde a la complejidad de la funci¶on insertar, espec¶³¯camenteen la primera posici¶on de una secuencia. n es el tama~no de la secuenciadesordenada en una instancia cualquiera de Seleccion y N es el tama~no della secuencia desordenada en la primera instancia.

Resolviendo Ts(n) para n > 0 queda:

Ts(n) = Te(n) + Tm(n) + Ti(N ¡ n; 1) + Tp(n) + Ts(n¡ 1)= Te(n) + Tm(n) + Ti(N ¡ n; 1) + Tp(n) + Te(n¡ 1)+

Tm(n¡ 1) + Ti(N ¡ n+ 1; 1) + Tp(n ¡ 1) + Ts(n¡ 2)...

=Pi¡1j=0 Te(n¡ j) +

Pi¡1j=0 Tm(n¡ j) +

Pi¡1j=0 Ti(N ¡ n+ j; 1)+

Pi¡1j=0 Tp(n¡ j) + Ts(n¡ i)

...Ts(n) =

Pn¡1j=0 Te(n¡ j) +

Pn¡1j=0 Tm(n ¡ j) +

Pn¡1j=0 Ti(N ¡ n+ j; 1)+

Pn¡1j=0 Tp(n¡ j) + c

Para calcular el orden de Ts(n) debemos hacer el an¶alisis bajo dos presu-posiciones:

Ordenamiento de una Secuencia 93

(A) La secuencia est¶a representada est¶aticamente. Esto implica que Te(n),Tm(n) y Ti(n; 1) son O(n), mientras que Tp(n) es O(1). Por lo tanto,nos queda:

Ts(n) = O(Pn¡1j=0 (n¡ j) +

Pn¡1j=0 +(n¡ j)Pn¡1

j=0 (N ¡ n+ j)+

Pn¡1j=0 1 + 1)

= O(2Pn¡1j=0 (n¡ j) +Nn¡ n2 + 1=2(n2 ¡ n) + n+ 1)

= O(2n2 ¡ n2 + n+Nn ¡ n2 + 1=2(n2 ¡ n) + n+ 1)

= O(n2=2 +Nn+ 3=2n+ 1)

Recordemos que el tama~no de la secuencia a ordenar n, en la llamadaoriginal es igual a N , por lo tanto, reemplazando en Ts(n) nos queda:

Ts(N) = O(3=2N 2 + 3=2N + 1) = O(N 2)

(B) La secuencia est¶a representada din¶amicamente. En este caso, Te(n),Tm(n) y Tp(n) son O(n), mientras que Ti(n; 1) es O(1).

Para calcular el Ts(n), se procede de manera an¶aloga al caso anterior.

Como puede verse el m¶etodo resulta de orden cuadr¶atico. En el caso deInsercion se puede reducir un poco el tiempo de ejecuci¶on del algoritmohaciendo la inserci¶on mediante b¶usqueda binaria, sin embargo no se cambiael orden del m¶etodo.

Partiendo de la misma descripci¶on de los algoritmos, vemos que el al-goritmo Seleccion se llama recursivamente tantas veces como la longitudde la secuencia original (N) y en cada llamada la longitud de la secuenciaordenada la llamaremos i y por lo tanto la secuencia desordenada tendr¶a unalongitud de N ¡ i. En el cuerpo del algoritmo se realizan las operaciones:

² 2 veces la operaci¶on de max(desordenada)

² la operaci¶on eliminar(desordenada,k) donde k es la posici¶on delm¶aximo elemento de desordenada

² la operaci¶on insertar(ordenada,1, proyectar(desordenada, k))

94

Usando los operadores de secuencia, la secuencia desordenada perder¶³a unelemento en el proyectar, siendo esa operaci¶on en una representaci¶on est¶aticade O(i) y la operaci¶on de insertar O(N ¡ i), dando como resultado un costode O(N). Usando un operador adicional al TDA secuencia de SWAP, siendoeste operador

TAD Secuenciaconswap[Elemento]Sintaxis

vacia : ) Secuenciaesvacia : Secuencia ) Booleaninsertar : Secuencia£Natural £ Elemento ) Secuenciaeliminar : Secuencia£Natural ) Secuenciaproyectar : Secuencia£Natural ) Elementoesta : Secuencia£ Elemento ) Booleanlong : Secuencia ) NaturalMAX : Secuencia£Natural £Natural ) NaturalSWAP : Secuencia£Natural £Natural ) Secuencia

Sem¶antica8s 2 Secuencia; p; p1; P 2 NaturalP 6= p;P 6= p1; e; e1 2 Elemento;

1. si proyectar(s; p) = e y proyectar(s; p1) = e1

proyectar(SWAP (s; p; p1); p) = e1

proyectar(SWAP (s; p; p1); p1) = e

proyectar(SWAP (s; p; p1); P ) = proyectar(s; P )

2. proyectar(s; p) · proyectar(s;MAX(s; 1; long(s)))

Podemos transformar el algoritmo:

function Seleccion(desordenada,ordenada:Secuencia):Secuencia;beginif esvacia(desordenada) then retornar(ordenada)else return(

Seleccion(eliminar(desordenada,max(desordenada)),insertar(ordenada,1,

proyectar(desordenada,

Ordenamiento de una Secuencia 95

max(desordenada)))))fi

end;

en el algoritmo que almacena en una secuencia de longitud N el par desecuencias (ordenada y desordenada), y recibiendo como par¶ametros la se-cuencia y el entero que indica el ¶ultimo elemento de la secuencia desordenada,sobreentendiendo que la secuencia ordenada se inicia en la siguiente posici¶on.

function Seleccion(s:Secuencia,i:Natural):Secuencia;beginif esvacia(desordenada) then retornar(ordenada)if i = 0 then return(s)else begin

k:= MAX(desordenada,1,i);retornar(Seleccion( SWAP(s,k,i),i-1))

endfi

end;

haciendo el an¶alisis de esta versi¶on, llamando Tw al tiempo de SWAP ( quees constante) y Tm(k) al tiempo requerido para calcular el m¶aximo en unasecuencia de k elementos:

Ts(n) = Tw + Tm(n) + Ts(n¡ 1)...Ts(n) =

Pn¡1j=0 Tw +

Pn¡1j=0 Tm(n¡ j)

Ts(n) =Pn¡1j=0 Tw +

Pn¡1j=0 (n¡ j)

...Ts(n) = n ¤ Tw + n¤(n+1)

2

La complejidad encontrada es nuevamente cuadr¶atica, sin embargo lasconstantes son mucho menores que en los an¶alisis precedentes. Esta versi¶ondel algoritmo explota la propiedad de los arreglos de poder intercambiar el¶ultimo elemento de desordenada con su m¶aximo, alargando as¶³ la longitudde la parte ordenada.

Se deja al lector como ejercicio el c¶alculo del T (n) para los m¶etodos deinserci¶on y burbuja.

96

6.3.2 An¶alisis del HeapSortEl an¶alisis de este m¶etodo lo haremos bajo la suposici¶on de que las secuenciasse representan est¶aticamente. La funci¶on HacerHeap construye el heap apartir de la secuencia desordenada. El costo asociado a la misma es O(n),siendo n la longitud de la secuencia desordenada. Falta ver el costo asociadoa la funci¶on MetodoHeap para aplicar la regla de la suma y obtener el ordendel HeapSort.

MetodoHeap(heap,ordenada:Secuencia):Secuencia;begin

si esvacia(heap) entonces return(heap)sino

return(MetodoHeap(heapify(sacar(heap)),insertar(ordenada,1,

proyectar(heap,1)))end;

se reemplazo long(ordenada) por 1Si reconocemos que utilizando representaci¶on est¶atica, para obtener los

nuevos argumentos para la recursi¶on basta con dividir el arreglo en dos partes:la parte izquierda correponder¶a a la secuencia desordenada (heap) y la partederecha a secuencia ordenada.

HEAP [1..i+1] ORDENADA[i+2..n]

La funci¶on sacar consistir¶³a en intercambiar el primero y el ¶ultimo ele-mento del heap, 1 y i+1, respectivamente, y en ese caso todo el trabajo sereducir¶³a a crear el heap inicial y a llevar a su posici¶on (heapify) el elemen-to mal ubicado en la ra¶³z del heap. El proceso heapify cuesta O(log(n)).N¶otese que tal como se describi¶o el proceso sacar arriba, se obtiene una se-cuencia ordenada decrecientemente, pero se preserva O(1) en la inserci¶on delelemento seleccionado en la secuencia ordenada. Para obtener una secuenciaordenada ascendentemente se trabaja con un max-heap donde se pide:

81 · i < n=2 (hi ¸ h2i ^ hi ¸ h2i+1)

Como se hacen n inserciones y estas se realizan en O(log(n)) la complejidadde MetodoHeap resulta O(n log(n)). Aplicando la regla de la suma, nos quedaque el orden de HeapSort es O(nlog(n)).

Ordenamiento de una Secuencia 97

6.4 Otros algoritmos de ordenamientoExiste una variedad de enfoques adicionales para ordenar una secuencia. Lostrabajados en las secciones anteriores est¶an particularmente adaptados pa-ra ordenar una secuencia que se almacena en su totalidad en la memoriaprincipal del computador. Otros algoritmos pueden adaptarse facilmente alos casos en que la memoria principal es insu¯ciente para almacenar todala secuencia. Mencionaremos dos m¶etodos, uno particularmente adaptadoa memoria secundaria que recibe el nombre de Merge Sort y el segundollamado Quick Sort que se caracteriza generalmente en tener un buen com-portamiento en tiempo de ejecuci¶on, pero posee el inconveniente que paraciertas secuencias su comportamiento puede decaer sensiblemente.

6.4.1 Merge SortEl esquema de este m¶etodo de ordenamiento se basa en el enfoque de "Dividey reinar¶as".

Si llamamos MERGESORT al operador que toma una secuencia y de-vuelve la secuencia ordenada deber¶a este operador veri¯car las condicionesdadas en 6.1.

Usaremos dos operadores auxiliares que llamaremos SPLIT y MERGEcon la siguiente ¯rma:

SPLIT : Secuencia ) (Secuencia; Secuencia)MERGE : (Secuencia; Secuencia) ) Secuencia

Sem¶antica8s 2 Secuencia; (p; p1) 2 Secuencia£ Secuencia; e 2 Elemento

i 2 Natural

1. SPLIT (s) = (p; p1)!long(p) aproximadamente igual a long(p1) ^perm(pkp1; s) = true

2. MERGE(p; p1) = s!ORD(p) = true ^ ORD(p1) = true ^ ORD(s) = true^ perm(pkp1; s) = true

Ahora estamos en condiciones de describir la sem¶antica deMERGESORT :MERGESORT (vacia) = vacia

98

MERGESORT (s) =MERGE(MERGESORT(¼1(SPLIT (s));MERGESORT(¼2(SPLIT (s)))

Usando las propiedades de los operadores MERGE, SPLIT dados en 1 y2 podemos veri¯car que el operador MERGESORT veri¯ca las condicionesrequeridas en 6.1 para que un m¶etodo sea de ordenamiento. El operador deMERGE puede ser implementado en O(n), el operador de SPLIT en O(n),por lo que resulta que el algoritmo de MERGESORT es de O(n log(n)).

6.4.2 Quick sortEste algoritmo es muy similar a MERGESORT , s¶olo di¯ere en el opera-dor de separaci¶on de la secuencia, que se realiza mediante la elecci¶on de unelemento (que puede o no ser un elemento de la secuencia),que se denominapivote y cuyo valor debe ser pr¶oximo a la mediana de la secuencia, de maneratal que la secuencia sea dividida en dos subsecuencias de aproximadamentela misma longitud. El operador de separaci¶on SPLIT1

1. SPLIT1(s; e) = (p; p1)!proyectar(p; i) · e ^ proyectar(p1; i) > e ^perm(pkp1; s) = true

Ahora estamos en condiciones de describir la sem¶antica deQUICKSORT :QUICKSORT (s) =

QUICKSORT(¼1(SPLIT1(s; e))kQUICKSORT(¼2(SPLIT1(s; e))Si observamos la ecuaci¶on 6.4.2 que como SPLIT1 es un operador que

hace que la primera secuencia del resultado tiene elementos menores o igualesal pivote y los de la segunda secuencia son mayores que el pivote, nos bastaconcatenar las secuencias resultantes de las llamadas al QUICKSORT paratener una secuencia ordenada.

El valor de e utilizado para la realizaci¶on del operador SPLIT1 es cr¶³ticopara asegurar el orden del algoritmo. En particular, si se logra en cadauso del operador SPLIT1 una buena elecci¶on del elemento que divide a lassecuencias (por ejemplo, divide la secuencia en dos secuencias de aproximada-mente la misma longitud) el algoritmo de QUICKSORT es de O(n log(n)).Sin embargo si e es un elemento que hace que long(¼2(SPLIT (s; e)) =0, la expresi¶on en 6.4.2 es una computaci¶on in¯nita. En el caso en quelong(¼1(SPLIT (s; e)) = 1 el algoritmo de MERGESORT ser¶a de O(n2).Existen varias t¶ecnicas seguras ( en el sentido de apartarnos de un caso de-generado o del caso de orden O(n2)) de elecci¶on del pivote. Si se conoce una

Ordenamiento de una Secuencia 99

distribuci¶on de las claves a ordenar puede hacerse una buena aproximaci¶ona la mediana. Otra forma es tomar el promedio entre dos valores de la se-cuencia. En todo caso el costo asociado a la elecci¶on del pivote debe ser deO(1), ya que si se invirtiera mayor trabajo en la elecci¶on el m¶etodo dejar¶³ade ser O(n log(n)).

6.5 Resumen del cap¶³tulo 6En este cap¶³tulo se revisaron algunos m¶etodos de ordenamiento, b¶asicamentelos llamados m¶etodos de ordenamiento interno, sin y con precondicionamien-to, haciendo el an¶alisis de su complejidad. Asimismo se revisa la propiedadde estabilidad que asegura la posibilidad de realizar ordenamientos sucesi-vos, sobre diferentes claves, logrando ordenar un conjunto de elementos portuplas de claves.

Haciendo una recapitulaci¶on de los m¶etodos vistos en este cap¶³tulo, podr¶³amosllegar a la conclusi¶on que el algoritmo de HEAPSORT es el mas e¯cien-te, lo cual es erroneo. Existen en la literatura otros algoritmos de ordenO(nlog(n)), tal como Quicksort que en el caso promedio es O(nlog(n)), sien-do su peor caso O(n2), siendo tambien un m¶etodo no estable, el Shellsort conuna complejidad de O(n1:25). Es importante recordar que en el cap¶³tulo 1en la secci¶on 1.2.2 vimos que cualquiera sea el m¶etodo de ordenamiento queutilice comparaciones de claves para ordenar, requerir¶a al menos O(nlog(n)).

6.6 Ejercicios

1. Dada la siguiente de¯nici¶on del predicado mismo:

mismo(x; z) =(vedadero si long(x) = long(z) ^ 8i9j(xi = zj)falso sino

Indique si la de¯nici¶on anterior es equivalinte a decir que el predicadodar¶a como resultado verdadero solamente cuando los dos argumentossean iguales. Justi¯que su respuesta.

2. Ordene las siguientes secuencias, utilizando los algoritmos estudiadosen este cap¶³tulo:

100

(a) < 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12 >

(b) < 1; 3; 5; 7; 9; 11; 2; 4; 6; 8; 10; 12 >

(c) < 12; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11 >

(d) < 12; 11; 10; 9; 8; 7; 6; 5; 4; 3; 2; 1 >

(e) < 1; 12; 11; 10; 9; 8; 7; 6; 5; 4; 3; 2 >

(i) Analice el n¶umero de comparaciones y de intercambios obtenidoscon cada algoritmo.

(ii) Elabore las gr¶a¯cas de rendimiento de cada una de las secuenciasseg¶un el algoritmo ejecutado (n¶umero de comparaciones vs n¶umerode elementos en la secuencia).

3. Considere los siguientes patrones de la secuencia:

s =< s1 s2 ¢ ¢ ¢ sn >

donde n es par:

(a) s2 < s3 < ¢ ¢ ¢ < sn¡1;s1 > sn¡1; sn < s2

(b) s1 < s3 < ¢ ¢ ¢ < sn¡1;s2 > s4 > ¢ ¢ ¢ > sn

(c) s1 < s3 < s4 < ¢ ¢ ¢ < sn¡2;sn¡1 > sn;sn¡1 < s1;s2 > sn¡2

Para cada patr¶on, determinar el n¶umero de movimientos y de compa-raciones si la secuencia s se ordena con los m¶etodos presentados en estecap¶³tulo.

4. Considere la siguiente secuencia:

s =< s1; s2; : : : ; sn >

donde

(a) s1 < s2 < ¢ ¢ ¢ < s(n=2)¡1

Ordenamiento de una Secuencia 101

(b) s(n=2)+2 < s(n=2)+3 < ¢ ¢ ¢ < sn(c) sn=2 < s1

(d) sn < s(n=2)+1

Determinar el n¶umero de movimientos y de comparaciones si la secuen-cia s se ordena con los m¶etodos presentados en este cap¶³tulo.

5. Considere la siguiente secuencia:

s =< s1; s2; : : : ; sn >

donde

(a) s1 < s3 < s5 ¢ ¢ ¢ es una subsecuencia de s estrictamente decrecien-te.

(b) s2 > s4 > s6 > ¢ ¢ ¢ es una subsecuencia de s estrictamente cre-ciente.

Determinar el n¶umero de movimientos y de comparaciones si la secuen-cia s se ordena con los m¶etodos presentados en este cap¶³tulo.

6. El Club de Gimnasia de la USB, ha extendido el horario de las clasesde Aerobics que ofrece cada trimestre, por lo que la demanda de dichasclases ha aumentado. Para reforzar este aumento, el Club ha creadoun Plan de Oferta que consiste en hacer un descuento del 20% a aque-llas personas que se inscriban por un per¶³odo de un a~no para tomardichas clases. Las inscripciones normalmente se realizan a principiosde trimestre, aunque hay oportunidad de inscribirse en el transcursodel mismo.El Club de Gimnasia desea tener un peque~no sistema que le permita ve-ri¯car autom¶aticamente los datos de las personas inscritas y controlarel n¶umero de personas por clase. El conjunto de personas inscritashasta una cierta fecha se mantendr¶an en orden creciente, por n¶umerode carnet, en una secuencia. Los datos de las personas que se inscribana \destiempo" (en el transcurso del trimestre) se mantendr¶an por ordende inscripci¶on en otra secuencia. Al ¯nal de cada trimestre hay que unirambos vectores, y eliminar del conjunto de personas inscritas a aquellasa las que se les haya vencido su per¶³odo. Se desea que usted elija, delos algoritmos considerados en el poblema anterior, aquel que resultem¶as e¯ciente para esta operaci¶on. Justi¯que su elecci¶on.

102

7. Suponga que las claves que se utilizan para el ordenamiento de unasecuencia poseen la caracter¶³stica que comparar dos claves tiene uncosto muy superior al de una comparaci¶on de enteros.

i) En la versi¶on del m¶etodo de inserci¶on haga una modi¯caci¶on quereduzca, para el caso promedio, el n¶umero de comparaciones declaves necesarias para lograr el ordenamiento de la secuencia.

ii) Encuentre una secuencia de entrada que usando la versi¶on modi-¯cada del algoritmo requiera mayor n¶umero de comparaciones declaves que cuando es clasi¯cada con la versi¶on original.

iii) Muestre que si se trata de implementar el m¶etodo deQUICKSORTcalculando en cada paso la elecci¶on del pivote como la medianadel conjunto, el m¶etodo ya no es de orden O(n log(n)).

8. Muestre que si se trata de implementar el m¶etodo de QUICKSORTcalculando en cada paso la elecci¶on del pivote como la mediana delconjunto, el m¶etodo ya no es de orden O(n log(n)).

6.7 Bibliograf¶³a1. AHO, Alfred, HOPCROFT,John & ULLMAN, Je®rey. \Data Struc-

tures and Algorithms". Addison Wesley Series in Computer Science.1985.

2. BAASE, Sara. \Computer Algorithms. Introduction to Design andAnalysis". Addison Wesley Series in Computer Science. 1978.

3. BINSTOCK,Andrew & REX, John. \Practical Algorithms for Pro-grammers". Addison Wesley Series in Computer Science. 1995.

4. CLARK, K.L. & DARLINGTON,J.\Algorithm Clasi¯cation throughSynthesis". The Computer Journal. Vol. 23. No. 1. 1980.

5. GONNET, G.H. & BAEZA-YATES, R. \Handbook of Algorithms andData Structures in Pascal and C". 2ndEd. Addison Wesley Series inComputer Science, 1.991.

6. KNUTH, D. \The Art of Computer Programming, Vol. 3: Sorting andSearching". Addison Wesley Series in Computer Science, 1.973.

TAD Diccionario 103

7. LUCENA, C.J. & PEQUE~NO, T.M. \An approach for Data Type Spe-ci¯cation and its Use in Program Veri¯cation". Information ProcessingLetters. Vol. 8. No. 2. Feb. 1979.

8. WIRTH, Niklaus. \Algorithms and Data Structures". Prentice Hall,1.986.

104

Cap¶³tulo 7

TAD Diccionario

7.1 Marco Conceptual

Consideremos el diccionario de la Real Academia de la Lengua Espa~nola yllam¶emosle C; peri¶odicamente esta instituci¶on incorpora nuevas palabras aC. Tambi¶en hay palabras que caen en desuso y son entonces desincorpora-das de C.

Sin embargo, la mayor utilidad de C y en general del diccionario de cual-quier idioma consiste en que mantiene la relaci¶on existente entre las palabrasy el signi¯cado de cada una de ellas, debido a esto, la operaci¶on que se realizacon m¶as frecuencia sobre un diccionario es la recuperaci¶on del signi¯cadode una palabra. Evidentemente, para poder hacer esto ¶ultimo es necesariosaber cu¶al es la palabra a la que se le va a buscar el signi¯cado.

Si imaginamos una p¶agina de C vemos que las palabras se listan en ordenlexicogr¶a¯co y justi¯cadas a la izquierda. A derecha de cada una de ellasencontramos p¶arrafos donde se dan las diferentes acepciones que puede te-ner. Si consideramos estos p¶arrafos como el signi¯cado de cada palabra,podemos imaginarnos a C como una colecci¶on de pares ordenados de la forma:

(palabra; conjuntodesignif icado)

con la caracter¶istica de que los pares no se repiten y si consideramos laprimera proyecci¶on de un par, palabra, ¶esta no ocurre en ning¶un otro comoprimera proyecci¶on porque s¶olo tiene un signi¯cado (recordemos que todaslas acepciones de una palabra constituyen su signi¯cado). Esta propiedad de

105

106

los pares de la relaci¶on nos dice que m¶as que una relaci¶on, C es una funci¶on.1Ahora bien, as¶³ como hemos hablado del diccionario de un idioma, como unobjeto donde la operaci¶on fundamental es la recuperaci¶on de informaci¶on, po-demos extender esta noci¶on a dominios diferentes al dominio de las palabray sus signi¯cados. Podemos hablar entonces de diccionarios de estudiantesde la USB, de empleados de una empresa, de veh¶³culos registrados en un es-tado, de cursos de una carrera, personas de un pa¶³s, etc. En cada uno de losejemplos antes mencionados observamos el hecho de que estamos hablandode conjuntos, por lo tanto, no existen elementos repetidos. Consideremos eldiccionario de estudiantes de la USB, llam¶emosle EUSB, y supongamos quelas coordinaciones de las diferentes carreras realizan anualmente un proceso(computarizado) que determina para cada estudiante un plan para ¯nalizarla carrera lo antes posible y lo envia a la direcci¶on de habitaci¶on de cadaestudiante. Para realizar el mencionado proceso, es necesario recuperar paracada estudiante, a partir del carnet, toda la informaci¶on necesaria: cursosaprobados, carrera a la que pertenecen y direcci¶on de habitaci¶on. Si utili-zamos nuestro esquema de pares para los elementos de un diccionario, EUSBpuede visualizarse como sigue:

(carnet1; datos1)

(carnet2; datos2)

(carnet3; datos3)

...

(carnetN ; datosN )

La caracter¶³stica que queremos resaltar y que antes no vimos en C es elhecho de que los elementos del dominio de EUSB forman parte de los elementosdel rango, ya que al igual que el nombre, el apellido, la direcci¶on, etc. el carnetes un dato m¶as de un estudiante; en general el rango de un diccionario es de untipo compuesto, por ejemplo, en la informaci¶on de una persona se encuentrasu c¶edula de identidad, nombre, apellido, etc.; en la de un autom¶ovil seencuentra su n¶umero de matr¶³cula, color, modelo, etc.

1Una funci¶on f : A ! B es una relaci¶on binaria, Rf , de A en B tal que para todoa 2 A existe un ¶unico b 2 B para el cual (a; b) 2 Rf . Si existe un elemento en A que noest¶a relacionado con ning¶un elemento de B, entonces f es una funci¶on parcial.

TAD Diccionario 107

Ahora bien, los elementos del dominio de un diccionario no se escogen alazar entre los tipos que componen el tipo del rango, sino que se escoge entrelos que tengan la propiedad de que identi¯ca un¶³vocamente un elemento, locual como ya hemos visto, ocurre con el carnet de los estudiantes, la c¶edulade identidad de las personas, los n¶umeros de matr¶³cula de los veh¶³culos,etc. Usualmente los elementos del dominio de un diccionario se denominanclaves. El tipo del dominio de un diccionario lo llamaremos tipo clave y aldel rango tipo elemento.

En resumen, un diccionario es una colecci¶on de pares ordenados D quesatisfacen la propiedad de ser una funci¶on,

D : TipoClave) TipoElemento

donde la operaciones de insertar nuevos items y recuperar informaci¶on, pue-den interpretarse como de¯nir y aplicar la funcion D, respectivamente. Eloperador eliminar hace inde¯nida la funci¶on D para un punto del dominioTipoClave.

En base a la sem¶antica intuitiva de los operadores, dada arriba, diremosque el TAD Diccionario puede caracterizarse como una extensi¶on del TADFuncion2 con el operador de restricci¶on del dominio de la funci¶on en un punto;se deja al lector como ejercicio la extensi¶on de este TAD.

7.2 Especi¯caci¶on del TAD DiccionarioLa especi¯caci¶on del TAD Diccionario es la siguiente:TDA Diccionario = Funcion[TipoClave; T ipoElemento]Sintaxis

vacio : ) Diccionarioesvacio : Diccionario ) Booleaninsertar : Diccionario£ TipoClave

£TipoElemento ) Diccionarioeliminar : Diccionario£ TipoClave ) Diccionariorecuperar : Diccionario£ TipoClave ) T ipoElemento

Sem¶antica8d 2 Diccionario; e; e1 2 Elemento; e6=Elemento e1;

2Ver la especi¯caci¶on del TAD Funcion[A;B] en la secci¶on 3.5 del cap¶³tulo 3

108

1. vacio = new

2. esvacio(vacio) = true

3. esvacio(insertar(d; k; e)) = false

4. insertar(d; k; e) = def(d; k; e)

5. recuperar(d; k) = aplic(d; k)

6. eliminar(d; k) = restringir(d; k)

Fin-Diccionario;3

7.3 Representaci¶on Mediante Tablas de HashEn la secci¶on anterior, cuando hablamos de las operaciones que caracterizana los diccionarios, dimos par¶ametros de frecuencia de las mismas que nosconviene analizar para determinar si una representaci¶on es adecuada o no:

² insertar y eliminar son operaciones frecuentes.

² recuperar es muy frecuente.

En base a la frecuencia de uso de recuperar, se requiere que esta operaci¶onno se realice por b¶usqueda secuencial, atar¶³amos al tiempo de acceso a serproporcional al tama~no del diccionario. En el caso de la b¶usqueda binaria,se requiere que los elementos est¶en ordenados por la clave. En particular, labase de datos de estudiantes de la USB cuenta con m¶as de 10000 estudiantes.

A continuaci¶on presentamos un esquema de representaci¶on del TAD Dic-cionario conocido como representaci¶on mediante tablas de hash4. La ideab¶asica es que el conjunto de elementos se particiona en clases de equivalencia(disjuntas) mediante la aplicaci¶on de una funci¶on, denominada funci¶on dehash. Por ejemplo, en el caso de C, es posible particionarlo en clases: la clasede las palabras que empiezan con la letra A, la clase de las que empiezan con

3El operador restringir se re¯ere al ejercicio propuesto en la secci¶on de ejercicios delcap¶³tulo 3

4Una traducci¶on de hash (que no usaremos) ser¶³a picadillo

TAD Diccionario 109

la letra B y as¶³ hasta la letra Z, generando 27 clases. Esto se logra aplicandola funci¶on H:

H(amarillo) = AH(borrar) = B

...y as¶³ sucesivamente.

En general, supongamos que podemos particionar los elementos de un dic-cionario mediante la relaci¶on de equivalencia \los elementos con igual imagenbajo la funci¶on de hash". Esta relaci¶on deber¶a crear un n¶umero de clases deequivalencia menor que el universo potencial; estas clases las numeraremosde 0 a M{1.

Para representar un diccionario mediante tablas de hash, necesitamosde¯nir lo siguiente:

² La funci¶on de hash (H).Hasta ahora s¶olo sabemos que 8e 2 Elemento; 0 · H(clave(e)) ·M{1

² Representar las clases. Para representar las clases podemos distinguirdos enfoques:

{ Hashing Abierto.{ Hashing Cerrado.

A continuaci¶on discutiremos cada uno de los enfoques propuestos.

7.3.1 Hashing AbiertoEn el esquema de hashing abierto, puede distinguirse claramente el conjuntocociente y las clases; el conjunto cociente se representa mediante un arreglode M componentes (tantas como clases de equivalencia de¯na la funci¶onde hash), donde cada elemento del arreglo se asocia a una clase, y a su vez,cada clase que puede tener varios miembros, se representa mediante cualquierestructura que sea capaz de almacenar un conjunto.

Type RgoClases = 0..M-1;Clase = Conjunto[Elemento];TablaDeHash = array[RgoClases]of Clase;Diccionario = TablaDeHash;

110

0 1 2 ¢ ¢ ¢ C0 ¢ ¢ ¢1 ¢ ¢ ¢... ¢ ¢ ¢M-1 ¢ ¢ ¢

Tabla 7.1: Almacenamiento

Una posible implementaci¶on es un vector cuyos elementos sean vectores,es decir, las clases se implementan como vectores. Gr¶a¯camente la estructuraes la que se muestra en la tabla 7.1.

Los elementos se asignan en el primer lugar de cada vector, y si est¶aocupado, se recorre el vector horizontalmente buscando una posici¶on vac¶³a.

Otra implementaci¶on posible es la que utiliza representaci¶on din¶amica(listas). Es decir, la tabla de hash ser¶³a un vector de listas donde cada unade ellas representa una clase.

En este ¶ultimo caso, el mecanismo de b¶usqueda de una clave e, ser¶³a elc¶alculo de H(e), lo que dar¶³a acceso a la clase en la cual deber¶³a encontrarseel elemento, y luego se realizar¶³a un recorrido de la lista hasta encontrar elelemento buscado. Debe notarse que en el caso en que la clave buscada nose encuentre en el diccionario, el costo de la b¶usqueda ser¶a proporcional altama~no de la clase de equivalencia donde hubiera estado la clave buscada.

Si las clases son peque~nas con respecto al tama~no total del diccionario,podemos decir que el tiempo de recuperaci¶on es casi constante.

Para obtener un buen comportamiento de las operaciones con esta repre-sentaci¶on es necesario elegir H de forma tal que cada clase de equivalenciatengan m¶as o menos el mismo tama~no, es decir que los elementos del diccio-nario est¶en uniformemente distribu¶³dos entre las clases. Otra cosa deseablees que las clases no sean demasiado grandes. Si las condiciones anteriores sedan y el diccionario tiene N elementos, cada clase tendr¶a en promedio N=Melementos y este es el tama~no del conjunto donde se realizar¶a la b¶usqueda.

Este modelo de organizaci¶on de datos requiere la utilizaci¶on de listas ypor lo tanto, manejo din¶amico de memoria, por lo que hay un incremento enel uso de memoria. Es bueno recordar que el almacenamiento en vectores eslo m¶as econ¶omico como forma de guardar informaci¶on ya que no hace uso de

TAD Diccionario 111

memoria adicional al requerido para guardar los datos.

7.3.2 Hashing Cerrado

En este modelo, se almacenan todas las entradas del diccionario en un vector,usando la funci¶on de hashing para determinar la posici¶on en el vector dondeuna entrada ser¶a colocada. Debido a que las clases de equivalencia de clavesde¯nidas por la funci¶on no son en general de tama~no unitario, se producir¶ancolisiones, lo que corresponde a tener varias claves que pretenden ocupar lamisma posici¶on.

Bajo este enfoque, no hay una diferenciaci¶on entre el conjunto cociente ylas clases ya que los elementos del diccionario se almacenan dentro del arreglo.Esta representaci¶on presenta el problema de las colisiones ya que cuando doselementos tienen la misma imagen bajo la funci¶on de hash, s¶olo uno de los dospuede ser almacenado en esa posici¶on del arreglo (el primero que encontr¶ola posici¶on vacia). Para resolver este problema, se de¯ne una secuencia defunciones de rehash, mediante las cuales se examinan otras posiciones dentrodel arreglo hasta encontrar una que est¶e vacia, donde ¯nalmente se coloca elelemento. Si no se encuentra ninguna posici¶on vacia no ser¶a posible hacer lainserci¶on.

Type RgoEntradas = 0..K-1; (* K > M *)TablaDeHash = array[RgoEntradas]of Elemento;Diccionario = TablaDeHash;

A continuaci¶on presentamos algunos m¶etodos para resolver colisiones me-diante rehashing:

1. Prueba LinealEste m¶etodo de soluci¶on de colisiones consiste en tener una funci¶on dehash (H0) y si hay colisi¶on, intentar en posiciones contiguas conside-rando el arreglo como un anillo (la posici¶on contigua a M{1 es 0).

H0(e) = H(e)

Hi(e) = (H0(e) + i)modM; i > 0 (7.1)

112

0 1 2 3 4 5 6 7 8 911 50 23 15 24 14y2 y1 y3 y4 y5 y6

Tabla 7.2: Almacenamiento de valores

Esta funci¶on presenta el problema de que no distribuye los elementosuniformemente en la tabla y puede ocurrir que parte del arreglo est¶evac¶³a y otra muy llena; sin embargo, el tama~no total del diccionario est¶alimitado por el tama~no del vector. Consideremos el siguiente ejemplo:sea D un diccionario de a lo sumo 10 elementos, representando me-diante una tabla de hashing cerrado, cuyas claves tienen un m¶aximode dos d¶³gitos decimales, denominados d1 y d0. La funci¶on de hashcorrespondiente es

H0(10d1 + d0) = (d1 + d0)mod 10;

y Hi es como (7.1). Si los elementos se ingresan en el siguiente orden

(50; y1); (11; y2); (23; y3); (15; y4); (24; y5); (14; y6)

donde yi corresponde a la informaci¶on asociada a la clave, el vectorresultante es el que se muestra en la tabla 7.2.

Es de hacer notar que si bien la clase de equivalencia de

H0(14) = H0(23) = H0(50) = 5;

es de tama~no 3, la recuperaci¶on de la clave 14, requiere 5 comparacionesde claves.

2. Prueba Cuadr¶atica

H0(e) = H(e)

Hi(e) = (H0 + i2) mod M, i > 0

el vector resultante es el que se muestra en la tabla 7.3.

TAD Diccionario 113

0 1 2 3 4 5 6 7 8 924 11 50 23 15 14y5 y2 y1 y3 y4 y6

Tabla 7.3: Resultado

No hay demasiada diferencia entre las tablas usando el hashing lineal ocuadr¶atico, sin embargo puede notarse, a¶un en un ejemplo tan peque~noque en el hashing lineal las clases quedan pegadas entre si mientras queen el hashing cuadr¶atico hay mayor dispersi¶on de claves. Esto hace quelas b¶usquedas en cada clase se hagan mas cortas.

Una desventaja de esta funci¶on de rehash es que no todas las posicionesson revisadas para insertar, por lo tanto podr¶³a darse el caso de nopoder insertar un elemento aunque hubiera espacio disponible. Unacaracter¶³stica deseable para este tipo de hashing es que el porcentajede llenado de la tabla no supere el 50% del total de la misma.

7.4 Res¶umen del cap¶³tulo 7

Hemos visto un m¶etodo de organizar un conjunto de elementos que poseenla caracter¶³stica que el conjunto tiene escaso crecimiento, escaso respecto ala frecuencia de utilizaci¶on del operador de recuperaci¶on o b¶usqueda.

El esquema presentado en este cap¶³tulo logra un tiempo constante (inde-pendiente del tama~no del conjunto) para la operci¶on de b¶usqueda. Esto esparticularmente promisorio para conjuntos muy grandes. No debemos dejar-nos llevar por el entusiasmo y aceptar que este m¶etodo es el mejor ya quepresenta la mas baja complejidad respecto a los otros m¶etodos. Esta orga-nizaci¶on requiere caracter¶³sticas de la claves que nos permitan establecer lafunciones de hashing ( y eventualmente de rehashing) que logren alcanzar lacomplejidad anunciada para la operaci¶on de b¶usqueda. Otro inconvenientea tener en consideraci¶on al momento de elegir este m¶etodo de representa-ci¶on es el manejo del crecimiento del conjunto. En particular los conjuntosorganizados con este m¶etodo en una aplicaci¶on tienen la particularidad queel comportamiento del operador de b¶usqueda puede degradarse con la uti-lizaci¶on de la aplicaci¶on, principalmente debido a ingresos. Es por eso queaplicaciones que incluyan datos organizados por hashing deben ser monito-

114

reados (administradas) en su comportamiento, veri¯cando que las hip¶otesissobre los datos se mantienen a pesar de los ingresos, que la bondad de lasfunciones sigue siendo v¶alida y eventualmente realizar operaciones de man-tenimiento que pueden pasar por la reorganizaci¶on de los datos o el cambiode las funciones de hashing (las funciones de rehashing).

El el cap¶³tulo 8 se revisan organizaciones de conjunto que son menossensibles al crecimiento (decrecimiento) del conjunto sobre el cual se realizala b¶usqueda.

7.5 Ejercicios1. Calcular el n¶umero de palabras posibles de no m¶as de 14 letras.

2. Veri¯car el n¶umero de palabras que est¶an de¯nidas en su diccionariofavorito.

3. Considere la siguiente representaci¶on para el TAD Diccionario:

Type Diccionario = array[0..10] of Elemento;

con la siguiente funci¶on de hash: H0(e) = e2 mod 11

(a) Construya la tabla de hash abierta para los siguientes elementos:

0,6,7,5,8,2,1,4,3

(b) Con los mismos elementos de (a), construya la tabla de hash ce-rrada, considerando para el rehashing el m¶etodo de prueba lineal.

(c) C¶omo se alterar¶³a (b) si se utiliza para el rehashing el m¶etodo deprueba cuadr¶atica.

4. Hasta ahora se ha especi¯cado el TAD Diccionario como una especia-lizaci¶on del TAD Funcion[A;B]. >Cu¶al es la diferencia si se especi¯cacomo una especializaci¶on del TAD Conjunto[Elemento]?.

5. Supongamos que se mantiene el diccionario de estudiantes de la USB,representado mediante hashing abierto, donde las claves vienen dadaspor los carnets. Suponga adem¶as que 1=3 de los estudiantes est¶ancursando el ciclo b¶asico.

TAD Diccionario 115

(a) De¯na una funci¶on de hash que agrupe a todos los estudiantes delciclo b¶asico en la misma clase de equivalencia.

(b) De¯na una funci¶on de hash que distribuya la informaci¶on de losestudiantes \aleatoriamente" en la tabla de hash que representael diccionario.

(c) Compare las funciones de¯nidas en (a) y (b).

(d) Implemente las funciones de¯nidas en (a) y (b) utilizando hashingabierto y hashing cerrado con prueba lineal.

6. Considere los siguientes m¶etodos de hashing:

(i) M¶etodo de la Divisi¶on (Hd):Hd se obtiene tomando el resto de dividir la suma de los d¶³gitosde la clave por M. Es decir, Hd(clave) 2 f0; :::;M ¡ 1g. Es decir:Si clave = dn10n + ::: + d110 + d0 entonces

Hd(clave) = (Pni=0 di) mod M

(ii) Midsquare Hashing (Hm):

(ii.1) Elevar al cuadrado parte de la clave, o la clave completa si esposible.

(ii.2a) Extraer n d¶³gitos decimales a partir de la mitad del resultadode (ii.1) para obtener Hm(clave) 2 f0; 1; :::; 10n ¡ 1g.

(ii.2b) Extraer n bits a partir de la mitad del resultado de (ii.1) paraobtenerHm(clave) 2 f0; 1; :::; 2n ¡ 1g.

(iii) Folding (Hf):Se divide la clave en varias partes que luego se suman para obtenerHf en el rango deseado. Por ejemplo si deseamos Hf de dos d¶³gitosy la clave tiene siete, hacemos lo siguiente:

Hf(1761439) = 17 + 61 + 43 + 9 = 30

N¶otese que el d¶³gito de 10n, donde n es el n¶umero de d¶³gitos de-seados, se ignora.

(a) Implemente los m¶etodos de hashing descritos arriba.

(b) Compare el resultado de aplicar ¶estos m¶etodos a un conjunto declaves dado. Cu¶al m¶etodo distribuye mejor?

116

7. El Sistema nacional de Bibliotecas (SNB), ha decidido ofrecer a sususuarios un nuevo servicio llamado Pr¶estamos a Distancia, que con-siste en poner a la disposici¶on no s¶olo los t¶³tulos que se encuentran enla Biblioteca Central, sino tambi¶en los que se encuentran en cada unade las bibliotecas adscritas al sistema. Ya han resuelto los problemasde env¶³o y transporte de libros, pero se han dado cuenta que debenorganizar adecuadamente la informaci¶on. Lo primero que han hecho escodi¯car las diferentes bibliotecas del pa¶³s, adscritas o no, as¶³ como lost¶³tulos para identi¯carlos univocamente. Con esto podr¶an ofrecer uncat¶alogos de bibliotecas y de t¶³tulos, donde se pueden consultar dichosc¶odigos.

El paso siguiente es la automatizaci¶on de los procesos de mantenimientoy consulta de la informaci¶on, para lo cual el SBN ha solicitado sucolaboraci¶on. La idea es que Ud. les d¶e una soluci¶on desde el punto devista computacional para:

(a) Mantener la informaci¶on: ingreso y desincorporaci¶on de t¶³tulos yejemplares.

(b) Consultar si una biblioteca determinada est¶a adscrita o no al SBN.

(c) Consultar si un t¶³tulo est¶a disponible o no, para hacer la solicitudde pr¶estamo.

Ud. debe considerar la siguiente pol¶³tica:

Es preferible aumentar la cantidad de t¶³tulos en cada biblioteca y res-tringir el n¶umero de adscripciones al SBN (presuponiendo que es muycostoso expandir la red de transporte).

² Una biblioteca s¶olo puede prestar un libro a distancia si tiene m¶asde un ejemplar del mismo.

² Hay M bibliotecas adscritas al SBN.

² Cada biblioteca tiene a lo sumo N t¶³tulos diferentes.

² M<< N.

² Es muy frecuente la incorporaci¶on de nuevos t¶³tulos en una bi-blioteca, aunque en menor que 1=3 del n¶umero de consultas.

² La incorporaci¶on de bibliotecas al SBN es bajo.

TAD Diccionario 117

(a) Analice la pol¶³tica dada.

(b) Adoptando la pol¶³tica, suponga que adem¶as de consultar las biblio-tecas y los libros por sus c¶odigos, se desea hacer las consultas pornombres y autores, respectivamente. Proponga una soluci¶on paraeste problema utilizando tablas de hash. Justi¯que con par¶ametrosnum¶ericos y la relaci¶on entre ellos su soluci¶on.

7.6 Bibliograf¶³a1. AHO, Alfred, HOPCROFT, John & Ullman,Je®rey. \ Data Structures

and Algorithms". Addison Wesley Series in Computer Science.1985

2. BERZTISS, A.T.\Data Structures. Theory and Practice".AcademicPress.

3. CAIRO, O. & GUARDATI, S. \Estructuras de Datos". McGraw-Hill.1.993.

4. GONNET,G.H. & BAEZA-YATES, R. \Handbook of Algorithms andData Structures. In PASCAL and C. 2nd Ed. Addison Wesley.

5. WIRTH, Nicklaus. \Algorithms+Data Structures= Programs".PrenticeHall.

118

Cap¶³tulo 8

¶Arboles

8.1 Marco Conceptual

Algunas veces, cuando modelamos una situaci¶on encontramos que la mejormanera de representar la relaci¶on que existe entre los objetos involucradoses mediante una estructura jer¶arquica, como vemos en la ¯gura 8.1. Tales el caso de la relaci¶on entre las diferentes unidades administrativas, quedescribe una organizaci¶on tradicional, llamada organigrama. Otro ejemplolo podemos ver en el ¶arbol geneal¶ogico de una persona, que vemos en la ¯gura8.2 donde A es hijo de B y C, teniendo como abuelos a D,E,F y G . Asimismopuede servir para organizar los elementos de un conjunto de manera de poderrealizar operaciones sobre el mismo de manera m¶as e¯ciente.

Este tipo de estructuras jer¶arquicas recibe el nombre de ¶arbol. En el casode un organigrama observamos que en cada nivel del mismo se encuentran,por lo general, m¶as de dos unidades administrativas, por lo que se conocecomo ¶arbol M-ario. El ¶arbol geneal¶ogico, en que cada individuo esta repre-sentado por un elemento del ¶arbol, relacionandose con su padre y madre esun ¶arbol binario (2-ario).

En los ejemplos mencionados arriba notamos que es irrelevante el ordenen el que ocurren los objetos de cada nivel, por lo que se conocen como ¶arbolesno ordenados.1

Formalmente un ¶arbol M-ario no ordenado podemos modelarlo como una

1Podemos considerar a un ¶arbol como un conjunto de elementos y una relaci¶on parti-cular sobre el producto cartesiano.

119

120

Figura 8.1: Organigrama

secuencia heterog¶enea 2 de dos elementos. A continuaci¶on daremos una de-¯nici¶on recursiva.

De¯nici¶on: ¶Arbol M-ario no ordenado:

(i) La secuencia vac¶³a (<>) corresponde al ¶arbol nulo no ordenado.

(ii) Sea e un elemento del dominio y a1; :::; aM ¶arboles M-arios no orde-nados, entonces, la secuencia a =< e; [a1; :::; aM ] >, donde [a1; :::; aM ]denota un multiconjunto de ¶arboles, es un ¶arbol N-ario no ordenado yse de¯nen las siguientes relaciones:

{ e es la ra¶³z de a.

{ 8 1 · i ·M , ai es un sub¶arbol de a.

2Heterog¶eneas en el sentido de los elementos pueden ser de tipos diferentes.

¶Arboles 121

Figura 8.2: ¶arbol geneal¶ogico

{ 8 1 · i ·M e es padre de la ra¶³z de ai.

{ 8 1 · i ·M la ra¶³z de ai es hijo (sucesor) de e.

(iii) S¶olo son ¶arboles no ordenados los objetos generados a partir de (i) yde (ii).

En la de¯nici¶on anterior notamos que los sucesores est¶an organizadoscomo un multiconjunto. Sin embargo, si consideramos el ¶arbol asociado auna expresi¶on algebraica en la que cada nodo con hijos es el padre de susoperandos (sean ¶arboles o variables simples), nos damos cuenta de que en esecaso es importante el orden en que se colocan los argumentos ya que paralos operadores no conmutativos es importante distinguir cual es el primeroperando y cual es el segundo. Otro ejemplo de esto es el ¶arbol asociadoa una instrucci¶on condicional if(b; s1; s2). Si consideramos s1 y s2 comoexpresiones algebraicas y b como una expresi¶on booleana, el operador ifpuede considerarse como un operador ternario, siendo s1 el resultado en elcaso en que la expresi¶on b resulte verdadera y s2 en el caso contrario. Estetipo de ¶arboles se denominan ¶arboles ordenados. Para los ¶arboles ordenados

122

es conveniente organizar a los sucesores como una secuencia, debido a que enellas es importante la posici¶on en que los elementos ocurren. En el caso delif ser¶³a: < if;< b; s1; s2 >>, con lo cual tenemos la siguiente de¯nici¶on:

De¯nici¶on: ¶Arbol M-ario ordenado:

(i) La secuencia vac¶³a (<>) corresponde al ¶arbol ordenado nulo.

(ii) Sea e un elemento del dominio y a1; :::; aM ¶arboles M-arios ordenados,entonces, la secuencia a =< e;< a1; :::; aM >> es un ¶arbol M-arioordenado y se de¯nen las mismas relaciones de la de¯nici¶on anterior.

(iii) S¶olo son ¶arboles ordenados los objetos generados a partir de (i) y de(ii).

En este cap¶³tulo s¶olo nos ocuparemos de los ¶arboles ordenados, por lo cualutilizaremos el modelo donde los sucesores est¶an representados mediante unasecuencia.

8.2 Especi¯caci¶on del TAD Arbol (¶Arboles Or-denados)

Para de¯nir el TAD Arbol requerimos adem¶as del TAD Secuencia visto enel cap¶³tulo 4, el TAD SecHet cuyos valores son secuencias heterog¶eneas.ESPSecHet es igual a ESPSecuencia modi¯cando el conjunto de dominios Da la uni¶on de todos los dominios que intervienen. En el caso de los ¶arboleslos dominios de ESPSecHet ser¶an secuencias formadas por elementos y se-cuencias de ¶arboles.En el resto de este cap¶³tulo utilizaremos opH para denotar los operadores delTAD SecHet.

Como los ¶arboles son una especializaci¶on de las secuencias heterogeneas,usaremos para de¯nir los operadores, los operadores de las secuencias hete-rogeneas.

8.2.1 ¶Arboles OrdenadosTAD Arbol < SecHet[Elemento; Secuencia[Arbol]]

D = fArbol; SecHet; Secuencia; Boolean;Elementog

¶Arboles 123

Sintaxis

nulo : ) Arbolesnulo : Arbol ) Booleancreararbol : Elemento£ Secuencia ) Arbolraiz : Arbol ) Elementosucc : Arbol ) Secuencia#elem : Arbol ) Naturaleshoja : Arbol ) Booleanaltura : Arbol ) Natural

Sem¶antica8a; a1 2 Arbol; s : Secuencia; e 2 Elemento; a1 6= nulo;

1. longH(a) = 0 _ longH(a) = 2

2. nulo = vaciaH

3. esnulo(a) = esvaciaH(a)

4. creararbol(e; s) = insertarH(insertarH(vaciaH ; 1; e); 2; s)

5. :(esnulo(a1))! raiz(a1) = proyectarH(a1; 1)

6. :(esnulo(a1))! succ(a1) = proyectarH(a1; 2)

7. eshoja(nulo) = false

8. :esnulo(a)! eshoja(a) = false

9. long(proyectarH(a; 2)) = 0! eshoja(a) = true

10. eshoja(a) =Vlong(succ(a))i=1 proyectar(succ(a); i) = nulo

11. #elem(nulo) = 0

12. #elem(a1) = 1 +Plong(succ(a1))i=1 #elem(proyectar(succ(a1); i))

13. eshoja(a1)! altura(a1) = 0

14. :(eshoja(a1))!altura(a1) = 1 +max(i=1;long(succ(a1))(altura(proyectar(succ(a1); i)))

124

Fin-Arbol;El ¶arbol geneal¶ogico de la ¯gura 8.2 es un ¶arbol de altura 2.

Puede notarse que estamos usando en la especi¯caci¶on la propiedad quelos operadores sum y max no ser¶an evaluados cuando el l¶³mite superior seainferior al l¶³mite inferior, dando como resultado de la evaluaci¶on cero (elneutro de la suma).

8.2.2 Conceptos de ¶arbolesAlgunos conceptos importantes relacionados con los ¶arboles son los siguien-tes:

Grado : El grado de un ¶arbol se re¯ere al n¶umero de hijos que tiene elelemento con m¶as sucesores. Cuando hablamos de ¶arboles M-arios, estamossuponiendo que el elemento con m¶as sucesores tiene M hijos, por lo tanto elgrado es M.

Nivel : Un nivel de un ¶arbol se re¯ere a un estrato de la estructurajer¶arquica. Dependiendo de la convenci¶on que se tome, el nivel donde seencuentra la ra¶³z, es el nivel 0 o el nivel 1. En este libro usaremos como nivelde la ra¶³z cero.

¶Arbol Completo : Un ¶arbol es completo si el n¶umero de hijos de cadaelemento es igual al grado del ¶arbol. Un ¶arbol como el que presentamos enla ¯gura 8.3 tiene en el i¶esimo nivel M i elementos, por lo tanto el n¶umero deelementos del ¶arbol es igual a

N =kX

i=0M i = (Mk+1 ¡ 1)=(M ¡ 1)

donde k corresponde a la altura del ¶arbol.

8.3 Recorrido en ¶ArbolesConsideremos nuevamente el ejemplo del organigrama y supongamos quequeremos obtener todas las unidades administrativas que constituyen la orga-nizaci¶on que representa. Para obtenerlas, debemos revisar el ¶arbol de alguna

¶Arboles 125

Figura 8.3: ¶arbol de altura 2

manera y listar cada una de las ra¶³ces de los sub-¶arboles. Esta operaci¶on seconoce como recorrido de un ¶arbol. Existen diversas maneras de realizar elrecorrido, pero en general, un recorrido es una funci¶on que va de ¶arboles enlistas de elementos donde cualquier lista de los elementos que ocurren en el¶arbol es considerada un recorrido3:

recorrido : Arbol ) lista[Elemento]

Para especi¯car la sem¶antica de esta operaci¶on, debemos extender el TADArbol con una operaci¶on que permita determinar si un elemento ocurre o noen un ¶arbol:

ocurre : Arbol £ Elemento) Boolean

Con la siguiente sem¶antica:

² ocurre(nulo; e) = false

² ocurre(a; e) = (e = raiz(a))_ Wlong(succ(a))i=1 ocurre(proyectar(succ(a); i); e)

Una vez extendido el TAD Arbol con el operador ocurre podemos esta-blecer la sem¶antica de recorrido4:

8a(8e (ocurre(a; e)! 9i (scan(recorrido(a); i)) = e))^len(recorrido(a)) ¸ #elem(a))

3Ver la especi¯caci¶on del TAD Lista en el cap¶³tulo 3.4scan(l,i) es un operador que extiende el TAD Lista y que devuelve el elemento que

ocupa la i-¶esima posici¶on en la lista l.

126

N¶otese que con esta sem¶antica de la operaci¶on recorrido estamos pidiendoque todos los elementos de ¶arbol est¶en en la lista resultante y adem¶as estamosadmitiendo como un recorrido de un ¶arbol cualquier lista de los elementosque ocurran en ¶el, a¶un cuando la longitud de esta sea mayor que su n¶umerode elementos, lo cual signi¯ca que se est¶an repitiendo algunos o cada uno deellos.

Como dijimos anteriormente, hay varias maneras de realizar el recorrido.En este cap¶³tulo nos interesaremos en tres m¶etodos espec¶³¯cos que retornanuna lista con los elementos del ¶arbol (sin repetici¶on). Los m¶etodos a loscuales nos referimos son conocidos como preorden, postorden e inorden.

Debido a que cuando se realiza un recorrido se \visitan" todos los ele-mentos ya que tenemos el operador raiz para \visitar" a la ra¶³z de un ¶arbolpero no tenemos un operador del TAD Arbol para acceder a cada uno de lasraices de los sucesores. Es por eso que de¯niremos una funci¶on para reali-zar la operaci¶on en cada uno de las formas de recorrido que ser¶an revisados,que retorna una lista con los elementos (sin repetici¶on) de cada uno de lossub¶arboles. Estos operadores son VisitarPre,VisitarPost y VisitarIn, cuya¯rma damos a continuaci¶on

V isitarPre; V isitarPost;V isitarIn : Secuencia[Arbol] ) Lista[Elemento]

La sem¶antica de cada uno de estos operadores se dar¶a con el m¶etodo.

8.3.1 Recorrido en Preorden

Recorrido en Preorden Consiste en listar primero la ra¶³z del ¶arbol yluego los elementos en los sub¶arboles sucesores en el orden en el cual ocurren.

² esvacia(succ(a))!preorden(a) = cons(raiz(a); null)

² :esvacia(succ(a))!preorden(a) = cons(raiz(a); V isitarPre(succ(a)))

² esvacia(s)! V isitarPre(s) = null

¶Arboles 127

² :esvacia(s)!V isitarPre(s) = append(preorden(proyectar(s; 1));V isitarPre(eliminar(s; 1)))

8.3.2 Recorrido en Postorden

Recorrido en Postorden Consiste en listar primero los elementos en lossub¶arboles sucesores en el orden en el cual ocurren y luego la ra¶³z.

² esvacia(succ(a))!postorden(a) = cons(raiz(a); null)

² :esvacia(succ(a))!postorden(a) = append(V isitarPost(succ(a)); cons(raiz(a); null))

² esvacia(s)! V isitarPost(s) = null

² :esvacia(s)!V isitarPost(s) = append(postorden(proyectar(s; 1));V isitarPost(eliminar(s; 1)))

8.3.3 Recorrido en Inorden

Recorrido en Inorden Consiste en listar primero los elementos del sub¶arbolsucesor que se encuentran al principio de la secuencia de sucesores, luego lara¶³z y ¯nalmente, los elementos en el resto de los sub¶arboles sucesores.

² esvacia(succ(a))!inorden(a) = cons(raiz(a); null)

² :esvacia(succ(a))!inorden(a) = append(inorden(proyectar(succ(a; 1))); cons(raiz(a);V isitarIn(eliminar(succ(a); 1))))

² esvacia(s)! V isitarIn(s) = null

² :esvacia(s)!V isitarIn(s) = append(inorden(proyectar(s; 1));V isitarIn(eliminar(s; 1)))

128

En la siguiente secci¶on de este cap¶³tulo, presentaremos los ¶arboles binariosy algunas especializaciones de los mismos; estas especializaciones se har¶ande¯niendo cada operador en t¶erminos del TAD m¶as general, y a~nadiendolos axiomas que de¯nen el comportamiento particular, que denominaremosAxiomas de Comportamiento.

8.4 ¶Arboles BinariosUn ¶arbol binario es un ¶arbol ordenado constituido por una ra¶³z y dos sub¶arbolesbinarios, por lo tanto, los modelaremos como secuencias heterog¶eneas de laforma

< e;< a1; a2 >>

donde e 2 Elemento y < a1; a2 > es una secuencia de dos ¶arboles binarios,donde la primera proyecci¶on la llamaremos izq y la segunda der. N¶oteseque por ser los ¶arboles binarios ordenados, la secuencia de sucesores debe servacia o debe tener los dos sub¶arboles. Un ejemplo t¶³pico de ¶arbol binario esel ¶arbol asociado a una expresi¶on booleana, donde la m¶axima aridad de losoperadores es igual a dos.

TDA ArbolBinario < Arbol[Elemento]

D = fArbolBinario; Boolean;Elementog

Sintaxis

nulo : ) ArbolBinarioesnulo : ArbolBinario ) Booleancrearbin : Elemento£ Secuencia ) ArbolBinarioraiz : ArbolBinario ) Elementoizq; der : ArbolBinario ) ArbolBinario

Sem¶anticae 2 Elemento; s 2 Secuencia[ArbolBinario];

esvacia(s) _ long(s) = 2

crearbin(e; s) = creararbol(e; s)

¶Arboles 129

izq(creararbol(e; s)) = proyectar(s; 1)

der(creararbol(e; s)) = proyectar(s; 2)

...

Fin-ArbolBinario;

Los puntos suspensivos se re¯eren a los operadores #elem, eshoja y altura ylos axiomas correspondientes se dejan como ejercicio al lector.

Convenci¶on: Debido a que la secuencia de sucesores tiene a lo sumo lon-gitud 2, simpli¯caremos la notaci¶on de secuencia para los sucesores. En lade¯nici¶on de un ¶arbol binario se debe indicar entonces los dos sub¶arbolesaunque sean nulos y la ra¶³z. Nos queda entonces la siguiente especi¯caci¶on:

TDA ArbolBinarioSintaxis

nulo : ) ArbolBinarioesnulo : ArbolBinario ) Booleancrearbin : Elemento£ ArbolBinario ) ArbolBinario

£ArbolBinarioraiz : ArbolBinario ) Elementoizq; der : ArbolBinario ) ArbolBinario

Sem¶antica8b1; b2 2 ArbolBinario; e 2 Elemento; s 2 Secuencia[ArbolBinario];

raiz(crearbin(e; b1; b2)) = e

izq(crearbin(e; b1; b2)) = b1

der(crearbin(e; b1; b2)) = b2

...

Fin-ArbolBinario;

130

Implementaci¶on del TAD ArbolBinario[Elemento]: Al pensar en im-plementaciones de ¶arboles, en particular binarios, debemos pensar en estruc-turar cada elemento del conjunto como una terna. En la primera componentecolocaremos el elemento del conjunto y en las dos siguientes las referenciasa los ¶arboles correspondientes. Estas referencias pueden ser posiciones dememoria (apuntadores) (al estilo PASCAL) o posiciones dentro de un vectorque almacena los elementos (enteros) o ¶arboles (al estilo JAVA).

A continuaci¶on presentamos una implementaci¶on del TAD ArbolBinariohaciendo uso de memoria din¶amica.

type ArbolBinario = ^NodoArbol;NodoArbol = record

elem: Elemento;izq, der: ArbolBinario

end;

En el ap¶endice A se encuetran las implementaciones de los operadores delTDA ArbolBinario

8.4.1 ¶Arboles Binarios de B¶usqueda

Un ¶arbol binario de b¶usqueda, tambi¶en conocido como ¶arbol de b¶usqueda,es aquel donde la ra¶³ces del sub¶arbol izquierdo y derecho son menor y ma-yor, respectivamente que la ra¶³z del ¶arbol, seg¶un la relaci¶on Á, y ambossub¶arboles son ¶arboles de b¶usqueda. Dado que estos objetos deben mante-ner su organizaci¶on en relaci¶on al orden, surge la necesidad de dos nuevosoperadores, insertarbol y eliminarbol, para permitir el ingreso y el egreso deelementos en el ¶arbol. N¶otese que si mantuvieramos el operador crearbincorrer¶³amos el riesgo de perder la organizaci¶on de ¶arbol de b¶usqueda. Comosu nombre lo indica, los ¶arboles de b¶usqueda son objetos que permiten man-tener y recuperar informaci¶on. Los operadores mencionados anteriormenteest¶an orientados al mantenimiento. Para recuperar se dispone del operadorbuscarbol. Recordemos que un ¶arbol de b¶usqueda es una forma de organizarun conjunto en que los elementos admiten una relaci¶on de orden total. De lamisma manera se puede utilizar los ¶arboles para almacenar multiconjuntos,admitiendo la presencia de claves repetidas.

¶Arboles 131

TAD ArbolBusqueda < ArbolBinario[Elemento]Sintaxis

nulo : ) ArbolBusquedaesnulo : ArbolBusqueda ) Booleaninsertarbol : ArbolBusqueda£ Elemento ) ArbolBusquedaeliminarbol : ArbolBusqueda£ Elemento ) ArbolBusquedabuscarbol : ArbolBusqueda£ Elemento ) ArbolBusquedaraiz : ArbolBusqueda ) Elementoizq; der : ArbolBusqueda ) ArbolBusquedanumnodos : ArbolBusqueda ) Naturaleshoja : ArbolBusqueda ) Booleanaltura : ArbolBusqueda ) Naturalmax : ArbolBusqueda ) Elemento

Sem¶antica:::b 2 ArbolBusqueda; b6= nulo;

² Axioma de Comportamiento

a. :esnulo(izq(b)) ^ :esnulo(der(b))!raiz(izq(b)) Á raiz(b) ¹ raiz(der(b))

b. :esnulo(izq(b) ^ esnulo(der(b))!raiz(izq(b)) Á raiz(b))

c. esnulo(izq(b)) ^ :esnulo(der(b))!raiz(b) ¹ raiz(der(b))

² insertarbol(nulo; e) = crearbin(e; nulo; nulo)

² e Á raiz(b)!insertarbol(b; e) = crearbin(raiz(b); insertarbol(izq(b); e); der(b))

² raiz(b) ¹ e!insertarbol(b; e) = crearbin(raiz(b); izq(b); insertarbol(der(b); e))

² buscarbol(nulo; e) = nulo

² raiz(b) = e! buscar(b; e) = b

² raiz(b) Á e! buscarbol(b; e) = buscarbol(der(b); e)

132

² e Á raiz(b)! buscarbol(b; e) = buscarbol(izq(b); e)

² eliminarbol(nulo; e) = nulo

² raiz(b) Á e ^ :esnulo(der(b))!eliminarbol(b; e) = crearbin(raiz(b); izq(b)); eliminarbol(der(b); e)))

² raiz(b) Á e ^ esnulo(der(b))!

eliminarbol(b; e) = b

² e Á raiz(b) ^ :esnulo(izq(b))!eliminarbol(b; e) = crearbin(raiz(b); eliminarbol(izq(b); e); der(b)))

² e Á raiz(b) ^ esnulo(izq(b))!

eliminarbol(b; e) = b

² e = raiz(b) ^ eshoja(b)! eliminarbol(b; e) = nulo

² (e = raiz(b) ^ :eshoja(b))!

(:esnulo(izq(b)) ^ :esnulo(der(b))!eliminarbol(b; e) = crearbin(max(izq(b)); eliminarbol(izq(b);max(izq(b))); der(b)))

^(esnulo(izq(b)) ^ :esnulo(der(b))!eliminarbol(b; e) = der(b))

^(:esnulo(izq(b)) ^ esnulo(der(b))!eliminarbol(b; e) = izq(b))

² eshoja(b) _ (:eshoja(b) ^ esnulo(der(b)))!max(b) = raiz(b)

² :eshoja(b) ^ :esnulo(der(b))!max(b) = max(der(b))

Fin-ArbolBusqueda;

¶Arboles 133

Implementaci¶on del TAD ArbolBusqueda[Elemento]: La implementa-ci¶on del TAD ArbolBusqueda, basada en el TAD ArbolBinario, se encuentraen el ap¶endice A.

Si consideramos un ¶arbol de b¶usqueda completo tenemos que el n¶umerode elementos es

N =kX

i=02i = 2k+1 ¡ 1

por lo que la altura k = O(log2(N)), lo que nos asegurarar¶³a el mismo ordenpara las operaciones insertarbol, eliminarbol y buscarbol. El problema est¶aen que estos operadores no garantizan que los ¶arboles de b¶usqueda creadossean completos, en particular una secuencia de inserci¶on de claves en ordencreciente hace que el ¶arbol de b¶usqueda sea un ¶arbol degenerado (los ¶arbolesizquierdos son siempre ¶arboles nulos). Para aprovechar el orden log2(N )que puede lograrse, surge la familia de ¶arboles de b¶usqueda equilibrados queestudiaremos en la siguiente secci¶on.

8.4.2 ¶Arboles Equilibrados

Dentro de los ¶arboles de b¶usqueda nos interesan aquellos que veri¯can quelos sub¶arboles tienen alturas similares. Esto requiere que la inserci¶on y laeliminaci¶on de elementos preserve la propiedad que el ¶arbol izquierdo y de-recho poseen alturas similares. Dos subclases de estos son los ¶arboles AVL ylos ¶arboles perfectamente balanceados. Estas estructuras particulares tienenla propiedad que el costo de mantener el equilibrio entre los subarboles noresulta demasiado costoso.

TAD ArbolAVL

Un ¶arbol AVL 5 es un ¶arbol de b¶usqueda donde las alturas de los sub¶arbolesizquierdo y derecho di¯eren a lo sumo en 1 y ambos son ¶arboles AVL. Verla Figura 8.4. En los ¶arboles AVL debemos asegurar que las eliminaciones ylas inserciones preserven la propiedad de AVL. Se introduce una operaci¶onbalancear que se aplica a ¶arboles de b¶usqueda que resultan de haber insertado(eliminado) un elemento a un ¶arbol AVL y como resultado de esa inserci¶on(eliminaci¶on) han perdido la propiedad de ser AVL.

5En los ¶arboles AVL, la altura del ¶arbol nulo es cero y la de una hoja es 1.

134

Figura 8.4: ¶Arbol AVL de 5elementos

TAD ArbolAV L < ArbolBusqueda[Elemento] Sintaxis

nulo : ) ArbolAV Lesnulo : ArbolAV L ) BooleaninsertarAV L : ArbolAV L£ Elemento ) ArbolAV LeliminarAV L : ArbolAV L£ Elemento ) ArbolAV LbuscarAV L : ArbolAV L£ Elemento ) ArbolAV Lraiz : ArbolAV L ) Elementoizq; der : ArbolAV L ) ArbolAV Lnumnodos : ArbolAV L ) Naturaleshoja : ArbolAV L ) BooleanalturaAV L : ArbolAV L ) Naturalbalancear : ArbolBusqueda ) ArbolAV L

Sem¶anticae 2 Elemento; b 2 ArbolAV L; b6= nulo;

² Axioma de Comportamientojaltura(izq(b))¡ altura(der(b))j · 1

² insertarAV L(nulo; e) = crearbin(e; nulo; nulo)

² e Á raiz(b)! insertarAV L(b; e) = balancear(crearbin(raiz(b);insertarAV L(izq(b); e); der(b)))

¶Arboles 135

² raiz(b) ¹ e! insertarAV L(b; e) = balancear(crearbin(raiz(b);izq(b); insertarAV L(der(b); e)))

² eliminarbol(nulo; e) = nulo

² raiz(b) Á e ^ :esnulo(der(b))!eliminarAV L(b; e) = balancear(crearbin(raiz(b); izq(b));eliminarAV L(der(b); e))))

² raiz(b) Á e ^ esnulo(der(b))!eliminarAV L(b; e) = balancear(b)

² e Á raiz(b) ^ :esnulo(izq(b))!eliminarAV L(b; e) = balancear(crearbin(raiz(b);eliminarAV L(izq(b); e); der(b))))

² e Á raiz(b) ^ esnulo(izq(b))!eliminarAV L(b; e) = balancear(b)

² e = raiz(b) ^ eshoja(b)! eliminarAV L(b; e) = nulo

² (e = raiz(b) ^ :eshoja(b))!

(:esnulo(izq(b)) ^ :esnulo(der(b))!eliminarAV L(b; e) =balancear(crearbin(max(izq(b)); eliminarAV L(izq(b);max(izq(b))); der(b))))

^(esnulo(izq(b)) ^ :esnulo(der(b))!eliminarAV L(b; e) = balancear(der(b)))

^(:esnulo(izq(b)) ^ esnulo(der(b))!eliminarAV L(b; e) = balancear(izq(b)))

² buscarAV L(b; e) = buscarbol(b; e)

² eshoja(b)! balancear(b) = b

² Axioma II:eshoja(b) ^ (altura(izq(b))¡ altura(der(b)) = 2)^(altura(izq(izq(b))) > altura(der(izq(b))))!balancear(b) = crearbin(raiz(izq(b)); izq(izq(b)));

crearbin(raiz(b); der(izq(b)); der(b)))

136

² Axioma ID:eshoja(b) ^ (altura(izq(b))¡ altura(der(b)) = 2)^(altura(der(izq(b))) > altura(izq(izq(b))))!balancear(b) = crearbin(raiz(der(izq(b)));

crearbin(raiz(izq(b)); izq(izq(b)); izq(der(izq(b))));crearbin(raiz(b); der(der(izq(b))); der(b)))

Fin-ArbolAVL;

La operaci¶on balancear se aplica sobre ¶arboles que eventualmente ya noveri¯can el axioma:

Axioma de Comportamientojaltura(izq(b))¡ altura(der(b))j · 1

Cuando se realiza una inserci¶on (eliminaci¶on) en un ¶arbol AVL, no nece-sariamente este pierde su condici¶on de AVL como se muestra en las ¯guras8.5 y 8.6, por lo que balancear debe dejar el ¶arbol intacto cuando su argu-mento (¶arbol de b¶usqueda ) sea un ¶arbol AVL. A continuaci¶on mostraremosuna serie de inserciones, que no alteran la propiedad de AVL hasta llegar a lasituaci¶on en que balancear debe actuar para reordenar el ¶arbol y recuperarla condici¶on de AVL.

Analizando los casos de deformaci¶on de un ¶arbol AVL cuando se insertaun elemento

Figura 8.5: ¶Arbol AVL Figura 8.6: ¶Arbol de la ¯g.8.5 luego de la inserci¶on

Usaremos unos diagramas para representar el desbalanceo en los axiomasII e ID.

¶Arboles 137

Caso IIEl ¶arbol de la ¯gura 8.7 presenta un desbalanceo producido por el ¶arbol

izquierdo del ¶arbol izquierdoCuando se encuentra un ¶arbol resultado de una inserci¶on que no veri¯ca

el axioma de AVL con las caracter¶³sticas de la ¯gura 8.9, aplicando el axiomaII resultar¶a un ¶arbol transformado como el de la ¯gura 8.10.

Este ¶arbol lo podemos representar como el diagrama de la ¯gura 8.9 dondelos ¶arboles representados por rect¶angulos corresponden a ¶arboles AVL y losmarcados por X son los que realizan la transgresi¶on de la propiedad de serAVL.

Como vemos en la ¯gura 8.8 es el resultado de aplicar el axioma II al¶arbol de la ¯gura 8.7.

Caso IDEl ¶arbol de la ¯gura 8.11 presenta un desbalanceo producido por el ¶arbol

derecho del ¶arbol izquierdoCuando se encuentra un ¶arbol resultado de una inserci¶on que no veri¯ca el

axioma de AVL con las caracter¶³sticas de la ¯gura 8.13, aplicando el axiomaID resultar¶a un ¶arbol transformado como el de la ¯gura 8.14.

Este ¶arbol lo podemos representar como el diagrama de la ¯gura 8.13donde los ¶arboles representados por rect¶angulos corresponden a ¶arboles AVLy los marcados por X son los que realizan la transgresi¶on de la propiedad deser AVL.

Como vemos en la ¯gura 8.12 es el resultado de aplicar el axioma ID al¶arbol de la ¯gura 8.11.

Se deja como ejercicio al lector escribir los axiomas correspondientes a loscasos sim¶etricos (DD y DI).

Para implementar el TAD arbolAVL es conveniente extender el TAD Ar-bolBusqueda con el siguiente operador:

crearbusq : Elemento£ArbolBusqueda£ArbolBusqueda! ArbolBusqueda

cuya sem¶antica damos a continuaci¶on:

² esnulo(b1) ^ esnulo(b2)! crearbusq(e; b1; b2) = crearbol(e; b1; b2)

² :esnulo(b1) ^ :esnulo(b2) ^ raiz(b1) Á e Á raiz(b2)!crearbusq(e; b1; b2) = crearbol(e; b1; b2)

138

Figura 8.7: Desbalanceo en ¶arbolizquierdo del ¶arbol izquierdo

Figura 8.8: Resultado de balancearel ¶arbol de la ¯gura 8.7

Figura 8.9: Caso II Figura 8.10: Balanceo Usando elaxioma II

¶Arboles 139

Figura 8.11: Desbalanceo en¶arbol derecho del ¶arbol iz-quierdo

Figura 8.12: Resultado debalancear el ¶arbol de la ¯gu-ra 8.11

Figura 8.13: Caso ID Figura 8.14: Balanceo Usando elaxioma ID

² :esnulo(b1) ^ esnulo(b2) ^ raiz(b1) Á e!crearbusq(e; b1; b2) = crearbol(e; b1; b2)

² esnulo(b1) ^ :esnulo(b2) ^ e Á raiz(b2)!crearbusq(e; b1; b2) = crearbol(e; b1; b2)

140

Implementaci¶on del TAD ArbolAV L[Elemento]: La implementaci¶ondel TAD ArbolAV L se encuentra el el ap¶endice A

8.5 Otros ¶arboles

En esta secci¶on nos ocuparemos de revisar otras estructuras de ¶arboles quepermiten al almacenamiento de un conjunto de elementos, una de cuyascomponentes es la clave por la que se recupera al elemento.

¶Arboles Perfectamente Balanceados Un ¶arbol perfectamente balan-ceado es un ¶arbol de b¶usqueda donde el n¶umero de elementos de los sub¶arbolesizquierdo y derecho di¯eren a lo sumo en 1.

TAD ArbolPB < ArbolBusqueda[Elemento]Sintaxis

...Sem¶antica:::b 2 ArbolPB; b6= nulo;

² Axioma de Comportamientoj#elem(izq(b))¡#elem(der(b))j · 1

Fin-ArbolPB;

8.6 Res¶umen del cap¶³tulo 8

En este cap¶³tulo hemos presentado una clase de datos que pueden caracteri-zarse como un conjunto ( o multiconjunto) que posee una relaci¶on jer¶arquicaentre los elementos ( relaci¶on de orden parcial).

En contraposici¶on a los mecanismos presentados en el cap¶³tulo 7, la or-ganizaci¶on de ¶arboles es m¶as estable respecto al tiempo requerido para laoperaci¶on de b¶usqueda, admitiendo crecimiento ( y decrecimiento) del con-junto sobre el cu¶al se realiza la b¶uqueda, pagando por ello que las operacionesse realicen en un tiempo que depende del tama~no del conjunto.

Hemos visto que una primera idea de organizaci¶on en ¶arboles puede darlugar a ¶arboles degenerados (donde la operaci¶on de b¶usqueda tiene O(N)),

¶Arboles 141

por lo que se investiga la introducci¶on de la propiedad de ser balanceado. Vi-mos que el mantenimiento de esta propiedad puede ser costosa (degradandoel tiempo total de operaci¶on de la aplicaci¶on, si bien conserva el tiempo deb¶usqueda en O(log (N))), por lo que se analizan m¶etodos para mantener uncriterio menos estricto de balance, por ejemplo la propiedad AVL, que per-mite que las operaciones requeridas para el mantenimiento del balance en lasinserciones y eliminaciones se mantenga en el mismo orden que las operacio-nes de b¶usqueda, haciendo que todas las operaciones de este TAD resulten deO(log (N ))), que resulta aceptable para conjuntos de gran tama~no. En par-ticular los manejadores de bases de datos usan esta organizac¶on para aligerarlas b¶usquedas en una tabla de la base de datos.

Debemos hacer notar que tal como lo mencionamos en el cap¶³tulo 7, el usode esta organizaci¶on de datos en una aplicaci¶on puede hacer que inicialmenetela aplicaci¶on tenga un comportamiento admisible pero con el tiempo (debidoal crecimiento de los conjuntos que se manejan) este comportamiento pasede admisible a no admisible. A diferencia del mecanismo de hashing, ladegradaci¶on en estos casos no puede resolverse con un mantenimiento y dellegar a ser totalmente inadmisible requiere un redise~no de la aplicaci¶on enlo que concierne al almacenamiento del conjunto.

8.7 Ejercicios1. Implemente el TAD Arbol[Elemento] con estructuras din¶amicas.

2. Considere la siguiente operaci¶on sobre ¶arboles n-arios:

elem por niveles : Arbol ) Cola[Cola[Elemento]]

Con la siguiente sem¶antica:

elem por niveles(a) da como resultado una cola de colas, donde cadauna de estas ¶ultimas contiene los elementos que se encuentran a lamisma altura (igual nivel). Los primeros elementos en arribar a cadacola son las raices de los sub¶arboles que se encuentran en las primerasposiciones de los sucesores de la ra¶³z del ¶arbol a.

Implemente la operaci¶on elem por niveles.

3. Implementa el TAD ArbolBinario[Elemento]:

142

(a) Con estructuras din¶amicas.

(b) Con estructuras est¶aticas.

4. Determinar el m¶aximo n¶umero de elementos de un ¶arbol binario dealtura h.

5. Considere la siguiente operaci¶on sobre expresiones en preorden:

arbol exp : ExpPre ) ArbolBinario

Con la siguiente sem¶antica:

arbol exp(exp) da como resultado el ¶arbol binario asociado a la expre-si¶on exp.

Implemente la operaci¶on arbol exp.

6. Dado los recorridos en preorden y en inorden de un ¶arbol binario, im-plemente un programa para reconstruir el ¶arbol.

7. Def. Un ¶arbol es perfectamente equilibrado si el n¶umero de elementosde sus sub¶arboles di¯eren a lo sumo en uno.

(a) > Cu¶al es la relaci¶on entre ¶arboles perfectamente equilibrados y¶arboles completos?

(b) > Cu¶al es la altura de un ¶arbol perfectamente equilibrado de Nelementos?

(c) > Cu¶al es la ventaja de tener ¶arboles perfectamente equilibrados?

8. Construya, mediante inserciones, los ¶arboles de b¶usqueda asociados acada una de las siguientes secuencias:

(a) < 100; 50; 170; 25; 55; 115; 193 >

(b) < 50; 25; 170; 193; 100; 55; 115 >

(c) < 25; 50; 55; 100; 115; 170; 193 >

(d) < 193; 170; 115; 100; 55; 50; 25 >

Para cada caso, determine el costo de buscar el elemento 80. Generaliceel costo para buscar cualquier elemento en un arbol de b¶usqueda de Nelementos. > Cu¶al es su conclusi¶on?

¶Arboles 143

9. Sugiera un algoritmo para crear un ¶arbol binario perfectamente equi-librado a partir de una secuencia.Puede usar este algoritmo si el ¶arboles de b¶usqueda. Explique.

10. Escriba un programa que retorne una lista con la frontera de un ¶arbol.

11. Cu¶antos v¶ertices pueden ser eliminados de un ¶arbol perfectamente ba-lanceado de quince elementos sin que deje de serlo y sin disminuir sualtura.

12. ¶Arboles AVL.

(a) Construya un ¶arbol AVL a partir de la siguiente secuencia den¶umeros:

< 5; 10; 15; 6; 3; 2; 7; 12; 20; 70; 51; 36 >

(b) Elimine los siguientes elementos del ¶arbol generado en (a):

20; 10; 15; 7; 70

En cada caso muestre la evoluci¶on de los procesos de inserci¶on yeliminaci¶on del ¶arbol.

8.8 Bibliograf¶³a1. AHO,Alfred, HOPCROFT,John & ULLMAN,Je®rey. \Data Structure

and Algorithms. Addison Wesley Series in Computer Science.1985

2. HILLE,R.F. \Data Abstraction and Program Development using Modula{2". Advance in Computer Science. Prentice Hall. 1989.

3. ORTEGA, Maruja y MEZA, Oscar. \Grafos y Algoritmos".Rep. # IC{1991{002. Dpto. de Computaci¶on y Tecn. de la Informa-ci¶on. USB.

4. WIRTH, Nicklaus. \Algorithms+Data Structures=Programs". Prenti-ce Hall.

144

Ap¶endice A

Implementaci¶on

A.1 Conjunto Est¶atico

Implementaci¶on Est¶atica de los operadores delTAD Conjunto

Arreglo de booleanos Sea A un arreglo booleano de dimensi¶on ¯nitay D el universo sobre el cual se de¯ne el conjunto.

Type CONJUNTO = A : array[1::card(D)] of Boolean

f vacio :) Conjuntog

Function vacio( A: CONJUNTO) CONJUNTO;begin

for i=1 to card(D)A[i] := FALSE;

vacio := Aend;

Usando la funci¶on convert que permite asociar a cada elemento de D unelemento del dominio [1::card(D)]fconvert : Elemento) [1::card(D)]gf insertar : Conjunto £ Elemento) Conjuntogf pre : convert(e) 2 [1::card(D)] g

145

146

Procedure insertar( var A: CONJUNTO, e: Elemento);begin

A[convert(e)] := TRUE;end

feliminar : Conjunto£ Elemento) Conjuntogf pre : convert(e) 2 [1::card(D)] g

Procedure eliminar( var A: CONJUNTO, e: Elemento);begin

A[convert(e)] := FALSE;end

fesvacio : Conjunto) Booleang

Function esvacio(A: CONJUNTO): Boolean;var esta: booleanbegin

esta := TRUE; i:=1;while (i·card(D) and esta)begin

if (A[i] = TRUE) then esta:= FALSE;i := i+1;

endesvacio := esta

end

fpertenece : Conjunto£ Elemento) Booleangf pre : convert(e) 2 [1::card(D)] g

Function pertenece( A:CONJUNTO, e: Elemento): Boolean)begin

return ( A[convert(e)] == TRUE) ;end

Ap¶endice A 147

Vacio

Ultimo-Elem

Segundo-Elem

Primer-Elem

Lleno

MAX-CONJ

3

2

1

tope

Figura A.1: Arreglo de elementos con repetici¶on

Arreglo de elementos con repetici¶on En esta parte se muestra ope-raciones admitiendo que el arreglo almacene elementos repetidos, haciendoque la eliminaci¶on requiera revisar la totalidad del arreglo y que la inserci¶onsea mas sencilla.

Type CONJUNTO =recordtope : 0..MAX-CONJentrada : array[1..MAX-CONJ] of Tipo-Elem

end

Algunas operaciones sobre Conjunto son implementadas como siguefvacio : Conjunto) Booleang

Procedure vacio(var c: CONJUNTO);begin

c.tope := 0end;

148

finsertar : Conjunto£ Elemento) Conjuntog

Procedure insertar(var c: CONJUNTO; elem:Tipo-Elem);begin

if c.tope = MAX-CONJ then ABORTelse

beginc.tope := c.tope + 1c.entrada[c.tope] := elem

end;end

feliminar : Conjunto£ Elemento) Conjuntog

Procedure eliminar(var c: CONJUNTO; elem:Tipo-Elem);var i : 1.. MAX-CONJbegin

i := 1while (i · c.tope)

if c.entrada[i] 6= elem then i := i + 1else

beginif(i6= c.tope) thenc.entrada[i] := c.entrada[c.tope];c.tope := c.tope - 1;

end;end;

Arreglo de elementos sin repetici¶on En esta parte se muestra ope-raciones no admitiendo que el arreglo almacene elementos repetidos, haciendoque la inserci¶on requiera revisar la totalidad del arreglo y que la eliminaci¶onsea mas sencilla.

Type CONJUNTO = recordtope : 0..MAX-CONJentrada : array[1..MAX-CONJ] of Tipo-Elem

end

Ap¶endice A 149

Algunas operaciones sobre Conjunto son implementadas como siguefvacio : Conjunto) Booleang

Procedure vacio(var c: CONJUNTO);begin

c.tope := 0end;

finsertar : Conjunto£ Elemento) Conjuntog

Procedure insertar(var c: CONJUNTO; elem:Tipo-Elem);begin

if c.tope = MAX-CONJ then ABORTelse

begini := 1;while ( c.entrada[i] 6= elem and i · c.tope) i := i + 1

if( i > c.tope) thenbegin

c.tope := c.tope + 1c.entrada[c.tope] := elem

end;end;

end

feliminar : Conjunto£ Elemento) Conjuntog

Procedure eliminar(var c: CONJUNTO; elem:Tipo-Elem);var i : 1.. MAX-CONJbegin

i := 1while(c.entrada[i] 6= elem and i · c.tope) i := i + 1if( i · c.tope) then

beginc.entrada[i] := c.entrada[c.tope];c.tope := c.tope - 1;

end;end;

150

A.2 Conjunto Din¶amico

Implementaci¶on Din¶amica de los Operadoresdel TAD Conjunto La estructura puede ser declarada como

TypeApunt-Nodo = ^ NodoNodo = record

entrada: Tipo-ElemSig-Nodo:Apunt-Nodo

end

La implementaci¶on de las operaciones usando una representaci¶on din¶amicapueden hacerse como se indica a continuaci¶on.f insertar : Conjunto £ Elemento) Conjuntog

Type Conjunto = pointer of NodoFunction insertar(C:Conjunto;elem:Tipo Elem):Conjunto

var p,q: Apunt-Nodo;beginnew(p);p^ .entrada := elem;p^ .Sig-Nodo := C;C := p ;insertar := C;

end

La complejidad de este algoritmo es de orden O(1).f eliminar : Conjunto £ Elemento) Conjuntog

Function eliminar(C:Conjunto; e: Tipo Elem):Conjuntovar p,q: Apunt-Nodo;begin

q := C;if C 6= NIL thenbegin

if (C^ .entrada6= e) thenbegin

Ap¶endice A 151

p := q;q := q^ .Sig-Nodo;while q^ 6= NIL and q^ .entrada6= e do

begin p := q;q := q^ .Sig-Nodo;

endif (q^ 6= NIL ) then p^ .Sig-Nodo = q

endelse

C := C^ .Sig-Pos;end;

La complejidad de este algoritmo es £(n) , dado que en el peor de los casosel elemento buscado est¶a en la ¶ultima posici¶on.

f long : Conjunto) Enterog

Function long(C:Conjunto):Integervar p: Apunt-Nodo;

i: Integer;beginif C = NIL then long := 0;else

p := C;i := 1;while p^ .Sig-Nodo6= NIL do

beginp := p^ .Sig-Nodo;i := i + 1;

endod

long:= i;end

La complejidad de esta algoritmo es £(n), dado que hay que recorrer todoel Conjunto

Otra versi¶on de esta misma funci¶on

152

Function long(C:Conjunto):Integervar p: Apunt-Nodo;

i: Integer;Begin

if C = NIL then long := 0;elselong:= 1 + long (C^ .Sig-Nodo);

end

Ap¶endice A 153

Vacio

Ultimo-Elem

Segundo-Elem

Primer-Elem

Lleno

MAX-SEC

3

2

1

Ult

Figura A.2: Secuencia de elementos

A.3 Secuencia Est¶aticaImplementaci¶on Est¶atica en PASCAL de losOperadores del TAD Secuencia La representaci¶on est¶aticade secuencia utilizar¶a un arreglo ( de dimensi¶on N) y un entero (Ult) que re-gistra la ¶ultima posici¶on del arreglo ocupada con valores de la secuencia.Vemos un diagrama en la ¯gura A.2

f vacia :) Secuenciag

function vacia: Secuencia;var s: Secuencia;begin

s.Ult := 0;return(s)

end;

finsertar : Secuencia£ Entero£ Elemento) Secuenciagf pre : 1 · long(s) + 1 g

154

function insertar(s: Secuencia; p: Entero; e: Elemento): Secuencia;var i: Entero;be gin

if (s.Ult < N) thenfor i:= s.Ult+1 downto p+1 do

s.Casilla[i] := s.Casilla[i-1]od;s.Casilla[p] := e;s.Ult := s.Ult +1

¯;return(s)

end;

feliminar : Secuencia£Entero) Secuenciag f pre : 1 · p · long(s)+1 g

function eliminar(s: Secuencia; p: Entero);var i: Entero;begin

s.Ult := s.Ult -1;for i:= p to s.Ult do

s.Casilla[i] := s.Casilla[i+1]odreturn(s)

end;

fesvacia : Secuencia) Booleang

function esvacia(s: Secuencia): Boolean;begin

return(s.Ult == 0)end;

festa : Secuencia£ Elemento) Booleang

function esta(s: Secuencia; e: Elemento): Boolean;var i: Entero;begin

if(s.Ult = 0) then

Ap¶endice A 155

return(false)else

i := 1;while (i < s.Ult) and (s.Casilla[i]6= e) do

i := i + 1od;return(s.Casilla[i] = e)

¯ end;

flong : Secuencia) Enterog f pre : 1 · long(s) + 1 g

function long(s: Secuencia): Entero;begin

return(s.Ult)end;

fproyectar : Secuencia £ Entero) Elementog f pre : 1 · p · long(s)g

function proyectar(s: Secuencia; p: Entero): Elemento;begin

return(s.Casilla[p])end;

A.4 Secuencia Din¶amicaImplementaci¶on Din¶amica en PASCAL de losOperadores del TAD Secuencia Para esta implementa-ci¶on se usar¶an las funciones de manejo de memoria de PASCAL (new ydispose para la obtenci¶on y liberaci¶on de memoria).fvacia :) Secuenciag

function vacia: Secuencia;begin

return(nil)end;

finsertar : Secuencia£ Entero£ Elemento) Secuenciagf pre : (1 <= p <= long(s) + 1) g

156

function insertar(s: Secuencia; p: Entero; e: Elemento): Secuencia;var s1,s2: Secuencia;begin

new(s1);s1^ .Elem := e;if ( p = 1 ) then

s1^ .Sig := s;s := s1

elses2 := s;for i:=2 to p-1 do

s2 := s2^ .Sigod;s1^ .Sig := s2^ .Sig;s2^ .Sig := s1

¯;return(s)end;

feliminar : Secuencia£ Entero) Secuenciagf pre : (1 <= p <= long(s)) g

function eliminar(s: Secuencia; p: Entero);var s1,s2: Secuencia;begin

if ( p = 1 ) thens1 := s;s := s^ .Sig;dispose(s1)

elses1 := s;for i:=2 to p-1 do

s1 := s1^ .Sigod;s2 := s1^ .Sig; La casilla a eliminars1^ .Sig := s2^ .Sig;dispose(s2)

¯;

Ap¶endice A 157

return(s)end;

fesvacia : Secuencia) Booleang

function esvacia(s: Secuencia): Boolean;begin

return(s = nil)end;

festa : secuencia£ Elemento) Booleang

function esta(s: Secuencia; e: Elemento): Boolean;var Ocur: Boolean;begin

Ocur := false;while(s 6= nil) and not(Ocur) do

Ocur : = (s^ .Elem = e);s := s^ .Sig

do;return(Ocur)

end;

flong : secuencia) Enterog

function long(s: Secuencia): Entero;var i: Entero;begin

i = 0;while(s 6= nil) do

i:= i + 1;s := s^ .Sig

od;return(i)

end;

fproyectar : secuencia£ Entero) Elementogf pre : (1 <= p <= long(s)) g

158

function proyectar(s: Secuencia; p: Entero): Elemento;begin

for i := 1 to p-1 dos := s^ .Sig

od;return(s.Elem)

end;

A.5 Pila Est¶aticaImplementaci¶on Est¶atica de los Operadores deTAD Pila Para implementar una pila en forma est¶atica se usa unarreglo donde se almacena los elementos y un contador que indica cuantasentradas hay en el arreglo. Por ser est¶atico es necesario declarar el tama~nom¶aximo permitido del arreglo (MAX-Pila) as¶³ como el tipo de elementos aalmacenar en la estructura o arreglo (Tipo-Elem).

Type Pila =recordtop : 0..MAX-Pilaentrada : array[1..MAX-Pila] of Tipo-Elemend

Las operaciones de empilar y desempilar sobre la Pila son implementadascomo siguefempilar : P ila£Elemento) Pilagprocedure empilar(var P:Pila; e:Tipo-Elem);beginwith P do

if top = MAX-Pilathen

writeln('Error:intenta almacenar un elemento en una pila llena')else begin

top := top +1;entrada[top] := eend

end;

Ap¶endice A 159

fdesempilar : Pila) P ilag

procedure desempilar(var P:Pila);beginwith P doif top = 0

thenwriteln('Error: desempilando de una pila vacia')

else begintop := top -1end

end;

fvaciaP : P ila) Pilag

function vaciaP ( ):PilabeginP.top := 0return Pend;

fesvaciaP : Pila) Booleang

function esvaciaP ( P:Pila):Booleanbeginwith P doif top = 0

thenreturn TRUE

elsebegin

return FALSEend

end;

ftope : Pila) Elementogf pre : esvaciaP (P ) = FALSE g

160

function tope( P:Pila ):Tipo-Elembeginwith P doif top = 0

thenwriteln('Error: intenta sacar un elemento de una pila vacia')

else beginreturn P.entrada[top]end

end;

Con esta implementaci¶on la operaci¶on de empilar es de orden £(n).

A.6 Pila Din¶amicaImplementaci¶on Din¶amica de los Operadoresdel TAD Pila

Pila Vacia

p?" !

# Ã

Figura A.3: Representaci¶on de la pila vac¶³a

TypeApunt-Pila = ^ NodoPilaNodoPila = record

entrada: Tipo-ElemSig-Nodo: Apunt-Pilaend

Type Pila = Apunt-pila

Ap¶endice A 161

f esvaciap : Pila) Booleang

function esvaciap( p:Pila):booleanbeginif p = NIL

thenreturn TRUE

elsereturn FALSE

end

f tope : Pila) Elementog

function tope( p:Pila):Tipo-Elembeginreturn p^ .entrada

end;

f empilar : PilaXElemento) Pilag

procedure empilar(var p:Pila; e:Tipo-Elem);var q: Apunt-Pila;beginnew(q);if q = NIL

thenwriteln('Error:intento de a~nadir un nodo inexistente')

elsebeginq^ .entrada := e;q^ .Sig-Nodo := p;p := q;end

end;

f desempilar : Pila) P ilag

162

X

Nuevo

viejo

q

p

QQQs

n

-

-

-µ ´¶ ³?

--

Figura A.4: Agregando un NODO a la PILA

procedure desempilar(var p:Pila);var q: Apunt-Pila;beginif esvaciap(p)

thenwriteln('Intento de eliminar un elemento de una pila vacia');

elsebeginq := p;p := q^ .Sig-Nododispose(q);end

end;

-- -?µ ´¶ ³

-

nQ

QQsp

q

X

Figura A.5: Eliminando el elemento TOPE

Ap¶endice A 163

A.7 Cola Est¶atica

Implementaci¶on Est¶atica de los Operadoresdel TAD Cola .

Type Cola recordcont : 0..MAX-Cola;Primero : 0..MAX-Cola;Ultimo : 0..MAX-Cola;entrada : array[1..MAX-Cola] of Tipo-Elem;end

var C : Cola;

f vaciaC : ) Colag

procedure vaciaC();begin

with C do begincont := 0;Primero := 1;Ultimo := 0;

endend;

f esvaciaC : Cola) Booleang

function esvaciaC(C:Cola):boolean;begin

with C do beginreturn (cont == 0)

end;

f encolar : ColaeElemento) Colag

164

Procedure encolar(var C:Cola, e:Tipo-Elem );begin

with C doif (cont == MAX-Cola) thenWriteln('ERROR: Cola Llena')

elsebegincont := cont +1;Ultimo := ( Ultimo mod MAX-Cola) + 1;entrada[Ultimo] := e;

end;end

fdesencolar : Cola) Colag

Procedure desencolar(var C:Cola);begin

with C doif (count == 0) then

writeln('ERROR: intento de eliminar de una cola vacia');else

begincont := cont - 1;Primero := (Primero mod MAX-Cola)+1;

end;end

ffrente : Cola) Elementog

Procedure frente( C:Cola, var e:Tipo-Elem);begin

with C doif (cont == 0) then

writeln('ERROR: intento de ver en una cola vacia');else

begine := entrada[Primero];

Ap¶endice A 165

endend

A.8 Cola Din¶amicaImplementaci¶on Din¶amica de los Operadoresdel TAD Cola .

UltimoPrimero H H H H H H H HHj

´´

´´

´+́

- -

C

X1 X2 X3

Figura A.6: Cola din¶amica

TypeApunt-Cola : ^ NodoColaNodoCola = record

entrada: Tipo-ElemSig-Nodo:Apunt-Colaend

Cola = recordPrimero : Apunt-Cola;Ultimo : Apunt-Colaend

166

fvaciaC : ) Colag

var C : Cola

Procedure vaciaC();beginC.Primero := NIL;C.Ultimo := NIL

end;

fencolar : ColaeElemento) Colag

Procedure encolar(var C:Cola, e:Tipo-Elem);var p: Apunt-Cola;

beginnew(p );p^ .entrada := e;

p^ .Sig-Nodo := NILwith C doif Primero == NIL

thenPrimero := p;Ultimo := p;

elseUltimo^ .Sig-Nodo := p;Ultimo := p;

¯end

fdesencolar : Cola) Colag

Procedure desencolar(var C:Cola);var p:Apunt-Cola;

beginwith C doif Primero == NIL

then

Ap¶endice A 167

X-- --

Primero

Ultimo

--

6X

Nuevo

Figura A.7: Sumar un elemento a la Cola

writeln('ERROR intento de eliminar de una cola vacia');else

beginp := Primero;Primero := Primero^ .Sig-Nodo;if Primero == NIL then

Ultimo := NILdispose(p);

endend

RemoveX

6 6

- --Primero

Ultimo

-

Figura A.8: Remueve un elemento del frente

A.9 ¶Arbol BinarioImplementaci¶on Din¶amica de los Operadoresde TAD ArbolBinario Se describe a continuaci¶on la implemen-

168

taci¶on din¶amica de ¶arboles.

type ArbolBinario = ^ NodoArbol;NodoArbol = record

elem: Elemento;izq, der: ArbolBinario

end;

fcrearbin : ElementoXArbolBinarioXArbolBinario) ArbolBinariog

function crearbin(e: Elemento; bi, bd: ArbolBinario): ArbolBinario;var b : ArbolBinario;begin

new(b); b^ .elem := e;b^ .izq := bi; b^ .der := bd;crearbin := b

end;

fnulo : ) ArbolBinariog

function nulo: ArbolBinario;begin

nulo := nilend;

fesnulo : ArbolBinario ) Boolean g

function esnulo(b: ArbolBinario): Boolean;begin

esnulo := (b = nil)end;

fraiz : ArbolBinario) Elementogfpre : not(esnulo(b))g

function raiz(b: ArbolBinario) : Elemento;begin

raiz := b^ .elemend;

Ap¶endice A 169

fder : ArbolBinario) ArbolBinariogfpre : not(esnulo(b))g

function der(b: ArbolBinario) :ArbolBinario;begin

der := b^ .derend;

fizq : ArbolBinario) ArbolBinariogfpre : not(esnulo(b))g

function izq(b: ArbolBinario) : ArbolBinario;begin

izq := b^ .izqend;

feshoja : ArbolBinario) Booleangfunction eshoja(b: ArbolBinario): Boolean;begin

eshoja := not(esnulo(b)) and(b^ .izq = nil and b^ .der = nil)

end;

f#elem : ArbolBinario) Naturalgfunction #elem(b: ArbolBinario): Natural;begin

if esnulo(b) then #elem:= 0else

#elem := 1 + #elem(b^ .izq) + #elem(b^ .der)end;

faltura : ArbolBinario) Naturalgfpre : not(esnulo(b))g

function altura(b: ArbolBinario): Natural;begin

if eshoja(b) then altura := 0elsealtura := 1 + max(altura(b^ .izq),altura(b^ .der))

end;

La funci¶on max calcula el m¶aximo entre dos n¶umeros naturales.

170

A.10 ¶Arbol de B¶usqueda

Implementaci¶on del TAD ArbolBusqueda A continuaci¶on presentamosuna implementaci¶on del TAD ArbolBusqueda, basada en el TAD ArbolBina-rio.

type ArbolBusqueda = ArbolBinario;fbuscarbol : ArbolBusqueda£Elemento) ArbolBusquedag

function buscarbol(b: ArbolBusqueda; e: Elemento): ArbolBusqueda;begin

if esnulo(b) then return(nulo)elseif (raiz(b) = e) then return(b)

elseif (raiz(b) < e) thenreturn(buscarbol(der(b),e))

elsereturn(buscarbol(izq(b),e))

¯¯

¯end;

finsertarbol : ArbolBusqueda£Elemento) ArbolBusquedag

function insertarbol(b:ArbolBusqueda; e: Elemento): ArbolBusqueda;begin

if esnulo(b) then return(crearbin(e, nulo, nulo))else if (raiz(b) = e) then return(b)

elseif(raiz(b) < e) thenb1 := insertarbol(der(b),e);return(crearbin(raiz(b), izq(b), b1))

elseb1:= insertarbol(izq(b),e);return(crearbin(raiz(b), b1, der(b)))

¯¯

¯end;

Ap¶endice A 171

feliminarbol : ArbolBusqueda£ Elemento) ArbolBusqueda gfpre : not(esnulo(b)) gLa funci¶on eliminararbol utiliza como auxiliar la funci¶on borrar max que

recibe como par¶ametro un ¶arbol y elimina el elemento m¶aximo del mismo,devolviendo en el segundo par¶ametro el valor de ese elemento m¶aximo.

function eliminarbol(b:ArbolBusqueda; e: Elemento): ArbolBusqueda;var max: Elemento;function borrar max (b: ArbolBusqueda; var m: Elemento): ArbolBusqueda;begin borrar max

ifnot(eshoja(b)) and not(esnulo(der(b)) thenreturn(crearbin(raiz(b),izq(b),borrar max(der(b),m)))

elsem := raiz(b);return(izq(b))

¯end borrar maxbegin eliminarbol

if esnulo(b) then return(b)else

if(raiz(b) = e) then encontro el elementoif eshoja(b) then return(nulo)else debe eliminar un nodo interno

if esnulo(der(b)) thenreturn(izq(b))else

if esnulo(izq(b)) thenreturn(der(b))elseb1 := borrar max (izq(b), max);return(crearbin(max, b1, der(b)))¯

¯¯

else continua la busquedaif (raiz(b) < e) then

if (esnulo(der(b)) then return(b)else

172

b1 := eliminarbol(der(b),e);return(crearbin(raiz(b), izq(b), b1))

¯else

if (esnulo(izq(b)) then return(b)else

b1:= eliminarbol(izq(b),e);return(crearbin(raiz(b), b1, der(b)))

¯¯

¯¯

end; eliminarbol

A.11 ¶Arbol AVLImplementaci¶on del TAD ArbolAV L[Elemento] type ArbolBusqueda= ArbolBusqueda; faltura : ArbolBusqueda) Naturalg

function alturaAV L(b: ArbolAVL): Integer;begin

if esnulo(b) then alturaAV L := 0else

return(1 + max(altura(izq(b),altura(der(b))))¯

end;

fbalancear : ArbolBusqueda) ArbolAV Lg

function balancear(b: ArbolAVL): ArbolAVL;begin

if (esnulo(b) or eshoja(b)) then balancear := nuloelse if abs(alturaAV L(izq(b)) - alturaAV L(der(b)) = 2) then

Cargado hacia la izquierdaif (alturaAV L(izq(izq(b)) > alturaAV L(der(izq(b)))then Axioma DDreturn(crearbusq(raiz(izq(b)), izq(izq(b)),

crearbusq(raiz(b),der(izq(b)),

Ap¶endice A 173

der(b))))else Axioma ID

return(crearbusq(raiz(der(izq(b))),crearbusq(raiz(izq(b)),izq(izq(b)),izq(der(izq(b)))),der(b)))

¯else Cargado hacia la derecha

.......¯end balancear

fbuscarAV L : ArbolAV L£ Elemento) ArbolAV Lg

function buscarAV L(b: ArbolAVL; e: Elemento): ArbolAVL;begin

if esnulo(b) then return(nulo)else

if (raiz(b) = e) then return(b)else if (raiz(b) < e) then

return(buscarAV L(der(b),e))else

return(buscarAV L(izq(b),e))¯

¯¯

end;

finsertarAV L : ArbolAV L£ Elemento) ArbolAV Lg

function insertarAV L(b:ArbolAVL; e: Elemento): ArbolAVL;begin

if esnulo(b) thenreturn(crearbusq(e, nulo, nulo))

elseif (raiz(b) = e) then return(b)else

if (raiz(b) < e) thenb1 := insertarAV L(der(b),e);

174

return(balancear(crearbusq(raiz(b),izq(b),b1)))else

b1:= insertarAV L(izq(b),e);return(balancear(crearbusq(raiz(b),b1,der(b)))

¯¯

¯end;

feliminarAV L : ArbolAV L£ Elemento) ArbolAV Lgfpre : not(esnulo(b)) g

function eliminarAV L(b:ArbolBusqueda; e: Elemento): ArbolBusqueda;var max: elemento;function borrar max (b: ArbolAVL; var m: Elemento): ArbolAVL;begin borrar max

if not(eshoja(b)) and not(esnulo(der(b)) thenreturn(balancear(crearbusq(raiz(b),izq(b),borrar max(der(b),m))))

elsem := raiz(b);return(izq(b))

¯end borrar maxbegin eliminarAVL

if esnulo(b) then return(nulo)else

if (raiz(b) = e) then encontro el elementoif eshoja(b) then return(nulo)else debe eliminar un nodo interno

if esnulo(der(b)) thenreturn(izq(b))else

if esnulo(izq(b)) thenreturn(der(b))else

b1 := borrar max (izq(b), max);return(balancear(crearbusq(max, b1, der(b))))

¯

Ap¶endice A 175

¯¯

else continua la busquedaif (raiz(b) < e) then

b1 := eliminarbol(der(b),e);return(balancear(crearbin(raiz(b), izq(b), b1)))

elseb1:= eliminarbol(izq(b),e);return(balancear(crearbin(raiz(b), b1, der(b))))

¯¯

¯end; eliminarAVL

176

Ap¶endice B

Estructuraci¶on de los TiposAbstractos de Datos

En este ap¶endice se relacionan los tipos abstractos (TAD) cubiertos en estelibro indicando las relaciones existentes entre ellos. Presentamos dos tiposde relaciones diferentes:

² Las relaciones que sobre el tipo Elemento.

² Las relaciones espaciales ( o relaciones de accesibilidad) entre los ele-mentos.

En ambos casos las relaciones que se establecen son relaciones de orden(parcial o total).

Los TAD estudiados se parametrizaron con el tipo Elemento. Comose indica en la ¯gura B.1 los dos tipos abstractos base son el conjunto yel multiconjunto, dado que representan colecciones de objetos cuya ¶unicapropiedad es la de pertenecer a un mismo conjunto. Los dem¶as TAD seobtienes de conjuntos y multiconjuntos agregandoles relaciones espaciales orelaciones a los elementos.

Cuando se le agrega al conjunto o al multiconjunto un ORDEN TO-TAL en el espacio como organizaci¶on surge el tipo abstracto secuencia. Lasecuencia es un ordenamiento espacial de los elementos de un conjunto (mul-ticonjunto). Surge as¶³ la noci¶on de puesto de un elemento.

Los tipos COLA,PILA y DIPOLO son especializaciones del tipo secuen-cia poniendo restricciones a las pol¶³ticas de ingreso y egreso de los elementosa una secuencia.

177

178

Figura B.1: Relaciones entre los TDA

Si adicionalmente el TAD Elemento posee un orden total sobre ¶el, seaeste ¹, sumado al orden espacial vemos que es interesante hacer coincidir elorden espacial con el orden total de los elementos. Esto lo expresamos como

i < j , proyectar(s; i) ¹ proyectar(s; j)

.Para lograr esto se revisan los m¶etodos de ordenamiento de una secuencia

que reciben una secuencia y la transforman de manera que el puesto de unelemento re°eje el orden total de los elementos de la secuencia, lo que equivalea decir que el elemento del primer puesto de la secuencia resultado ser¶a elm¶³nimo del conjunto y el m¶aximo del conjunto ocupar¶a el ¶ultimo puesto.

Si a los tipos Conjunto y Multiconjunto se le agrega un orden parcialcomo organizaci¶on espacial surge el tipo abstracto ¶arbol, en su forma m¶asgeneral de ¶arbol n-ario a la especializaci¶on de ¶arbol binario.

En la ¯gura B.2 se muestra el TAD ¶arboles de b¶usqueda que se obtienenorganizando Conjunto y Multiconjunto de Elemento que posea un ordentotal, con un orden parcial espacial.

Ap¶endice B 179

Figura B.2: ¶Arboles

180

Ap¶endice C

¶Indice de materias

181

¶Indice de Materias

¶arbol, 119

abierto, 109abstractos, 13arreglos, 19ASCII, 17asignaci¶on, 14AVL, 133

b¶usqueda, 69, 71, 74, 75, 130balanceado, 133, 136, 140binario, 129

Caso promedio, 3, 4Cola, 60cola, 56colisiones, 111complejidad, 2, 4, 6, 23, 73, 76, 92,

95, 113completo, 124Concretos, 13Conjunto, 26conjunto, 32, 114, 130, 140costo, 1, 6, 76, 80, 82

degenerado, 133diccionario, 105, 107dipolo, 61

equilibrado, 133especializaci¶on, 55, 122, 128especializaciones, 54

especi¯caci¶on, 24, 79exponente, 16

frecuencia, 108

grado, 124

hashing, 109, 111, 113

identi¯cador, 13implementar, 31inorden, 126

l¶ogico, 17

mantisa, 16Mejor caso, 3modelo, 2Multiconjunto, 30multiconjunto, 45, 120, 121, 130,

140

nivel, 124

observados, 32orden, 5, 76, 93ordenado, 119, 121ordenamiento, 79, 80, 82, 99

Peor caso, 3, 4Pila, 60pila, 54, 56postorden, 126

182

¶Indice de materias 183

precondicionamiento, 99preorden, 126

real, 17recorrido, 125, 126referencias, 18registros, 20rehash, 111, 113

secuencia, 45, 46, 50, 53{55, 62, 69,73, 79, 81, 82, 85, 87, 122

selecci¶on, 83sem¶antica, 25, 27, 107sintaxis, 24

TAD, 23, 24, 37, 45, 54, 60{62, 69,82, 107, 122, 141

tipos estructurados, 19

UNICODE, 18

variable, 13