Академический Документы
Профессиональный Документы
Культура Документы
.',
\
<
<
.
,
<
ESTRUCTURA DE DATOS
Algoritmos, abstraccin y objetos
, <
,
."
r
CONSULTORES EDITORIALES
REA DE INFORMTICA y COMPUTACIN
ISBN: 84-481-2042-6
Depsito legal: M. 16.148-1999
... . .
.. .
.. .
...,-'..
,
..
.
,
Prlogo .................................................................................................................... . XXI
"
VII
viii Estructura de datos
Contenido ix
.
2.2.1. Cabecera de la unidad ....................................................... . 55
2.2.2. Seccin de interfaz ............................................................ . 55
2.2.3. Seccin de implementacin .............................................. . 56
2.2.4. Seccin de iniciacin (inicializacin) ............................. . 57
2.2.5. Ventajas de las unidades ................................................... . 57
2.3. Creacin de unidades ...................................................................... . 57
2.3.1. Construccin de grandes programas ................................ . 61
2.3.2. Uso de unidades ................................................................ . 61
2.3.3. Declaraciones/infonnacin pblica y privada ................. . 62
2.3.4. Clusula uses en la seccin de implementacin .......... . 63
2.4. Utilizacin de unidad estndar ....................................................... . 65
2.4.1. Unidad System ................................................................ 66
2.4.2. Unidad Crt ....................................................................... . 66
2.4.3. Unidad DOS ....................................................................... . 67
2.4.4. Unidad Printer ............................................................. . 68
2.4.5. Unidad Graph ................................................................... 68
2.5. Situacin de las unidades en sus discos: dnde busca Turbo Bor-
land Pascal las unidades? ................................................................. 69
2.6. Identificadores idnticos en diferentes unidades ............................ 71
2.7. Sntesis de unidades ......................................................................... 71
2.7.1. Estructura de una unidad ............................ ............ ........... 72
2.7.2. Excepciones en la escritura de unidades .......................... 73
2.7.3. Compilacin de unidades .................................................. 74
2.8. Otros mtodos de estructurar programas: inclusin, solapamientos
y encadenamiento ............................................................................ .
74
2.8.1. Los archivos de inclusin o incluidos (include) ............. . 74
2.8.2. Los solapamientos (overlays) ................................ :.......... . 75
2.8.3. La unidad OverIay (generacin de solapamientos) ......... . 76
2.8.4. Encadenamiento de archivos compilados ........................ . 79
Resumen .............................................................,......................................... . 79
..
E1erClClOS .................................................................................................... . 79
Referencias bibliogrficas ......................................................................... . 82
r
Captul 3.,
I Abstraccin de datos: tipos abstractos de datos y objetos ....... 83
3.3.
,.'.NI odularldad
. .
..................................................................................... . 89
3.3.1. La estructura de un mdulo ............................................. . 90
3.3.2. Reglas de modularizacin ............................................... . 91
3.4. Diseo de mdulos .......................................................................... . 94
3.4.1. Acoplamiento de mdulos .............................................. .. 94
3.4.2. Cohesin de mdulos ..................................................... .. 95
3.5. Tipos de datos ........................................ o 96
3.6. Abstraccin en lenguajes de programacin ................................... . 97
3.6.1. Abstracciones de control ................................................. . 97
3.6.2. Abstracciones de datos ................................................... .. 98
3.7. Tipos abstractos de datos (TAD) .................................................... . 99
3.7.1. Ventajas de los tipos abstractos de datos ........................ . 101
3.7.2. Implementacin de los TAD .......................................... .. 101
3.8. Tipos abstractos de datos en Turbo Borland Pascal ...................... . 102
3.8.1. Aplicacin del tipo abstracto de dato pila ..................... . 104
3 ..
9 . , b'
Orlentaclon a o ~etos ...................................................................... . 105
3.9.1. Abstraccin ...................................................................... . 107
. 3.9.2. Encapsulacin .................................................................. . 107
3.9.3. Modularidad ..................................................................... . 107
3.9.4. Jerarqua .................................................. ......................... . 108
3.9.5. Polimorfismo .................................................................... . 108
3.9.6. Otras propiedades ............................................................ . 109
3.10. Reutilizacin de software ............................................................... .. 110
3.11. Lenguajes de programacin orientados a objetos .......................... . 111
3.11.1. Clasificacin de los lenguajes orientados a objetos ...... . 112
3.12. Desarrollo tradicional frente a desarrollo orientado a objetos .... .. 116
3.13. Beneficios de las tecnologas de objetos ....................................... .. 118
Resumen ........................................................................................................ . 120
..
EjerCIClOS ...................................................................................................... . 120
Contenido xi
I
4.3.4. Procedimiento Di s po s e ............. l37
4.3.5. Constante ni 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . l38
4.3.6. Naturaleza dinmica de los punteros ............................... . 138
4.3.7. Comparacin de punteros ................................................. . l39
4.3.8. Paso de punteros como parmetros .................................. . 141
4.4. El tipo genrico puntero (Pointer) .................................................. . 142
4.5. La asignacin de memoria en Turbo Borland Pascal .................... . 142
4.5.1. El montculo (heap) y los punteros .................................. .
143
4.5.2. Mtodos de asignacin y liberacin de memoria ............ . 145
4.5.3. New y Dispose ............................................................... 145
4.5.4. Mark y Release ........................................................... . 146
4.5.5. GetMem y FreeMem ...................................................... . 146
4.5.6. MemAvail y MaxAvail ............................................... . 147
Resumen ..................................................................................................'... . 148
..
EJerCICIOS ................................................................................ 149
Problemas ................................................................................................... .
152
6.5. Implementacin de una lista circular mediante variables dinmicas ... . 196
6.6. Implementacin de listas circulares con doble enlace .................. . 200
Resumen .............................................................. o 203
..
EJerclclos .................................................................................................... . 204
Problemas ................................................................................................... . 204
Captulo 7. IPilas: el TAD pi 1 a ......................................................................... 207
7.1. Especificacin formal del tipo abstracto de datos pila ................. . 207
7.2. Implementacin del TAD pila con arrays .................................. . 208
7.3. Implementacin del TAD pi 1 a mediante variables dinmicas ... . 211
7.4. Evaluacin de expresiones aritmticas mediante pilas ................. . 215
7.4.1. Notaciones Prefija (Polaca) y Postfija (Polaca inversa) .. 215
7.4.2. Algoritmo para evaluaciones de una expresin aritmtica .... 216
7.5. Aplicacin prctica de la evaluacin de una expresin aritmtica 218
7.5.1. Unidad Pilaop ................................................................ . 218
7.5.2. Unidad ExpPost (transformacin a postfija) ............... . 220
7.5.3. Evaluacin de la expresin en postfij a ............................ . 222
Resumen ...................... a 224
..
EJerclclos .................................................................................................... . 225
Problemas ................................................................................................... . 225
.
,.
PARTE UI. ESTRUCTURAS DE DATOS AVANZADAS !
1,
Captul 9 Recursividad: algoritmos recursivos .......................................... . 263 !
.~
.
j
!
i
j.
" -,
Contenido XIII
9.3. Algoritmos divide y vencers ...................................................... 267
9.3.1. Torres de Hanoi .................................................................. 267
9.3.2. Traza de un segmento ........................................................ 269
9.4. Implementacin de procedimientos recursivos mediante pilas...... 270
9.4.1. El problema de las Torres de Hanoi resuelto sin recur-
sividad................................................................................. 271
9.5. Algoritmos de vuelta atrs (backtracking) ...................................... 277
9.5.1. Solucin del problema Salto del caballo con esquema
IteratIVO ................................... o., 281
9.5.2. Problema de las ocho reinas ............................................ .. 286
9.5.3. Solucin no recursiva al problema de las ocho reinas .... . 288
9.5.4. Problema de la mochila .................................................... . 290
9.5.5. Problema del laberinto ..................................................... .. 293
9.5.6. Generacin de permutaciones de n elementos ................ . 296
9.6. Problema de la seleccin ptima .................................................... . 297
9.6.1. El viajante de comercio ................................................... .. 298
9.7. Problema de los matrimonios estables .......................................... .. 298
Resumen ...................................................................................................... . 306
..
E~erclclos .................................................................................................... . 306
Problemas .................................................................................................... . 308
,
Captulo 10. I Arboles binarios ....... ................................................................... . 311
10.1. Concepto
, de rbol ......................................................................... . 312
10.2. Arboles binarios ............................................................................ . 314
10.2.1. Terminologa .................... ~ ............................................. . 315
10.2.2. Nivel
, de un nodo y altura de un rbol .......................... . 316
10.2.3. Arboles binario, lleno y completo ................................ . 318
10.2.4.
, Recorrido de un rbol binario ....................................... . 320
xiv Estructura de datos
,
10.7. Arbol binario de bsqueda .......................................................... .. 334
10.7.1 Creacin de un rbol binario ........................................ . 336
10.8. Operaciones en rboles binarios de bsqueda ............................. . 340
10.8.1. Bsqueda ........................................................................ . 341
10.8.2. Insercin ......................................................................... . 341
1O. 8"3 . ,
El lffilnaClon .................................................................... . 342
10.8.4. Recorrido de un rbol ................................................... . 344
10.8.5. Determinacin de la altura de un rbol ........................ . 345
Resumen ..................................................................................................... . 346
..
E~erclclos .................................................................................................... . 347
Problemas .................................................................................................... . 349
Referencias bibliogrficas ......................................................................... . 350
,
,
Captulo 11. Arboles equilibrados ........................................ ..................... ....... 353
,
Captulo 12. Arboles B ....................................................................................... 379
12.1. Definicn de .
un rbol B .............................................................. . 379
12.2. Representacin de un rbol B de orden m ................................... . 380
12.3. Proceso de creacin en un rbol B ............................................... .
381
12.4. Bsqueda de una clave en un rbol B .......................................... . 384
12.5. Algoritmo de insercin en un rbol B de orden m ................... ... . 385
12.6. Recorrido en un rbol B de orden m ... ................ ........................ .. 389
12.7. Eliminacin de una clave en un rbol B de orden m .................. . 390
12.8. TAO rbol B de orden m .......... .................................................... . 397
12.9. Realizacin de un rbol B en memoria externa .......................... . 400
Resumen ........................... , ......................................................................... . 414
EJerCICIos .................................................................................................... . 415
Problemas ................................................................................................... . 415
Contenido xv
Captulo 4) ..
Algoritmos fundamentales con grafos ...................................... . 455
......
14.1. Ordenacin topolgica .................................................................. . 456
14.2. Matriz de caminos: algoritmo de Warshall .................................. . 459
14.3. Problema de los caminos ms cortos con un solo origen: algorit-
mo de Dijkstra ............................................................................... . 461
14.3.1. Algoritmo de la longitud del camino ms corto .......... . 462
14.4. Problema de los caminos ms cortos entre todos los pares de vr-
tices: algoritmo de Floyd .............................................................. . 467
14.4.1. Recuperacin de caminos ............................................ .. 469
14.5. Concepto del flujo ......................................................................... . 470
14.5.1. Planteamiento del problema ........................................ .. 471
, ,.
14.5.2. F ormu laClon matematlca ............................................... . 472
14.5.3. Algoritmo del aumento del flujo: algoritmo de Ford y
Fulkerson ....................................................................... . 472
14.5.4. Ejemplo de mejora de flujo .......................................... . 474
14.5.5. Esquema del algoritmo de aumento de flujo .............. .. 476
14.5.6. Tipos de datos y pseudocdigo .................................... . 478
14.5.7. Codificacin del algoritmo de flujo mximo: Ford-Fu1kerson . 479
XVI Estructura de datos
15.14. '
B usque da b"lnarla recursIva . ........................................................... . 544
'
15.14.1. Funcin bsqueda ...................................................... .. 544 ,,
15.14.2. Procedimiento BusquedaBin ................................ .. 545
!
.~
Contenido xvii
Contenido xix
..
EJerclclos .................................................................................................... . 678
Problemas ................................................................................................... . 679
Referencias bibliogrficas ......................................................................... . 679
Apndices
Apndice A. Vademcum de Matemticas para la resolucin de algoritmos
, .
numerlCOS . o ' , oo 733
Apendice B. Unidades estndar de Turbo Borland Pascal 7 ............................ . 739
B.I. Las unidades estndar ........................................................ . 740
B.2. La unidad Systern ............................................................ . 740
B.3. La unidad Printer ........................................................ .. 741
8.4. La unidad DOS ................................................................... . 742
B.5. Procedimientos y funciones de la unidad DOS ................ . 744
B.6. La unidad Crt ................................................................... . 753
,
-
Una de las disciplinas clsicas en todas las carreras relacionadas con la Informtica o las
Ciencias de la Computacin es Estructura de datos. El estudio de las estructuras de
datos es casi tan antiguo como el nacimiento de la programacin, y se ha convertido en
materia de estudio obligatoria en todos los curriculum desde finales de los aos sesenta
y sobre todo en la dcada de los setenta cuando apareci el lenguaje Pascal de la mano
del profesor Niklaus Wirtz, y posteriormente en la dcada de los ochenta con la apari-
cin de su obra ya clsica Algorihtms and Data Structures en 1986.
Ha sido en la dcada de los ochenta cuando surgieron los conceptos clsicos de es-
tructuras de datos, y aparecieron otros nuevos que se han ido consolidando en la segun-
da mitad de esa dcada, para llegar a implantar la caracterstica distintiva de la dcada de
los noventa, la orientacin a objetos. Una razn para que esta caracterstica se haya
convertido en ncleo fundamental de la programacin que se realiza en los noventa, y
que se seguir realizando en el tercer milenio, ha sido que un objeto encapsula el diseo
o implementacin de un tipo abstracto de datos (TAD). Adems de encapsulacin de
datos, los objetos tambin encapsulan herencia; por ejemplo, una cola es un tipo de lista
con restricciones especficas, de modo que el diseo del tipo de dato Cola puede heredar
algunos de los diseos de mtodos (operaciones) del tipo de dato Lis t a.
As pues, Estructura de datos. Algoritmos, abstraccin y objetos trata sobre el estu-
dio de las estructuras de datos dentro del marco de trabajo de los tipos abstractos de
datos (TAD) y bajo la ptica del anlisis y diseo de los algoritmos que manipulan esos
tipos abstractos de datos u objetos.
Objetivos y caractersticas
mas de computadora.
Ensear a los estudiantes y lectores autodidactas, el uso de tcnicas de anlisis y
diseo con las que se pueden evaluar y validar algoritmos.
Proporcionar ejemplos de principios de ingeniera de software y tcnicas de pro-
gramacin que incluyen abstraccin de datos y programacin orientada a objetos.
Introduccin al uso adecuado de las caractersticas especficas de Turbo Borland
Pascal, especialmente aquellas que permiten la compilacin separada: unidades,
tanto predefinidas incorporadas en el compilador como definidas por el usuario.
Requisitos
El nico requisito previo para los estudiantes que emplean este texto es un curso de uno
o dos semestres, de programacin con diseo de algoritmos mediante pseudocdigos, o
lenguajes estructurados, tales como FORTRAN, Pascal, C, C++ o Java. Los estudiantes
que han estudiado sus cursos de programacin sin utilizar el lenguaje Pascal, pueden
seguir este libro junto con alguno de los libros de texto que se listan en la bibliografia
final del libro o en las referencias bibliogrficas de los captulos 1 y 2. No obstante, se
han incluido varios apndices sobre Pascal y Turbo Pascal que pensamos ser suficiente,
al menos, a nivel de sintaxis para refrescar o adquirir aquellos conocimientos bsicos
necesarios para seguir la calificacin de los diferentes algoritmos del libro.
Depuracin
Todos los programas y algoritmos del texto se han probado y depurado. Adems de nuestra
tarea de puesta a punto de programas, diferentes profesores nos han ayudado en esta
tarea. Este es el caso de Matilde Femndez, Lucas Snchez, Jess Prez, Isabel Torralvo
a
y M. del Mar Garca, todos ellos profesores de la Facultad de Informtica y Escuela
Universitaria de Informtica de la Universidad Pontificia de Salamanca en el campus de
Madrid. Su entusiasmo y el cario puesto en esta actividad ha sido desbordante y siem-
pre aportaron sugerencias valiosas. Por supuesto, que cualquier error que todava pudie-
ra existir, es absoluta responsabilidad de los autores.
Los ejercicios y problemas de los diferentes captulos varan en tipo y dificultad.
Algunos son reiterativos para confirmar la comprensin de los textos. Otros implican
modificaciones a programas o algoritmos presentados. Se han incluido gran cantidad de
problemas de programacin con diferentes niveles de complejidad que confiamos sean
complementos eficientes a la formacin conseguida por el lector.
Contenido
Prlogo XXV
Parte 111: Estructuras de datos avanzadas. Las estructuras rboles binarios, equili-
brado y B, grafos, junto con el estudio de algoritmos recursivos y de manipulacin de
las citadas estructuras de datos, son el tema central de esta parte.
Parte IV: Archivos y ordenacin. En esta parte se tratan los importantes algoritmos de
manipulacin de ordenacin, bsqueda y mezcla, junto con el concepto de archivo y su
tratamiento; otro concepto importante que se estudia en esta parte, es el Anlisis de Al-
goritmos, como tcnica indispensable para conseguir algoritmos eficientes.
AGRADECIMIENTOS
Este libro no es slo fruto del trabajo de los autores, tal y como sucede con la creacin
de la mayora de los libros tcnicos. Muchas personas han colaborado de una u otra
manera para que este libro vea la luz.
Entre estas personas queremos destacar aqueIlas que ms han influido en la versin
ltima. Los profesores de Estructuras de datos, Lucas Snchez, Matilde Fernndez y
Jess Prez, del Departamento de Lenguajes y Sistemas Informticos e Ingeniera de
Software de la Facultad de Informtica y de la Escuela Universitaria de Informtica de
la Universidad Pontificia de Salamanca (UPSA), con sus aportaciones y sugerencias fru-
to de su larga experiencia como profesores de la asignatura Estructura de datos en el
campus de Madrid, han ledo y revisado las primeras pruebas de imprenta de este libro,
y nos han dado ideas y sugerencias que han mejorado notablemente el libro. Las profe-
a
soras M. Mar Garca e Isabel Torralvo y el profesor Joaqun Abeger, todos del mismo
departamento que los profesores anteriores, tambin han ledo las galeradas del texto y
han detectado erratas y depurado muchos programas del libro.
Adems de los profesores anteriores, otros profesores de la Facultad y Escuela Uni-
versitaria de Informtica de UPSA han ayudado
,
y apoyado a que esta obra sea una rea-
lidad: Paloma Centenera, Luis Villar y Angel Hermoso.
A todos deseamos agradecer nuestro reconocimiento por su arduo trabajo. No slo
nos han demostrado que son colegas, sino y sobre todo son amigos. Nuestras gracias
ms sinceras a todos eIlos, sin su apoyo y trabajo esta obra no sera la misma.
Naturalmente, no seramos justos si no reconociramos la inmensa ayuda que ha
supuesto y seguir suponiendo las sugerencias, consejos y crticas que nuestros numero-
sos alumnos de todos estos aos pasados nos han hecho tanto en Espaa como en Lati-
noamrica. Son el mejor aliciente que cualquier profesor puede tener. En nuestro caso
ha sido una realidad vivida da a da. Nuestro agradecimiento eterno.
XXVIII Estructura de datos
I
PARTE
,
I
,
-,
1
,
CAPITULO
. , . .,
n enlerla eso are: Intro ucclon
, .,
a a meto o o la e construcclon
e es I ro
.- - _ ., _. -. .. r, '" _. :-:-, -: -/ ';"':. ','.
CONTE
1.1 . Abstraccin.'
1.2. Resolucin de problemas de programacin.
1.3. Herramientas para la resolucin de problemas.
1.4. Factores en la calidad del software.
1.5. El ciclo de vida del software.
1.6. Mtodos formales de verificacin de programas.
1.7. Principios de diseos de sistemas de software.
1.8. Estilo de programacin.
1.9. La documentacin.
1.10. Depuracin.
1.11. Diseo de algoritmos.
1.12. Pruebas (testing).
1.13. Eficiencia.
1.14. Transportabilidad (portabilidad).
RESUMEN.
EJERCICIOS.
PROBLEMAS.
3
4 Estructura de datos
,
1.1. ABSTRACCION
Los seres humanos se han convertido en la especie ms influyente de este planeta, debido
a su capacidad para abstraer el pensamiento. Los sistemas complejos, sean naturales o
artificiales, slo pueden ser comprendidos y gestionados cuando se omiten detalles que son
irrelevantes a nuestras necesidades inmediatas. El proceso de excluir detalles no deseados
o no significativos, al problema que se trata de resolver, se denomina abstraccin, y es
algo que se hace en cualquier momento.
Cualquier sistema de complejidad suficiente se puede visualizar en diversos niveles
de abstraccin dependiendo del propsito del problema. Si nuestra intencin es conseguir
una visin general del proceso, las caractersticas del proceso presente en nuestra abstrac-
cin constar principalmente de generalizaciones. Sin embargo, si se trata de modificar
partes de un sistema, se necesitar examinar esas partes con gran nivel de detalle. Consi-
deremos el problema de representar un sistema relativamente complejo tal como un coche.
El nivel de abstraccin ser diferente segn sea la persona o entidad que se relaciona con ,
el coche: conductor, propietario, fabricante o mecnica.
As, desde el punto de vista del conductor sus caractersticas se expresan en trminos ,
de sus funciones (acelerar, frenar, conducir, etc.); desde el punto de vista del propietario I
sus caractersticas se expresan en funcin de nombre, direccin, edad; la mecnica del ,
coche es una coleccin de partes que cooperan entre s para proveer las funciones citadas,
mientras que desde el punto de vista del fabricante interesa precio, produccin anual de
~
la empresa, duracin de construccin, etc. La existencia de diferentes niveles de abstrac-
cin conduce a la idea de una jerarqua de abstracciones.
Las soluciones a problemas no triviales tiene una jerarqua de abstracciones de modo I
que slo los objetivos generales son evidentes al nivel ms alto. A medida que se des-
ciende en nivel los aspectos diferentes de la solucin se hacen evidentes.
En un intento de controlar la complejidad, los diseadores del sistema explotan las
caractersticas bidimensionales de la jerarqua de abstracciones. La primera etapa al tratar
con un problema grande es seleccionar un nivel apropiado a las herramientas (hardware
y software) que se utilizan para resolverlo. El problema se descompone entonces en subpro-
"
, ,
1.2. RESOLUCION DE PROBLEMAS DE PROGRAMACION
tener que poner menos datos en una coleccin, quitar datos de una coleccin o realizar
preguntas sobre una coleccin de datos. Cuando se construye una solucin, se deben
organizar sus colecciones de datos de modo que se pueda operar sobre los datos fcil-
mente en la manera que requiera el algoritmo. .
Sin embargo, no slo se necesita almacenar los datos en estructuras de datos sino
tambin operar sobre esos datos. De este modo una entidad fundamental ser el tipo
abstracto de datos (TAO) (Abstract Data Type, ADT), que es una coleccin de datos y
un conjunto de operaciones que actan sobre esos datos. Por ejemplo, supongamos que
se necesita almacenar una coleccin de nombres de futbolistas de modo que permita una
bsqueda rpida de un nombre dado. El algoritmo de bsqueda binaria que se estudiar
en el captulo 15 pellnitir buscar en una lista (un array) eficientemente, si el array o
lista est ordenado. Por consiguiente, una solucin a este problema es almacenar los
nombres ordenados en un array y utilizar un algoritmo de bsqueda binaria para buscar
en el array un nombre especificado. Un TAD que visualice el array ordenado junto con
el algoritmo de bsqueda binaria resolver el problema.
Programa
principal
..'
Encontrar
la media
Obtener el
Leer las notas Ordenar
elemento central
de la lista la lista
de la lista
I
modificacin, en tiempo de ejecucin.
Eficiencia
La eficiencia de un software es su capacidad para hacer un buen uso de los recursos que
manipula.
Transportabilidad (portabilidad)
La transportabilidad o portabilidad es la facilidad con la que un software puede ser
transportado sobre diferentes sistemas fisicos o lgicos.
Integridad
La integridad es la capacidad de un software a proteger sus propios componentes contra
los procesos que no tenga el derecho de acceder.
Facilidad de utilizacin
Un software es fcil de utilizar si se puede comunicar consigo de manera cmoda.
Correccin (exactitud)
Capacidad de los productos software de realizar exactamente las tareas definidas por su
especificacin.
Robustez
Capacidad de los productos software de funcionar incluso en situaciones anormales .
Extensibilidad
Facilidad que tienen los productos de adaptarse a cambios en su especificacin. Existen
dos principios fundamentales para conseguir esto:
diseo simple;
descentralizacin.
Reutilizacin
Capacidad de los productos de ser reutilizados, en su totalidad o en parte, en nuevas
aplicaciones.
Compatibilidad
Facilidad de los productos para ser combinados con otros.
Carrasco, Hellman y Verof: Data structures and problem solving with Turbo Pascal, The Benjamingl
I
10 Estructura de datos
El ciclo de vida del software es un proceso iterativo, de modo que se modificarn las
sucesivas etapas en funcin de la modificacin de las especificaciones de los requisitos
producidos en la fase de diseo o implementacin, o bien una vez que el sistema se ha
implementado, y probado, pueden aparecer errores que ser necesario corregir y depu-
rar, y que requieren la repeticin de etapas anteriores.
La Figura 1.3 muestra el ciclo de vida de software y la disposicin tpica de sus
diferentes etapas en el sistema conocido como ciclo de vida en cascada, que supone que
la salida de cada etapa es la entrada de la etapa siguiente.
1.5.1. Anlisis
La primera etapa en la produccin de un sistema de software es decidir exactamente qu
se supone ha de hacer el sistema; esta etapa se conoce tambin como anlisis de requisitos
o especificaciones y por esta circunstancia muchos tratadistas suelen subdividir la etapa
en otras dos:
Anlisis
..
Diseo
Implementacin
Depuracin
Mantenimiento
, .,.
1
Ingeniera de software: introduccin a la metodologa de construccin de grandes programas 11
Descripcin problema
Prototipos de
1.5.2. Diseo
La especificacin de un sistema indica lo que el sistema debe hacer. La etapa de diseo
del sistema indica cmo ha de hacerse. Para un sistema pequeo, la etapa de diseo puede
ser tan sencilla como escribir un algoritmo en pseudocdigo. Para un sistema grande, esta
etapa incluye tambin la fase de diseo de algoritmos, pero incluye el diseo e interaccin
de un nmero de algoritmos diferentes, con frecuencia slo bosquejados, as como una
estrategia para cumplir todos los detalles y producir el cdigo correspondiente.
12 Estructura de datos
Por ltimo, se puede utilizar pseudocdigo 3 para especificar los detalles del algorit-
mo. Es importante que se emplee bastante tiempo en la fase de diseo de sus programas.
El resultado final de diseo descendente es una solucin que sea fcil de traducir en
estructuras de control y estructuras de datos de un lenguaje de programacin especfico,
en nuestro caso, Turbo Borland Pascal.
'i '
, ,
2Para ampliar sobre este tema de diagramas de estructuras, puede consultar estas obras nuestras: Fun-
damentos de programacin, 2." edicin, McGraw-Hill, 1992; Problemas de metodologa de la programa-
cin, McGraw-Hill, 1992, o bien la obra Pascal y Turbo Pascal. Un enfoque prctico, de Joyanes, Zahonero
y Hermoso, en McGraw-Hill, 1995.
J Para consultar el tema del pseudocdigo, vanse las obras: Fundamentos de programacin. A 19orit-
.
mas y estructuras de datos, 2." edicin, McGraw-Hill, 1996, de Luis Joyanes, y Fundamentos de programa-
cin. Libro de problemas, McGraw-Hill, 1996, de Luis Joyanes, Luis Rodrguez y Matilde Fernndez.
,
Ingeniera de software: introduccin a la metodologa de construccin de grandes programas 13
1.5.5. Verificacin
La etapa de pruebas ha de comenzar tan pronto como sea posible en la fase de diseo y
continuar a lo largo de la implementacin del sistema. Incluso aunque las pruebas son
herramientas extremadamente vlidas para proporcionar la evidencia de que un programa
es correcto y cumple sus especificaciones, es dificil conocer si las pruebas realizadas
r
,
, 14 Estructura de datos
I
son suficientes. Por ejemplo, cmo se puede conocer que son suficientes los diferentes
conjuntos de datos de prueba o que se han ejecutado todos los caminos posibles a travs
del programa?
Por esas razones se ha desarrollado un segundo mtodo para demostrar la correccin
o exactitud de un programa. Este mtodo, denominado verificacin formal, implica la
construccin de pruebas matemticas que ayudan a determinar si los programas hacen
lo que se supone han de hacer. La verificacin fOlmal implica la aplicacin de reglas
formales para mostrar que un programa cumple su especificacin: la verificacin. La
verificacin formal funciona bi<;!n en programas pequeos, pero es compleja cuando se
utiliza en programas grandes. La teora de la verificacin requiere conocimientos
matemticos avanzados y por otra parte se sale fuera de los objetivos de este libro; por
esta razn slo hemos constatado la importancia de esta etapa.
La prueba de que un algoritmo es correcto es como probar un teorema matemtico. Por
ejemplo, probar que un mdulo es exacto (correcto) comienza con las precondiciones
(axiomas e hiptesis en matemticas) y muestra que las etapas del algoritmo conducen a
las postcondiciones. La verificacin trata de probar con medios matemticos que los
algoritmos son correctos.
Si se descubre un error durante el proceso de verificacin, se debe corregir su algo-
ritmo y posiblemente se han de modificar las especificaciones del problema. Un mtodo
es utilizar invariantes (una condicin que siempre es verdadera en un punto especfico
de un algoritmo), lo que probablemente har que su algoritmo contenga pocos errores
antes de que comience la codificacin. Como resultado se gastar menos tiempo en la
depuracin de su programa.
1.5.6. Mantenimiento
Cuando el producto software (el programa) se ha terminado, se distribuye entre los posi-
bles usuarios, se instala en las computadoras y se utiliza (produccin). Sin embargo, y
aunque a priori el programa funcione correctamente, el software debe ser mantenido
y actualizado. De hecho, el coste tpico del mantenimiento excede, con creces, el coste
de produccin del sistema original.
Un sistema de software producir errores que sern detectados, casi con seguridad,
por los usuarios del sistema y que no se descubrieron durante la fase de prueba. La correc-
cin de estos errores es parte del mantenimiento del software. Otro aspecto de la fase de
mantenimiento es la mejora del software aadiendo ms caractersticas o modificando
partes existentes que se adapten mejor a los usuarios.
Otras causas que obligarn a revisar el sistema de software en la etapa de mantenimien-
to son las siguientes: 1) Cuando un nuevo hardware se introduce, el sistema puede ser
modificado para ejecutarlo en un nuevo entorno; 2) Si cambian las necesidades del usuario,
suele ser menos caro y ms rpido, modificar el sistema existente que producir un siste-
ma totalmente nuevo. La mayor parte del tiempo de los programadores de un sistema se
gasta en el mantenimiento de los sistemas existentes y no en el diseo de sistemas total-
mente nuevos. Por esta causa, entre otras, se ha de tratar siempre de disear programas
de modo que sean fciles de comprender y entender (legibles) y fciles de cambiar,
,
l
,
;
I Mantenimiento Especificaciones
i,
Evolucin Diseo
Produccin Verificacin
Pruebas Codificacin
!,
Figura 1.4. Etapas del ciclo de vida del software cuyo ncleo aglutinador
es la documentacin.
16 Estructura de datos
Aunque la verificacin formal de programas se sale fuera del mbito de este libro, por su
importancia vamos a considerar dos conceptos clave, asertos (afirmaciones) y precondi-
ciones/postcondiciones invariantes que ayuden a documentar, corregir y clarificar el di-
seo de mdulos y de programas.
Una asercin (aserto) es una frase sobre una condicin especfica en un cierto
punto de un algoritmo o programa.
EJEMPLO 1.1
El siguiente fragm ento de programa contiene una secuencia de sentencias de asigna-
cin, seguidas por un aserto:
A
-- 10 ; ( as e r t o : A e s lO )
x
-- A ,' {as er t o : X es lO }
y -
- x + A; {aser t o : Y e s 2 0}
Este trmino se suele traducir tambin por afirmaciones o declaraciones. El trmino aserto est ms
4
extendido en la jerga informtica, y al igual que aserto , estn los dos trminos admitidos por el DRA E.
!
Ingeniera de software: introduccin a la metodologa de construccin de grandes programas 17
,
EJEMPLO 1.2
,
{Precondiciones y postcondiciones del procedimiento LeerEnteros}
procedure LeerEnteros (Min, Max:lnteger; var N: Integer);
{
Lectura de un entero entre Min y Max en N
Pre : Min y Max son valores asignados
Post: devuelve en N el primer valor del dato entre Min y Max
I si Min <= Max es verdadero; en caso contrario
I
i N no est definido.
}
La precondicin indica que los parmetros de entrada Min y Max se definen antes
de que comience la ejecucin del procedimiento. La postcondicin indica que la ejecu-
cin del procedimiento asigna el primer dato entre Min y Max al parmetro de salida
I, siempre que Min < = Max sea verdadero.
,
Las precondiciones y postcondiciones son ms que un mtodo para resumir acciones de
I un procedimiento. La declaracin de estas condiciones debe ser la primera etapa en el
diseo y escritura de un procedimiento. Es conveniente en la escritura de algoritmos de
procedimientos, se escriba la cabecera del procedimiento que muestra los parmetros
afectados por el procedimiento as como unos comentarios de cabecera que contienen
las precondiciones y postcondiciones.
,,
~
,
18 Estructura de datos
La primera asercin, la precondicin, describe las condiciones que han de ser verda-
deras antes de ejecutar P.
La segunda asercin, la postcondicin, describe las condiciones que han de ser ver-
daderas despus de que P se ha ejecutado (suponiendo que la precondicin fue verdade-
ra antes). El modelo general es:
EJE LO 1.3
I
,
ElprocedimientoOrdenarSele cc ion (A, m, n) ordena a los elementosdelarray.
A [m . . n] en orden descendente. El modelo correspondiente puede escribirse as:
PROBLEMA 1.1
Encontrar la posicin del elemento mayor de una lista con indicacin de precondicio-
nes y postcondiciones.
function EncontrarMax (var A:Lista; m, n: Integerl : Integer;
{preco ndicin : m < n}
{pos tcondicin : devuelv e posic in eleme nto mayor en A[m .. n]}
var i, j : In t eger ;
begin
l := m;
j : = n ; {aser c i n}
repeat
i :=i+l 0 ;
i f A [ i] > A [ j] then j : = i ;
until i = n;
En co ntrarMax : = J ; {devuelve j como elemento mayor}
end;
PROBLEMA 1.2
1.4
Un bucle que calcula la suma de los n primeros elementos del array (lista) A:
EJEMPLO 1.5
Invariante de un bucle que sume n enteros (n entero positivo); i, Suma, n son de tipo
entero.
20 Estructura de datos
lo que significa: i debe ser menor que o igual que n y despus de cada pasada o vuelta,
Suma es igual a la suma de todos los enteros positivos menores que i.
En la verificacin de programas la invariante del bucle se utiliza para probar que el
bucle cumple su especificacin. Para nuestro propsito, se puede utilizar el invariante
del bucle para documentar el comportamiento del mismo y se situar justo antes del
cuerpo del bucle.
{Suma de enteros 1 a n}
{prec o ndicin : n > = 1}
Suma := O;
1, - ,
. - 1
while i <= n do
{ in variante : i <= n +1 y Suma es 1+2+ ... i - 1}
begin
,
Suma : Suma + l ;
,
1 . -- i+1
.
end;
{p o stco ndicin : Suma es 1+2+3+ .. n-1+n}
EJEMPLO 1.6
Si la variante de un bucle es:
{invariante: i <= n y Suma es la suma de todos los nmeros ledo s del
t eclado}
. -- O',
1 < n {condi cin / prueba del bucle}
Read (Item);
Suma : = Suma + I tem ; {cuerpo del bucle}
i :=i+l
,
Ingeniera de software: introduccin a la metodologa de construccin de grandes programas 21
Con toda esta informacin es una tarea fcil escribir el bucle de suma :
Suma : = 0.0;
i : = O;
while i do <{y , toma l os va lores 0,1, 2 , 3 , .. n - 1}
n
Rea d ( Item);
Su ma : = Su ma + Item ;
i : = i + 1
end;
EJEMPLO 1.7
En los bucles for es p osible declarar tambin invariantes, pero teniendo presente
la particularidad de esta sentencia: la variable de control del bucle es indefinida des-
pus que se sale del bucle, p or lo que para definir su invariante se ha de considerar que
dicha variable de control se incrementa antes de salir del bucle y mantiene su valor
.fi nal.
PROBLEMA 1.3
Ingeniera de software: introduccin a la metodologa de construccin de grandes programas 23
1.7. -
PRINCIPIOS DE DISENO DE SIST S DE SOFTWARE
24 Estructura de datos
i
Ingeniera de software: introduccin a la metodologa de construccin de grandes programas 25
1.7.3. Modificabilidad
EJEMPLO 1.8
Los lmites del rango de un array suelen ser definidos mejor mediante constantes con
nombre que mediante constantes numricas. As, la declaracin tpica de un array y su
proceso posterior mediante un bucle es:
ya que cuando se desee cambiar el nmero de elementos del array slo sera necesario
cambiar el valor de la constante NumeroDeItems, mientras que en el caso anterior
supondr cambiar la declaracin del tipo y el ndice de bucle, mientras que en el segun-
do caso slo el valor de la constante.
Erro r de rang o
i,
,
- - - - - - - -- - ----------------------------------------------_.
No utilizar tipos subrango para detectar datos de entrada no vlidos. Por ejemplo,
si se desea comprobar que detelminados tipos nunca sean negativos, se pueden
cambiar las definiciones de tipo global a:
type TipoNoNeg - O .. maxint; {tipo nuevo}
TipoMillar = Bajo .. Alto; {permanece el mismo}
TipoTabla = array[TipoMillar] of TipoNoNeg;
{un array de este tipo contiene s610 enteros no negativos}
Cada subprograma debe comprobar los valores de sus parmetros. As, en el caso
de la funcin S urna 1 n te rv a 1 o que suma todos los enteros comprendidos
entre m y n .
function Sumalntervalo (m,n:lnteger) : Integer;
{
precondici6n : m y n son enteros tales que m < = n
postcondici6n: Devuelve Sumalntervalo = m+(m+l)+ ... +n
m y n son inalterables
}
var Suma, Indice : Integer;
begin
Suma := O;
for Indice := m to n do
Suma := Suma + Indice;
Sumalntervalo := Suma
end;
1.7.8. Eficiencia
El objetivo de la eficiencia es hacer un uso ptimo de los recursos del programa. Tradicio-
nalmente, la eficiencia ha implicado recursos de tiempo y espacio. Un sistema eficiente
- _ .. _...
28 Estructura de datos
es aquel cuya velocidad es mayor con el menor espacio de memoria ocupada. En tiempos
pasados los recursos de memoria principal y de CPU eran factores clave a considerar para
aumentar la velocidad de ejecucin. En el ao 1997 las CPU (UCP, Unidad Central de
Proceso) tpicas de los PC eran Pentium de 166 y 200 MHz. En el ao 1988 son usuales
los Pentium de 233 Mhz y Pentium 11 de 266 Mhz y son ya muy frecuentes; las memo-
rias centrales usuales son 16 Mbytes o 32 Mbytes, aunque bsicamente los tamaos de
memorias tradicionales para trabajos profesionales ya son de un mnimo de 64 Mbytes;
el factor eficiencia ya no se mide con los mismos parmetros de memoria y tiempo. Hoy
da debe existir un compromiso entre legibilidad, modificabilidad y eficiencia, aunque,
con excepciones, prevalecer la legibilidad y modificabilidad.
,
1.8. ESTILO DE PROGRAMACION
30 Estructura de datos
variables globales, dado que los efectos de sus acciones producen los efectos laterales
indeseados, normalmente.
En general, el uso de variables globales con subprogramas no es correcto. Sin em-
bargo, el uso de la variable global, en s, no tiene porqu ser perjudicial. As, si un dato
es inherentemente importante en un programa al que casi todo subprograma debe acce-
der al mismo, entonces ese dato ha de ser global por naturaleza.
Usar nombres para nombrar objetos de datos tales como variables, constantes y
tipos. Utilizar Salario mejor que APagar o Pagar.
Utilizar verbos para nombrar procedimientos. LeerCaracter, LeerSigCar
y CalcularSigMov son procedimientos que realizan estas acciones mejor que
SigCar o SigMov (siguiente movimiento).
Utilizar formas del verbo sen> o estar para funciones lgicas. SonIgua-
les, EsCero, EsListo y EsVacio se utilizan como variables o funciones l-
glcas.
if Son Igual es (A . B)
..
Ingeniera de software: introduccin a la metodologa de construccin de grandes programas 31
Const pi = 3.141592;
Const NurnDiasSernana = 7,
Const Longitud = 45;
Este sistema tiene la ventaja de la facilidad para cambiar un valor determinado bien
por necesidad o por cualquier error tipogrfico
El uso de una sentencia got o casi siempre viola al menos una de estas condiciones.
Adems es muy dificil verificar la exactitud de un programa que contenga una sentencia
goto. Por consiguiente, en general, se debe evitar el uso de got o. Hay, sin embargo,
raras situaciones en las que se necesita un flujo de control excepcional, tales casos in-
cluyen aquellos que requieren o bien que un programa termine la ejecucin cuando ocurre
un error, o bien que un subprograma devuelve el control a su mdulo llamador. La inclu-
sin en Turbo Borland Pascal de sentencias hal t y exi t hacen innecesario en cual-
quier caso el uso de goto.
,
,
1.8.7. Uso adecuado de funciones
,
,,
Pascal le proporciona un sistema para realizar tareas distintas a las funciones primitivas
, incorporadas al lenguaje. El mecanismo de llamada a un procedimiento o funcin defi-
nida por el usuario se puede activar desde cualquier punto de un programa en el que se
necesite ese subprograma.
En el caso de una funcin, sta se debe utilizar siempre que se necesite obtener un
nico valor. Este uso corresponde a la nocin matemtica de funcin. Por consiguiente, es
muy extrao que una funcin realice una tarea diferente de devolver un valor y no debe
hacerlo.
,' "
" ' "
,
.
'
'
Una funcin no ,.,.,'" ... " nct.dct., SIDO devolver el valor requ.erido. Es decir, una
'"' funcinnUrttll """,'kla'r:l. ,"- -. ' j 'j' :."i';: ':, .,.;':, !: . --,--" - - , _, ::,: ~ " , :', ';,' ", ':: , : r; ::T,' ',,:~,:,::: ", ',.--- - " -
,
. .. .. - . .
- - .
- -
Funciones con variables globales. Si una funcin referencia a una variable glo-
bal, presenta el peligro de un posible efecto lateral. En general, las funciones no
deben asignar valores a variables globales.
Funciones con parmetros variables. Un parmetro variable es aquel en que su
valor cambiar dentro de la funcin. Este efecto es un efecto lateral. En general,
las funciones no deben utilizar parmetros variables. Si se necesitan parmetros
variables utilizar procedimientos.
Funciones que realizan entrada/salida (E/S). Las E/S son efectos laterales. Las
funciones no deben realizar E/S.
cia necesita acciones excepcionales que constituirn un mal estilo en la ejecucin normal
de un programa. Por ejemplo, el manejo de funciones puede implicar el uso de funciones
con efectos laterales.
Un subprograma debe comprobar ciertos tipos de errores, tal como entradas no vli-
das o parmetros valor. Qu accin debe hacer un subprograma cuando se encuentra un
error? Un sistema puede, en el caso de un procedimiento, presentar un mensaje de error
y devolver un indicador o bandera lgica a la rutina llamadora para indicarle que ha
encontrado una lnea de datos no vlida; en este caso, el procedimiento deja la responsa-
bilidad de realizar la accin apropiada a la rutina llamadora. En otras ocasiones, es ms
adecuado que el propio subprograma tome las acciones pertinentes por ejemplo,-
cuando la accin requerida no depende del punto en que fue llamado el subprograma.
Si una funcin maneja errores imprimiendo un mensaje o devolviendo un indicador,
viola las reglas contra efectos laterales dadas anteriormente.
Dependiendo del contexto, las acciones apropiadas pueden ir desde ignorar los datos
errneos hasta continuar la ejecucin para terminar el programa. En el caso de un error
fatal que invoque la terminacin, una ejecucin de hal t puede ser el mtodo ms lim-
pio para abortar. Otra situacin delicada se puede presentar cuando se encuentra un error
fatal en estructuras condicionales if - then-else o repetitivas while, repeat. La
primera accin puede ser llamar a un procedimiento de diagnstico que imprima la infor-
macin necesaria para ayudarle a determinar la causa del error; pero despus de que el
procedimiento ha presentado toda esta informacin, se ha de terminar el programa. Sin
embargo, si el procedimiento de diagnstico devuelve el control al punto en el que fue
llamado, debe salir de muchas capas de estructuras de control anidadas. En este caso la
solucin ms limpia es que la ltima sentencia del procedimiento de diagnstico sea
hal t.
1.8.9. Legibilidad
Para que un programa sea fcil de seguir su ejecucin (la traza) debe tener una buena
estructura y diseo, una buena eleccin de identificadores, buen sangrado y utilizar l-
neas en blanco en lugares adecuados y una buena documentacin.
Como ya se ha comentado anteriormente se han de elegir identificadores que describan
fielmente su propsito. Distinguir entre palabras reservadas, tales como f or o procedu-
re, identificadores estndar, tal como real o integer e identificadores definidos
por el usuario. Algunas reglas que hemos seguido en el libro son:
Los bloques deben ser sangrados suficientemente para que se vean con claridad
(3 a 5 espacios en blanco puede ser una cifra aceptable).
En una sentencia compuesta, las palabras be g i n - en d deben estar alineadas:
begin
<sentencia1>
<sen tencia 2>
i
Sangrado consistente. Sangrar siempre el mismo tipo de construcciones de igual
manera. Algunas propuestas pueden ser:
bucles while/repeat/for
Sentencias if-then-else
if <con d i cin > if <condicin > then
then <sen tenc i a1 > <senten cia1>
elee <sen t encia2 > elee
<sentencia2>
if <condicin >
then
<sentencias>
elee
<s entencias>
1.9. LA DOCUMENTACiN
En entornos interactivos como el caso de Turbo Borland Pascal, las misiones del
usuario y operador suelen ser las mismas. As pues, la documentacin del programa se
puede concretar a:
7 Brookshear, Glen J.: Introduccin a las ciencias de la computacin, Addison-Wesley, 1995, pg. 272.
I
36 Estructura de datos
documentacin interna,
documentacin externa.
Ingeniera de software: introduccin a la metodologa de construccin de grandes programas 37
Ejemplos
var
Radio ... ( entrada, rad i o de un c irc u lo )
( Calc u l ar Area)
Are a : = pi * radio * rad i o ;
Documentacin ajena al programa fuente, que se suele incluir en un manual que acom-
paa al programa. La documentacin externa debe incluir:
Listado actual del programa fuente, mapas de memoria, referencias cruzadas, etc.
Especificacin del programa: documento que define el propsito y modo de fun-
cionamiento del programa. I
Diagrama de estructura que representa la organizacin jerrquica de los mdulos
que comprende el programa.
Explicaciones de frmulas complejas.
Especificacin de los datos a procesar: archivos externos incluyendo el formato
de las estructuras de los registros, campos, etc.
Formatos de pantallas utilizados para interactuar con los usuarios.
Cualquier indicacin especial que pueda servir a los programadores que deben
mantener el programa.
L,
38 Estructura de datos
Aunque existe la tendencia entre los programadores y sobre todo entre los princi-
piantes a documentar los programas como ltima etapa, esto no es buena prctica, lo
idneo es documentar el programa a medida que se desarrolla. La tarea de escribir un
programa grande se puede extender por periodos de semanas o incluso meses. Esto le ha
de llevar a la consideracin de que lo que resulta evidente ahora puede no serlo de aqu
a dos meses; por esta causa, documentar a medida que se progresa en el programa es una
regla de oro para una programacin eficaz.
Regla
,
1.10. OEPU RACION
Una de las primeras cosas que se descubren al escribir programas es que un programa
raramente funciona correctamente la primera vez. La ley de Murphy si algo puede ser
incorrecto, lo ser parece estar escrita pensando en la programacin de computadoras.
Aunque un programa funcione sin mensajes de error y produzca resultados, puede
ser incorrecto. Un programa es correcto slo si se producen resultados correctos para
todas las entradas vlidas posibles. El proceso de eliminar errores bugs se denomi-
na depuracin (debugging) de un programa.
Ingeniera de software: introduccin a la metodologa de construccin de grandes programas 39
40 Estructura de datos
(Posicin una)
WriteLn ('Est situado en posicin una del procedimiento Test');
WriteLn ('A=', a, lB = " b, le = " e);
Las dos posiciones clave para situar los puntos de ruptura son al principio y al final
de un subprograma. Se deben examinar los valores de los parmetros en estas dos
posiciones utilizando o bien sentencias Wr i t e o ventanas de inspeccin u observacin
(watches).
Las variables cuyos valores son arrays u otras estructuras puede ser interesante exami-
narlas. Para ello se recurre a escribir rutinas especficas de volcado (presentacin en
pantalla o papel) que ejecuten la tarea. Una vez diseada la rutina se llama a ella desde
puntos diferentes segn interesa a la secuencia de flujo de control del programa y los
datos que sean necesarios en cada caso.
1.11.
-
DISENO DE ALGORITMOS
Tras la fase de anlisis, para poder solucionar problemas sobre una computadora, debe
conocerse cmo disear algoritmos. En la prctica sera deseable disponer de un mtodo
para escribir algoritmos, pero, en la realidad, no existe ningn algoritmo que sirva para
realizar dicha escritura. El diseo de algoritmos es un proceso creativo. Sin embargo,
existen una serie de pautas o lneas a seguir que ayudarn al diseo del algoritmo (Ta-
bla 1.1).
1. FOllnular una solucin precisa del problema que debc solucionar el algoritmo.
2. Ver si existe ya algn algoritmo para resolver el problema o bien se puede adaptar uno ya existente
(algoritmos conocidos).
3. Buscar si existen tcnicasestn~r(luesePlWdaiuwlizar, para resolver el.problema.
4. Elegir una estructura de dato~adecuada.
. . " .. ..
5. Dividir el problelll!l 1:11 s\l:bP(Clbl!<lllas Yplic.arel mtodo a ca4a uno~ los subproblemas (di$eo .
. descendente).
. . , ....
. ", '" ~
....
",;:,; ,:'
:":: ". ,. :."., ,, ...
que un programa es correcto es probar todos los casos posibles (realizar una prueba
exhaustiva), situacin tcnicamente imposible, incluso para los programas ms simples.
Consideremos un caso sencillo: calcular la media aritmtica de las temperaturas de un
mes dado; una prueba exhaustiva requerir todas las posibles combinaciones de tempe-
raturas y das de un mes: tarea ardua, laboriosa y lenta.
No obstante, el anlisis anterior no significa que la comprobacin sea imposible;
al contrario, existen diferentes metodologas formales para las comprobaciones de pro-
gramas. Una filosofa adecuada para pruebas de programas incluye las siguientes con-
sideraciones:
1. Suponer que su programa tiene errores hasta que sus pruebas muestren lo contrario.
2. Ningn test simple de ejec4cin puede probar que un programa est libre de
error.
3. Trate de someter al programa a pruebas duras. Un programa bien diseado mani-
pula entradas con elegancia. Por este trmino se entiende que el programa no
produce errores en tiempo de ejecucin ni produce resultados incorrectos; por el
contrario, el programa, en la mayora de los casos, visualizar un mensaje de error
claro y solicita de nuevo los datos de entrada.
4. Comenzar la comprobacin antes de terminar la codificacin.
5. Cambiar slo una cosa cada vez.
Cada vez que se ejecuta un programa con algunas entradas, se prueba a ver cmo
funciona el trabajo para esa entrada particular. Cada prueba ayuda a establecer que el
programa cumpla las especificaciones dadas.
Se deben buscar numerosos mtodos para encontrar datos de prueba que produzcan
probablemente errores. El primer mtodo se basa en identificar y probar entradas deno-
minadas valores externos, que son especialmente idneos para causar errores. Un valor
externo o lmite de un problema en una entrada produce un tipo diferente de comporta-
miento. Por ejemplo, suponiendo que se tiene una funcin ver_hora que tiene un
parmetro hora y una precondicin:
Los dos valores lmites de ver_hora son hora igual a O (dado que un valor menor
de O es ilegal) y hora igual a 23 (dado que un valor superior a 23-24 ... es ilegal). Puede
ocurrir que la funcin se comporte de modo diferente para horario matutino (O a 11) o
nocturno (12 a 23), entonces 11 y 12 sern valores extremos. Si se espera un comporta-
miento diferente para hora igual a O, entonces 1 es un valor extremo. En general no
existe una definicin precisa de valor extremo, pero debe ser aquel que muestre un com-
portamiento lmite en el sistema.
l. Asegrese de que cada lnea de su cdigo se ejecuta al menos una vez para algu-
nos de sus datos de prueba. Por ejemplo, puede ser una porcin de su cdigo que
maneje alguna situacin rara.
2. Si existe alguna parte de su cdigo que a veces se salte totalmente, asegrese, en
ese caso, que existe al menos una entrada de prueba que salte realmente esta
parte de su cdigo. Por ejemplo, un bucle en el que el cuerpo se ejecute, a veces,
cero veces. Asegrese de que hay una entrada de prueba que produce que el
cuerpo del bucle se ejecute cero veces.
de un end). Si una sentencia tiene un error de sintaxis, no puede ser traducida y su pro-
. ,
,
grama no se ejecutara.
Cuando se detecta un error, Turbo Borland Pascal carga automticamente el archivo
fuente, sita el cursor en el error y visualiza un mensaje de error.
NOllnalmente, los mensajes de error son fciles de encontrar. El siguiente ejemplo pre-
senta dos errores de sintaxis: el punto y coma que falta al final de la primera lnea y la
palabra WritaLn mal escrita, debera ser WriteLn.
Suma := O
for 1 := O to 10 do
~. WritaLn (Suma/lO);
I
1.12.2. Errores en tiempo de ejecucin
suceden cuando el programa trata de hacer algo imposible o ilgico. Los errores de eje-
", cucin slo se detectan en la ejecucin. Errores tpicos son: la divisin por cero, intentar
46 Estructura de datos
La media est calculada mal ya que existen once nmeros (O a 10) y no diez como se ha
escrito.
Si se desea escribir la sentencia:
y se escribe:
Es un error lgico (+ por *) ya que a priori el programa funciona bien, y sera dificil,
por otra parte, a no ser que el resultado fuese obvio, detectar el error.
1.12.4. El depurador
Turbo Borland Pascal tiene un programa depurador disponible para ayudarle a depurar
un programa; el programa depurador le permite ejecutar su programa, una sentencia cada
vez, de modo que se pueda ver el efecto de la misma. El depurador imprime un diagns-
tico cuando ocurre un error de ejecucin, indica la sentencia que produce el error y
permite visualizar los valores de variables seleccionadas en el momento del error. Asi-
mismo, se puede seguir la pista de los valores de variables seleccionadas durante la eje-
cucin del programa (traza), de modo que se pueda observar cmo cambian estas varia-
bles mientras el programa se ejecuta. Por ltimo se puede pedir al depurador que detenga
la ejecucin en determinados puntos (breakpoints); en esos momentos se pueden inspec-
cionar los valores de las variables seleccionadas a fin de determinar si son correctas.
El depurador tiene la gran ventaja de posibilitar la observacin de los diferentes va-
lores que van tomando las variables dentro del programa.
1.13. EFICIENCIA
La eficiencia de un programa es una medida de cantidad de recursos consumidos por el
programa. Tradicionalmente, los recursos considerados han sido el tiempo de ejecucin
y/o el almacenamiento (ocupacin del programa en memoria). Mientras menos tiempo
se utilice y menor almacenamiento, el programa ser ms eficiente.
El tiempo y almacenamiento (memoria) de la computadora suelen ser costosos y por
ello su ahorro siempre ser importante. En algunos casos la eficiencia es crticamente
Ingeniera de software: introduccin a la metodologa de construccin de grandes programas 47
45 73 81 1 20 1 60 321 450
se utiliza
Ejecucin
Intro d uzca 10 en t ero s en or de n asce nd ente :
2 5 8 12 23 37 45 89 1 12 234
I n tr o du c ir n m e r o a b uscar :
27
el e l e mento 27 n o es t en l a l ista
Bus q ueda1 te rm i n ada e n
10 i t e r ac i o n es
el ele mento 2 7 n o es t en l a lista
Bus qued a2 t ermi nada en
6 i t era cione s
RESUMEN
La ingeniera de software trata sobre la creacin y produccin de programas a gran escala. El ,
ciclo de vida del software consta de las fases:
Anlisis de requisitos y especificacin.
Diseo.
1
Implementacin (codificacin y depuracin).
If... ,
50 Estructura de datos
Prueba.
Evolucin.
Mantenimiento.
Si se desea crear buenos programas en Turbo Borland Pascal, los conceptos de unidades y progra-
macin modular sern vitales en el desarrollo de los mismos.
EJERCICIOS
1.1. Cul es el invariante del bucle siguiente?
! I nd i ce := 1 ;
Suma : = A [ 1 ] ;
while Ind ic e < N hacer
begin
Indice : = Succ ( In d i ce) ;
Sum a := Suma + A [ Indice ]
end;
1.2. Considere el programa siguiente que interactivamente lee y escribe el nmero de identifica-
cin, nombre, edad y salario (en millares de pesetas) de un grupo de empleados. Cmo se
puede mejorar el programa?
program Test ;
var xl, x 2, x3 , i : integ er ;
Nombre: array [ l .. 10 ] of ch ar;
begin
while not eo f do
begin
Re ad ( xl ) ;
for i : = 1 to 8 do
Read ( Nombre [ i] ) ;
Rea d Ln ( x 2 , x 3 ) ;
Wr it e Ln ( x 1 , Nombr e ,x 2 , x 3 )
end
end;
1.4. Escribir una [uncin que devuelve el total de dgitos (n) distintos de cero en un nmero
entero arbitrario (Nmero). La solucin debe incluir un bucle while con el siguiente inva-
riante de bucle vlido.
I {invarian t e :
O <= Tota l <= n y N me r o se h a div i d i d o po r 10 veces To ta l }
,
.. -
1.5. Escribir un invariante de bucle para el siguiente segmento de cdigo
Produc t o : = 1 ;
Con ta d o r := 2 ;
while Cont ador < 10 do
begin
Producto : = Producto * Co ntador;
Co ntador : = Contador + 1
end;
PROBLEMAS
1.1. Escribir un programa que lea una lista de 100 o menos enteros y a continuacin realice las
siguientes tareas: visualizar la lista ordenada desde el mayor hasta el menor; visualizar lista
en orden inverso, calcular la media; calcular la mediana; listar las listas en orden creciente y
en orden decreciente, mostrando la diferencia de cada valor con la media y la mediana. Es
conveniente que cada tarea se realice con un mdulo y luego se integren todos en un pro-
grama.
1.2. A la entrada de un aparcamiento, un automovilista retira un ticket en el cual est indicado
su hora de llegada. Antes de abandonar el aparcamiento se introduce el ticket en una m-
quina que le indica la suma a pagar. El pago se realiza en una mquina automtica que
devuelve cambio.
Escribir un programa que simule el trabajo de la mquina. Se supone que:
1.3. Escribir un programa que contenga una serie de opciones para manipular un par de matri-
ces (suma, resta y multiplicacin). Cada procedimiento debe validar sus parmetros de en-
trada antes de ejecutar la manipulacin requerida de datos.
1.4. Un viajante de comercio debe visitar N ciudades. Parte de una de ellas y debe volver a su
- punto de partida. Conoce la distancia entre cada una de las ciudades y desea hacer un viaje
A partir de cada ciudad, elige como ciudad siguiente la ms prxima entre las ciudades
que no ha visitado.
Se suponen datos: la lista de ciudades, las distancias (en kilmetros) entre cada una de ellas
y el nombre de la ciudad de partida. Elegir un algoritmo que calcule el recorrido ms corto.
1.5. Se tiene la lista de una clase que contiene un nombre de estudiante y las notas de cinco
'. exmenes. Se desea escribir un programa que visualice la media de cada alumno, la nota
media ms alta y la nota media ms baja, junto con los nombres correspondientes.
1.6. Se desea disear un programa que permita adiestrar a un nio en clculos mentales. Para
ello el nio debe elegir entre las cuatro operaciones aritmticas bsicas; la computadora le
presentar la operacin correspondiente entre dos nmeros, y el nio debe introducir desde
el teclado el resultado. El nio dispone de tres tentativas. Caso de acertar, la computadora
debe visualizar Enhorabuena, y en caso de fallo Lo siento, intntalo otra vez.
52 Estructura de datos
1.7. Escribir un programa que construya un directorio telefnico interactivo que contiene una
coleccin de nombres y nmeros de telfonos. Las caractersticas del directorio han de
ser: 1) poder insertar una nueva entrada en el directorio; 2) recuperar una entrada del direc-
torio; 3) cambiar una entrada del directorio, y 4) borrar una entrada del directorio. Nota: El
directorio debe estar ordenado alfabticamente.
,
,
,
I
,
CAPITULO
.,
-,onstrucclon ran es ro ramas:
, .
mo u os versus unl a es
, , - - -- "- - ,- ~" -
--
-
-,
.
CONTENIDO
,
;
,,}
Una de las caractersticas ms interesantes de Turbo Borland Pascal 5/
6/7 es la posibilidad de descomponer un programa grande en produc-
tos ms pequeos que se pueden compilar independientemente. Estos
mdulos se denominan unidades y eliminan el inconveniente de las
versiones anteriores a 4.0 de la limitacin de la memoria ocupada por 1
programas ejecutables a 64 K. Los lectores que hayan utilizado Modu-
la-2 encontrarn familiar el concepto unidad, ya que unidad (en Turbo
Borland Pascal) y mdulo (en Modula-2) representan el concepto de
compilacin separada y la posibilidad de construir grandes programas I
enlazando unidades compiladas separadamente para construir un pro-
grama ejecutable. Como resultado de ello, cuando se realiza un cam-
bio en el cdigo fuente, slo se tiene que compilar el segmento al que
afecta la modificacin.
53
r
54 Estructura de datos
i
Aceptamos el tllnino inicializacin por su extensa difusin en la jerga infollntica, aun a sabiendas
I 1
que dicho trmino no es aceptado por el DRAE y su expresin correcta sera iniciacin. 1
1
<1,
j
;
,
1
Ejemplo de declaracin
unit Ray o ;
interface
uses DOS , Graph, Crt ; (se utilizan las un i dade s DO S, Gr aph y Crt )
var
a , b, e : int ege r
function Ex po n encia l (a, b : i n t eger) : rea l;
procedure Di v id ir (x, y : integ er ;var cocien t e : i nt eg er) ;
2 El identificador puede tener de uno a ocho caracteres ms un punto y una extensin tal como .PAS .
, 56 Estructura de datos
Observaciones
l. La unidad Ray o puede utilizar cualquier procedimiento o funcin presente en
las unidades estndar Dos, Gr aph o Cr t .
2. Se declaran tres variables globales; a, b, e (estn disponibles a otras unidades y
programas que utilicen la unidad Rayo ). Se debe extremar el cuidado a la hora
de declarar variables globales en la seccin de interfaz de la unidad.
unit Rayo ;
interface
function Expo n encia l (A, B : i n t eger ) : rea l;
procedure Di v i dir (X , Y : in t eger ; var Cocien t e : in t eger) ;
implementation
function Expon e n c i al (A, B : i nt eg er) : real ;
var
P, I : integer;
begin
P := 1;
for 1 := 1 to B do
P := P * A ;
Expone nc ial .' - P
end;
Ntese que la declaracin de una unidad est terminada por la palabra reservada
end y un punto.
Las variables globales pueden ser declaradas dentro de una seccin de implementacin,
pero estas variables sern globales a la unidad solamente y no accesibles a cualquier otra
unidad o programa.
I
Construccin de grandes programas: mdulos versus unidades 57
crear sus propias unidades, enriqueciendo as los recursos bsicos. En general una unidad
,,
, puede llamar a otras unidades.
!
,
,
2.3. CREACION DE UNIDADES
interface
uses ert; ~ opcional Seccin de interfaz
procedure Frase(Texto : string);
implementation
uses Printer; ~ opcional
var
MiVar : Integer
procedure Frase;
begin Seccin de implementacin
ClrScr;
GotoXY ((80-Length (Texto)) div 2,1)
Write (texto);
end;
begin
Mi Var := o Seccin de iniciacin
end.
Para utilizar una unidad en su programa, debe incluir una sentencia uses para indi-
car al compilador que est utilizando esa unidad.
program Prueba;
uses demo;
Turbo Borland Pascal espera que el nombre del archivo fuente tenga el mismo nom-
bre de la unidad. Por ejemplo, la unidad demo se encuentra en el archivo demo . tpu.
Si el nombre de la unidad fuera demostra. TPU, Turbo Borland Pascal tratar de en-
contrar un archivo demostra. TPU para evitar estas contrariedades se puede utilizar
una directiva del compilador ($ U) , que permite especificar el nombre del archivo en
que se encuentra la unidad. As, por ejemplo, si la unidad utilidad se encuentra en el
archivo VARIOS. PAS un programa puede llamar de la forma siguiente:
program Test;
uses
Crt, {SU VARIOS.PAS} utilidad;
Una vez sin errores, conviene activar la opcin Comp i le a d i sk y volver a compilar.
Turbo Borland Pascal crea un archivo con extensin T PU. Este archivo se puede
dejar o mezclarlo con TURBO . TP L.
EJEMPLO 2.1
Escribir una unidad que conste a su vez de un procedimiento para intercambiar los
valores de dos variables, as como calcular su valor mximo.
unit Demol;
interface
procedure I nter cambio (var I , J : int eg er) ;
function Ma x imo (I , J : i ntege r) : i nt eger ;
implementation
procedure I n terca mbio;
var
Aux : integer ;
begin
Aux - I ,
-
1 - J ;
J - Aux
-
end;
function Maximo;
begin
i f I>J
then Ma x imo -- I
else Maximo -- J
end;
end.
Tras editar el programa, gurdelo en disco con el nombre Demo 1 . PAS , a continua-
cin compilar en disco. El cdigo objeto resultante ser Demo l . TPU. Un programa que
utiliza la unidad Demo 1 es:
60 Estructura de datos
program Prueba;
uses
Demo 1 ;
var
X, y : integer ;
begin
,
Write ('Introdu c i r dos num e r as enter os ' ) ;
ReadLn (X, Y);
In terca mbio (X , y); Wr it eLn (X , " , Y) ;
WriteLn ('e l valor mxi mo es ', Maxi mo( X, Y)) ;
end.
EJEMPLO 2.2
Construccin de una unidad con un procedimiento Intercambio y una funcin Potencia
o Exponenciacin (xn; x: real, n: entero).
unit Ca l cu lo;
procedure I n te rcambio ;
function Po t~nc ia ;
Reglas de compilacin
Turbo 80rtand diferencia unidades de programas por las palabras reservadas con
las que comienzan y acta de acuerdo con ellas.
62 Estructura de datos
El uso de una unidad o diferentes unidades aade muy poco tiempo (normalmente
menos de un segundo) al tiempo de compilacin de su programa. Si las unidades estn
cargadas en un archivo de disco independiente, se pueden necesitar unos segundos para
leerlas del disco.
Un programa puede utilizar ms de una unidad. En este caso todas las unidades se
listan en la sentencia uses, separadas por comas, como en el siguiente ejemplo:
program Prueba;
uses Ob j etos , Unidad2;
unit Unida d2 ;
interface
uses ObViejos, Obje t os ;
Construccin de grandes programas: mdulos versus unidades 63
unit Fi n anc a;
{dec la r a pro cedim ien to pa ra co n ve rt ir ca pit ales}
interface
const
Ta sa = 4. 25 ;
procedure Un o (Cap it al : r ea l) ;
procedure Dos(Cap it al : rea l ) ;
implementation
const
Banda = '*';
unit P;
interface
uses A, B, C;
,
,
)
implementation
uses Q; 1
2.3
El programa circular utiliza una unidad denominada Visualiz, que incorpora un procedi-
miento denominado EscribirEnPosicionXY, que a su vez se llama a otro procedimiento
denominado VerError que pertenece a una unidad denominada Errores, que contiene
una llamada a la unidad Visualizar.
program Circular;
{visualizar texto utilizando EscribirEnPosicionXY}
uses
Crt, Visualiz;
begin
ClrScr; {limpieza de la pantalla}
EscribirEnPosicionXY (1, 1, 'Test');
EscribirEnPosicionXY (90, 90,' Fuera de pantalla');
EscribirEnPosicionXY (10, 2, 'Retorno a pantalla')
end.
unit Vi suali z;
interface
procedure Escrib i r Enpos i cionXY (X,Y :in teger; Me n sa j e :string ) ;
implementation
uses Crt, Error ;
procedure Es crib irE nPo si cionXY (X ,Y:in teger ; Men saje: string);
begin
if (X in [ 1 .. 80 ] ) and (Y in [1 .. 2 5])
then
begin
GotoXY (X , Y, ) ;
Wr it e (Mensaje)
end
else
VerEr r or ( ' Coordenadas XY fue r a de rango ' )
end
end.
unit Error;
interface
procedure VerE r r o r (C adena : string)
implementation
uses Vis ual i z ;
procedure Ver Err or (Cade n a : str i ng)
begin
Esc ri b i rEnPosicionXY ( 1, 25 , cadena)
end;
end.
""
.y
' .,~
,"
L
la otra
1 ..
-.c_ .< __ ,.
', :'. .- - .. ..
, >"". . . , .. c
"! " ,
, ,
2.4. UTILlZACION DE UNIDAD ESTANDAR
El archivo T URBO. T PL, que contiene todas las unidades estndar, se carga en memoria
central a la vez que el propio compilador y est disponible en cualquier momento, con
la ayuda de la clusula uses.
Un programa debe contener la clusula uses , situada inmediatamente despus de la
cabecera, cuando utiliza objetos declarados en una unidad.
66 Estructura de datos
program Test ;
uses
Crt, Pro ceso;
const
Mayor = 1 00 ;
type
Pal abra - string [ 2] ;
var
Ex presion : rea l;
En este captulo se har una breve introduccin a las diferentes unidades. Todas las
unidades contienen una serie de objetos que estn declarados en la seccin de interface
(constantes, variables, tipos, procedimientos y funciones) y que son exportables o visua-
lizables desde cualquier programa o unidad que utilice dichas unidades.
2.4.2. Unidad Crt
Esta unidad proporciona un conjunto especfico de declaraciones para entrada y salida:
constantes, variables, procedimientos y funciones, que permiten el acceso al control de
los modos de pantalla, al teclado, a los colores, al posicionamiento del cursor, etc.
La mayora de los programas Turbo Borland Pascal que hacen uso de la pantalla para
representaciones de salida recurren a la unidad Crt. Algunos procedimientos tpicos son:
ClrS c r Borra la pantalla.
KeyPressed Detecta la pulsacin de una tecla.
Sou n d Hace sonar el altavoz interno.
wi ndow Define una ventana de texto en la pantalla.
EJEMPLO 2.4
El siguiente programa permite comprobar la velocidad de presentacin de los caracte-
res en la pantalla, creando una ventana de JO. 000 caracteres aleatorios que se repiten
tres veces.
I
, ;
Construccin de grandes programas: mdulos versus unidades 69
Algunos mtodos para indicar al sistema TURBO en qu directorio estn las unida-
des son:
B: \ Pruebas
El sistema ya est preparado para buscar en ese directorio las unidades que
haya escrito. Cuando se encuentra una clusula uses, el sistema busca la unidad
en TURBO. TPL, si no la encuentra, busca en el directorio activo de la unidad de
disco activa. Si no se encuentra en ninguna de esas posiciones, entonces busca en
el directorio que se referenci como Uni t Directories, es decir, en el ejemplo
Pruebas, en la unidad B. En caso negativo el sistema produce un error.
Se pueden utilizar directorios mltiples. En este caso se pueden listar todos los
directorios separados por puntos y comas:
Reglas de funcionamiento
, " < - ,-, .~ - :,-,,_ ,::_,_-~--"-, , :~ " , : ;- ' - .. '----:----. ::-.,-.--,:" _; '_ -- ;-.-.-----, , ~"- ' - . - -'- '-- .~ , ": , '- ,-'l-
- . "'", """ _
, - V. ' ->_-:- .-,>
y ,
., .
"
---------------------------------------------------------------------------------------
El programa TPUMOVER
Las unidades estndar residen en la biblioteca TURBO. TPL Y se cargan automtica-
mente cuando arranca Turbo Borland Pascal. Al objeto de ahorrar memoria se pueden
transferir unidades poco utilizadas, tales como Turbo3 y Graph, fuera del archivo
TURBO. TPL, mediante la utilidad TPUMOVER. En otras palabras, esta utilidad se pue-
de utilizar para aadir o borrar desde TURBO. TPL.
end.
, , "
" ._"
-,
-._~-
., - .
--,<----~-----
,',' -' - - , > ,
,
;:.
interface
uses <li s t a de u ni dades > {op cional}
{dec l a r aciones pb l icas o visibles son opc i o n a l es}
cons t .... .
type ..... .
var ..... .
implementation
{dec l a r acio n es priva d as : l ocales a l a u n i d a d }
uses <li s t a de unida des >
const ... .
type .... .
var .....
J
,
,
,J
I
I
Construccin de grandes programas: mdulos versus unidades 73
endo {obligatoria , fin de i mp l emen t aci n }
Modelo 1 ,,
,
unit Base ;
,,
interface :
,
uses
Crt ;
procedure Mens aje (Texto : string);
implementation
procedure Mensaj e ;
begin
ClrScr ;
GotoXY ((80 - Leng t h (Texto)) div 2 , 4 ) ;
Wr i te (T ext o )
end;
begin
o o o
endo
Modelo 2
unit Base ;
interface
uses
Crt ;
procedure Me n saje (Te xt o : string );
implementation
procedure Me n saje (T ext o: string ) ;;
begin
Cl rScr ;
GotoXY ((80 - Length (Texto)) div 2 , 4) ;
Write (T ext o)
end;
begin
. . ...
endo
Adems de las unidades, existen dos mtodos para estructurar o construir grandes pro-
gramas a partir de Turbo Borland Pascal 5.0: los archivos de inclusin (inelude) y los
solapamientos (overlays). Aunque es necesario hacer constar que si bien en las versio-
nes 3.0 y anteriores eran imprescindibles, su utilidad ha decado en 5.0, 6.0 Y 7.0 en
beneficio de las unidades.
l,
Construccin de grandes programas: mdulos versus unidades 75
76 Estructura de datos
Las. directivas
Construccin de grandes programas: mdulos versus unidades 77
program Mortim e r;
{$ F + }
uses overlay, Dos , Crt, Circu l os , Xmodem, Kermit, Parse r;
( SO Xmodem)
{SO Kermit}
{SO Parse r }
cima
Stack
Memoria EMS Almacenamiento
(si existe) en disco (DOS)
Memoria principal
(DOS)
Ejemplo
begin
Ov rI n i t i ' MIP ROG . OVR' )
end;
o.. _
78 Estructura de datos
OvrClearBuf
Este procedimiento permite borrar temporalmente la memoria intellnedia de solapamiento;
esta operacin se debe realizar cuando se necesite utilizar la memoria que ocupa.
OvrClearBuf
OvrGetBuf
Devuelve el tamao actual de la memoria inte/media de solapamiento, en VarLonglnt.
VarLonglnt:= OvrGetBuf
Ovrlnit
Inicializa el gestionador de solapamientos y abre el archivo de solapamiento.
Ovrlnit (nombrearchivo)
OvrlnitEMS
Verifica que existe un controlador EMS y suficiente memoria EMS para contener el
archivo de solapamiento.
OvrlnitEMS
Construccin de grandes programas: mdulos versus unidades 79
OvrSetBuf
Establece el tamao de la memoria intermedia de solapamiento (o ver/ay buffer).
OvrSetBuf (VarLonglnt)
RESUMEN
Una unidad es una coleccin de procedimientos y funciones de propsito general, guardadas en
disco de forma compilada. Las unidades se pueden utilizar para construir su propia librera de
procedimientos y funciones predefinidas. Esta librera puede ser utilizada en diferentes proyectos
y por diferentes equipos de programadores.
Las unidades refuerzan el concepto de abstraccin de datos. Esto se consigue situando los deta-
lles sobre procedimientos implementados en una unidad, y por consiguiente ocultando estos detalles.
unit <nombre>
interface
uses <lista de u nidades utilizadas por esta unidad >
{s e omite si no se uti liza ninguna unidad}
<cabeceras de procedimientos y f u n c i o nes >
<o tras declaraciones >
implementation
<declaraciones compl etas de pro ced imientos y fun cio nes >
begin {no se necesita si n o existen se ntencias de i nicializ ac i n}
end.
EJERCICIOS
2.1. Disear una unidad Lib 1 que defina las tres funciones siguientes, que puedan ser utilizadas
posteriormente por cualquier programa:
80 Estructura de datos
n
Desviacin media (DM = ~L
i 1
=
x-x I
donde x =
I es el valor absoluto
n
Media cuadrtica (MC) = #. L xl
1= 1
2.3. Escribir una unidad llamada Grados que incluya funciones para convertir grados sexagesi-
males y centesimales a radianes. Disear un programa que permita calcular los valores de
las funciones trigonomtricas seno, coseno y tangente de una tabla de valores angulares
dados en grados sexagesimales y centesimales (incremento del ngulo en la tabla, 1 grado).
2.4. Dadas dos matrices, A y B, donde
all a 12 al n b ll b 12 b lm
a 21 a22 a2n b21 b22 b 2m
A= y B=
Disear una unidad que contenga los procedimientos o funciones: producto y suma de
A y B.
2.5. Disear una unidad que soporte las siguientes dos funciones de tiempo:
Nota
o. , ,
' .
.' '
Y
, .
, --.-
2.6. Escribir una unidad que manipule tipos de datos abstractos Enteros grandes (enteros de al
menos 2 dgitos). Debe proporcionar nmeros positivos y negativos, y las operaciones de
suma, resta, multiplicacin y divisin.
2.7. Escribir una unidad cuyos subprogramas bsicos deben ser:
Operacin traspuesta de una matriz.
Multiplicaciones de dos matrices cuadradas.
Suma de dos matrices cuadradas.
2.8. Crear una unidad que se componga de procedimientos y funciones que realicen las tareas
siguientes:
Hacer el cursor visible o invisible.
Emitir un sonido (pitido bip).
Borrar la parte de pantalla situada entre dos lneas.
Convertir las letras de una cadena de caracteres en maysculas.
Convertir un valor numrico en una cadena de caracteres.
Insertar caracteres.
2.9. Escribir una unidad que contenga los procedimientos de cambios de base de numeracin:
paso de base 2 a base 16, base 2 a base 1O Y base 10 a base 2.
2.10. Escribir una unidad que contenga procedimientos y funciones que efecten las tareas si-
guientes:
2. 11. Escribir la unidad Prueba que contenga dos funciones para asegurar divisiones correc-
tas y evitar la divisin por cero, que produce un error irrecuperable en la ejecucin del
programa. Aplicacin prctica: Escribir un programa Demo Prueba que utilice las fun-
ciones creadas en la unidad Prueba.
2.12. Crear una unidad Aleatori que contenga tres funciones que proporcionen valores ge-
nerados aleatoriamente de tres tipos diferentes: enteros, cadenas y lgicos. Las funciones
a definir se denominan EnterasA, cadenasA. LagicasA.
82 Estructura de datos
2. 13. Escribir un programa que visualice seis lneas que contengan cada una de ellas un entero
entre 300 y 400, una cadena de ocho letras y un valor true o false, todos ellos aleatorios.
325 MNRPQANT true
346 LOIVRSTN false
37l MSPBVTRL true
382 NZJMKSBC false
343 FGRILTRP true
Nota: Utilice la unidad Aleatori.
2.14. El programa siguiente lee un archivo de entrada (programa fuente en Pascal) y lo convier-
te en otro archivo de salida (programa fuente en Pascal) con las palabras reservadas de
Turbo Borland Pascal en negritas y maysculas.
,
REFERENCIAS BIBLlOGRAFICAS
1. Borland: Reference Guide. Turbo Borland Pascal 5.0. Captulo 13.
Si desea trabajar con solapamientos, este captulo le complementar las ideas expuestas en la
seccin 2.8.
2. Dunteman, Jeff: Complete Turbo Borland Pascal. Third Edition. Scott Foreman, 1989.
Es una excelente obra para profundizar en Turbo Borland Pascal. Recomendada para usuarios
expertos y como ampliacin de conocimientos tras la lectura de esta obra.
,
CAPITULO
.,
stracclon e atos: ti os a stractos
atos o etos
., '.
CONTENIDO
83
84 Estructura de datos
3.1. EL PAPEL (EL ROL) DE LA ABSTRACCION
Los programadores han tenido que luchar con el problema de la complejidad durante
mucho tiempo desde el nacimiento de la informtica. Para comprender lo mejor posible
la importancia de las tcnicas orientadas a objetos, revisemos cules han sido los dife-
rentes mecanismos utilizados por los programadores para controlar la complejidad. En-
tre todos ellos se destaca la abstraccin. Como describe Wulft: Los humanos hemos
desarrollado una tcnica excepcionalmente potente para tratar la complejidad: abstraer-
nos de ella. Incapaces de dominar en su totalidad los objetos complejos, se ignora los
detalles no esenciales, tratando en su lugar con el modelo ideal del objeto y centrndo-
nos en el estudio de sus aspectos esenciales.
En esencia, la abstraccin es la capacidad para encapsular y aislar la informacin,
del diseo y ejecucin. En otro sentido, las tcnicas orientadas a objetos se ven como
resultado de una larga progresin histrica que comienza en los procedimientos y sigue
en los mdulos, tipos abstractos de datos y objetos.
Abstraccin de datos: tipos abstractos de datos y objetos 85
3.1.3. Procedimientos
Los procedimientos y funciones fueron uno de los primeros mecanismos de abstrac-
cin que se utilizaron ampliamente en lenguajes de programacin. Los procedimientos
permitan tareas que se ejecutaban rpidamente, o eran ejecutados slo con ligeras varia-
ciones, que se reunan en una entidad y se reutilizaban, en lugar de duplicar el cdigo
varias veces. Por otra parte, el procedimiento proporcion la primera posibilidad de ocul-
tacin de informacin. Un programador poda escribir un procedimiento o conjunto de
procedimientos, que se utilizaban por otros programadores. Estos otros programa-
dores no necesitaban conocer con exactitud los detalles de la implementacin, slo ne-
cesitaban el interfaz necesario. Sin embargo, los procedimientos no resolvan todos los
problemas. En particular, no era un mecanismo efectivo para ocultar la informacin y
para resolver el problema que se produca al trabajar mltiples programadores con nom-
bres idnticos.
Para ilustrar el problema, consideremos un programador que debe escribir un con-
junto de rutinas para implementar una pila. Siguiendo los criterios clsicos de diseo de
software, nuestro programador establece en primer lugar el interfaz visible a su trabajo,
es decir, cuatro rutinas: meter, sacar, pilavaca y pilallena. A continuacin implementa
los datos rutinas mediante arrays, listas enlazadas, etc. Naturalmente los datos conteni-
dos en la pila no se pueden hacer locales a cualquiera de las cuatro rutinas, ya que se
deben compartir por todos. Sin embargo, si las nicas elecciones posibles son variables
locales o globales, entonces la pila se debe mantener en variables globales; por el con-
trario, al ser las variables globales, no ,existe un mtodo para limitar la accesibilidad o
visibilidad de dichas variables. Por ejemplo, si la pila se representa en un array denomi-
nado datospila, este dato debe ser conocido por otros programadores, que puedan desear
crear variables utilizando el mismo nombre pero relativo a las referidas rutinas. De modo
similar las rutinas citadas estn reservadas y no se pueden utilizar en otras partes del
programa para otros propsitos. En Pascal existe el mbito local y global. Cualquier
mbito que permite acceso a los cuatro procedimientos debe permitir tambin el acceso
a sus datos comunes. Para resolver este problema, se ha desarrollado un mecanismo de
estructuracin diferente.
3.1.4. Mdulos
Un mdulo es una tcnica que proporciona la posibilidad de dividir sus datos y procedi-
mientos en una parte privada slo accesible dentro del mdulo y parte pblica
Abstraccin de datos: tipos abstractos de datos y objetos 87
-accesible fuera del mdulo . Los tipos, datos (variables) y procedimientos se pueden
definir en cualquier parte.
El criterio a seguir en la construccin de un mdulo es que si no se necesita algn
tipo de informacin, no se debe tener acceso a ella. Este criterio es la ocultacin de
informacin.
Los mdulos resuelven algunos problemas, pero no todos los problemas del desarro-
llo de software. Por ejemplo, los mdulos petmitirn a nuestros programadores ocultar
los detalles de la implementacin de su pila, pero qu sucede si otros usuarios desean
tener dos o ms pilas? Supongamos que un programador ha desarrollado un tipo de dato
e omp 1 e j o (representacin de un nmero complejo) y ha definido las operaciones arit-
mticas sobre nmeros 'complejos suma, resta, multiplicacin y divisin ; asimismo
ha definido rutinas para convertir nmeros convencionales a complejos. Se presenta un
problema: slo puede manipular un nmero complejo. El sistema de nmeros complejos
no ser til con esta restriccin, pero es la situacin en que se encuentra el programador
con mdulos simples.
Los mdulos proporcionan un mtodo efectivo de ocultacin de la informacin, pero
no permiten realizar instanciacin, que es la capacidad de hacer mltiples copias de las
zonas de datos.
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ __ ~.~
_ _ o ..... " _ _ _ _
88 Estructura de datos
3.1.6. Objetos
Un objeto es sencillamente un tipo abstracto de datos al que se aaden importan-
tes innovaciones en comparticin de cdigo y reutilizacin. Los mecanismos bsicos de
orientacin a objetos son: objetos, mensajes y mtodos, clases e instancias y herencia.
Una idea fundamental es la comunicacin de los objetos a travs de paso de mensa-
jes. Adems de esta idea, se aaden los mecanismos de herencia y polimorfismo. La
herencia permite diferentes tipos de datos para compartir el mismo cdigo, permitiendo
una reduccin en el tamao del cdigo y un incremento en la funcionalidad. El polimor-
fismo permite que un mismo mensaje pueda actuar sobre objetos diferentes y comportar-
se de modo distinto.
La persistencia se refiere a la permanencia de un objeto, esto es, la cantidad de tiem-
po para el cual se asigna espacio y permanece accesible en la memoria del compu-
tador.
Conceptos
clave
Entidades bsicas
Mensajes Herencia
Objeto
Mtodos Jerarqua
No existe ningn estilo de programacin idneo para todas las clases de pro-
gramacin. La orientacin a objetos se acopla a la simulacin de situaciones del mun-
do real.
En POO, las entidades centrales son los objetos, que son tipos de datos que encapsu-
lan con el mismo nombre estructuras de datos y las operaciones o algoritmos que mani-
pulan esos datos.
3.3. MODULARIDAD
2 Un ejemplo que sirve como modelo o patrn: Dictionary of Science and Techn%gy, Academic
Press, 1992.
3 Kuhn, Thomas S.: The Structure of Scientific Revo/ution, 2." ed.~ University of Chicago Press, Chi-
cago, 1970.
90 Estructura de datos
Un conjunto de datos. .
Un conjunto de operaciones que actan sobre los datos.
Atributos Algoritmos
Seccin
privada
Representacin Parmetros actuales
Unidades modulares
El lenguaje debe proporcionar estructuras modulares con las cuales se puedan des-
cribir las diferentes unidades. De este modo, el lenguaje (y el compilador) puede reco-
nocer un mdulo y debe ser capaz de manipular y gobernar su uso, adems de las ven-
tajas evidentes relativas a la legibilidad del cdigo resultante. Estas construcciones
modulares pueden, como en el caso de los lenguajes orientados a objetos, mostrar carac-
tersticas que facilitan la estructura del programa, as como la escritura de programas.
En otras palabras, nos referimos a las unidades modulares lingsticas que en el caso de
C++ se conocen como clases y en Turbo Borland Pascal, los mdulos se denominan
unidades. La sintaxis de las unidades diferencia entre el interfaz y la implementacin
del mdulo. Las dependencias entre unidades se pueden declarar slo en un interfaz del
mdulo. Ada va ms lejos y define el paquete en dos partes: la especificacin del paque-
te y el cuerpo del paquete. Al contrario que Object Pascal, Ada permite que la conexin
entre mdulos se declaren independientemente en la especificacin y en el cuerpo de un
paquete.
92 Estructura de datos
Interfaces adecuados
En la estructuracin de un programa en unidades es beneficioso que existan pocos inter-
faces y que estos sean pequeos. Es conveniente que existan pocos enlaces entre los
diferentes mdulos en que se descompone un programa. El interfaz de un mdulo es la
parte del mdulo (datos, procedimientos, etc.) que es visible fuera del mdulo.
Los interfaces deben ser tambin pequeos (esto es, su tamao debe ser pequeo con
respecto al tamao de los mdulos implicados). De este modo, los mdulos estn aco-
plados dbilmente; se enlazarn por un nmero pequeo de llamadas (Figura 3.3).
Pocos Muchos
interfaces interfaces
Parte
Interfaces visible
grandes
Parte
visible
Interfaces
pequeos
Interfaces explcitos
La interfaz o parte visible externamente de un mdulo se debe declarar y describir expl-
citamente; el programa debe especificar cules son los datos y procedimientos que un
mdulo trata de exportar y cules deben permanecer ocultos del exterior. La interfaz
debe ser fcilmente legible, tanto para el programador como para el compilador. Es de-
cir, el programador debe comprender cmo funciona el programa y el compilador ha de
poder comprobar si el cdigo que accede al mdulo se ha escrito correctamente.
Ocultacin de la informacin
Todos los mdulos deben seguir el principio de ocultacin de la informacin; cada m-
dulo debe representarse al menos un elemento de diseo (por ejemplo, la estructura de
un registro, un algoritmo, una abstraccin, etc.).
Otro criterio a tener en cuenta es la subdivisin de un sistema en mdulos, es el
principio denominado abierto-cerrado 4, formulado por Meyer. Este principio entiende
que cada mdulo se considerar cerrado (esto es, terminado y, por consiguiente, til o
activo desde dentro de otros mdulos) y, al mismo tiempo, debe ser abierto (esto es,
sometido a cambios y modificaciones). El principio abierto-cerrado debe producirse
sin tener que reescribir todos los mdulos que ya utilizan el mdulo que se est modifi-
cando.
, ',' , " "
. ~., 1, -",;,<: '
----.,-_. - " o _-c
. :,
- __'-_._
-._. . - -'-:'-,:',,'" :.,.
grafia de Miguel Katrib. Algunos ttulos destacados sobre orientacin a objetos son: Programacin Orien-
tada a Objetos a travs de C++ y Eiffel. V Escuela Internacional en Temas Selectos de Computacin.
Zacatecas, Mxico, 1994 (esta Escuela est organizada por la UN AM. Mxico); Programacin Orientada a
Objetos en C++. Infosys, Mxico, 1994; Collections and Iterators in Eiffel, Joop, vol. 6, nm. 7, noviem-
bre-diciembre 1993.
94 Estructura de datos
3.4.
- .
DISENO DE MODULOS
l. La sustitucin de un mdulo por otro, de modo que slo unos pocos mdulos
sern afectados por el cambio.
2. El seguimiento de un error y el aislamiento del mdulo defectuoso que produce
ese error.
Existen varias clases de. acoplamiento entre dos mdulos (Tabla 3.1). Examina-
remos los cinco tipos de acoplamiento, desde el menos deseable (esto es, acoplamiento
estrecho o impermeable) al ms deseable (esto es, acoplamiento ms dbil). La fuerza
de acoplamiento entre dos mdulos est influenciada por el tipo de conexin, el tipo de
comunicacin entre ellos y la complejidad global de su interfaz .
5 Booch, Grady: Object-Oriented Design with applications, Benjamin Cummings, 1991, pg. 52.
Abstraccin de datos: tipos abstractos de datos y objetos 95
l'ipC)$ de cohesin.
..... :::: ":.: ,. :.;".:<::.::: .... :.. ::. ... ". ."... . .":.: ..... :.::. :. :...
.: .. .
.. Gra"
. dec:o'hesin '
Todos los lenguajes de programacin soportan algn tipo de dato. Por ejemplo, el len-
guaje de programacin convencional Pascal soporta tipos base tales como enteros, rea-
les y caracteres, as como tipos compuestos tales como arrays (vectores y matrices) y
registros. Los tipos abstractos de datos extienden la funcin de un tipo de datos; ocul-
tan la implementacin de las operaciones definidas por el usuario asociadas con el
tipo de datos. Esta capacidad de ocultar la infonnacin permite el desarrollo de compo-
nentesde software reutilizables y extensibles.
Los lenguajes de programacin son las herramientas mediante las cuales los diseadores
de lenguajes pueden implementar los modelos abstractos. La abstraccin ofrecida por
los lenguajes de programacin se puede dividir en dos categoras: abstraccin de datos
(perteneciente a los datos) y abstraccin de control (perteneciente a las estructuras de
control).
Desde comienzos del decenio de los sesenta, en que se desarrollaron los prime-
ros lenguajes de programacin de alto nivel, ha sido posible utilizar las abstracciones
ms primitivas de ambas categoras (variables, tipos de datos, procedimientos, control
de bucles, etc.). Ambas categoras de abstracciones han producido una gran cantidad de
lenguajes de programacin no siempre bien definidos.
Los microprocesadores ofrecen directamente slo dos mecanismos para controlar el flu-
jo y ejecucin de las instrucciones: secuencia y salto. Los primeros lenguajes de progra-
macin de alto nivel introdujeron las estructuras de control: sentencias de bifurcacin
( i f) y bucles (for, while, do-l oop, etc.).
Las estructuras de control describen el orden en que se ejecutan las sentencias o
grupos de sentencia (unidades de programa). Las unidades de programa se utilizan como
bloques bsicos de la clsica descomposicin descendente. En todos los casos, los
subprogramas constituyen una herramienta potente de abstraccin ya que durante su
implementacin, el programador describe en detalle cmo funcionan los subprogramas.
Cuando el subprograma se llama, basta con conocer lo que hace y no cmo 10 hace. De
este modo, los subprogramas se convierten en cajas negras que amplan el lenguaje de
programacin a utilizar. En general, los subprogramas son los mecanismos ms amplia-
mente utilizados para reutilizar cdigo, a travs de colecciones de subprogramas en bi-
bliotecas.
lar a la utilizacin de un tipo de dato, cuyo uso se realiza sin tener en cuenta cmo est
representado o implementado.
Los tipos de datos son abstracciones y el proceso de construir nuevos tipos se llaman
abstracciones de datos. Los nuevos tipos de datos definidos por el usuario se llaman
tipos abstractos de datos.
El concepto de tipo, tal como se defini en Pascal y ALGOL 68, ha constituido un
hito importante hacia la realizacin de un lenguaje capaz de soportar programacin es-
tructurada. Sin embargo, estos lenguajes no soportan totalmente una metodologa. La
abstraccin de datos til para este propsito, no slo clasifica objetos de acuerdo a su
estructura de representacin; sino que se clasifican de acuerdo al comportamiento espe-
rado. Tal comportamiento es expresable en trminos de operaciones que son significati-
vas sobre esos datos, y las operaciones son el nico medio para crear, modificar y acce-
der a los objetos.
En trminos ms precisos, Ghezzi indica que un tipo de dato definible por el usuario
se denomina tipo abstracto de dato (TAD) si:
Las clases en SIMULA slo cumplan la primera de las dos condiciones, mientras
que otros lenguajes actuales cumplen las dos condiciones: Ada, Modula-2 y C++.
Los tipos abstractos de datos proporcionan un mecanismo adicional mediante el cual
se realiza una separacin clara entre la interfaz y la implementacin del tipo de dato. La
implementacin de un tipo abstracto de dato consta de:
La interfaz del tipo abstracto de dato se asocia con las operaciones y datos visibles al
exterior del TAD.
datos (estructuras de datos propias) y operaciones que se pueden realizar sobre esos
datos. Un TAD se compone de estructuras de datos y los procedimientos o funciones
que manipulan esas estructuras de datos.
Mtodo 1 Mtodo 1
Mtodo 3 Mtodo 3
...
Interfaz pblico
Representacin:
estructura de datos
(variables de instancia)
Implementacin de mtodos:
Implementacin privada
l. Permite una mejor conceptualizacin y modelado del mundo real. Mejora la re-
presentacin y la comprensibilidad. Clarifica los objetos basados en estructuras
y comportamientos comunes.
2. Mejora la robustez del sistema. Si hay caractersticas subyacentes en los lengua-
jes permiten la especificacin del tipo de cada variable, los tipos abstractos
de datos permiten la comprobacin de tipos para evitar errores de tipo en tiem-
po de ejecucin.
3. Mejora el rendimiento (prestaciones). Para sistemas tipeados, el conocimiento
de los objetos permite la optimizacin de tiempo de compilacin.
4. Separa la implementacin de la especificacin. Permite la modificacin y mejo-
ra de la implementacin sin afectar al interfaz pblico del tipo abstracto de dato.
5. Permite la extensibilidad del sistema. Los componentes de software reutiliza-
bles son ms fciles de crear y mantener.
6. Recoge mejor la semntica del tipo. Los tipos abstractos de datos agrupan o
localizan las operaciones y la representacin de atributos.
En estos lenguajes se definen la especificacin del TAD, que declara las operaciones
y los datos ocultos al exterior, y la implementacin, que muestra el cdigo fuente de las
operaciones y que permanece oculto al exterior del mdulo.
Las ventajas de los TAD se pueden manifestar en toda su potencia, debido a que las
dos partes de los mdulos (especificacin e implementacin) se pueden compilar por
separado mediante la tcnica de compilacin separada (<<separate compilation).
102 Estructura de datos
Pila
Estructura de datos
Almacena una serie de elementos del tipo elemento. La pila est inicialmente vaca y los elementos
se meten o sacan en la pila por el mismo extremo.
Operaciones (Procedimientos que actan sobre la estructura de datos).
Meter
Sacar
Crear
Destruir
Pilavacia Sacar Meter
Cim a
- , -
Fondo vi C\. CA ,.
La implementacin de una pila con capacidad para 1.000 elementos del tipo en-
tero es:
unit Pila;
interface .
const
MaxPila = 1000;
type
TipoElemento = int eger;
ListaElementos = array (l .. MaxPilal of TipoElemento;
tipo = record
Elems : ListaElementos; ,
Cima: integer;
end;
implementation
S.Cima := S.Cima + 1;
S .Elems(S.Cimal := Item;
end;
.
procedure Sacar (var S:tipo; var Item:TipoElemento);
begin
Item := S.Elems(S.Cimal;
S.Cima := S.Cima-l
end;
104 Estructura de datos
Una vez que se ha implementado el tipo de dato p i 1 a , ste puede ser utilizado en
cualquier programa con tal de invocar en la clusula uses a dicho tipo de dato P il a .
100
4567
- 20
25 0
250
-20
4567
10 0
program Numer o s ;
uses
Pi l a ;
var
S : Pila .Ti po ;
begin
Pi l a . Sacar( Nu mP i l a . Au x ) ;
Wr i te Ln( Aux ) ;
end; ( * whi le *)
end; ( * Ve rN umer os * )
poda haber realizado con estructuras dinmicas tales como listas enlazadas. De igual
modo se pueden implementar otros tipos de datos abstractos tales como, por ejemplo, las
colas que se utilizan en muchas aplicaciones: sistemas operativos, sistemas de comuni-
caciones, etc.
Problema del
mundo real
Programa
Abstraccin.
Encapsulacin.
Modularidad .
Jerarqua.
Como sugiere Booch, si alguno de estos elementos no existe, se dice que el modelo
no es orientado a objetos.
3.9.1. Abstraccin
La abstraccin es uno de los medios ms importante mediante el cual nos enfrentamos
con la complejidad inherente al software. La abstraccin es la propiedad que permite
representar las caractersticas esenciales de un objeto, sin preocuparse de las restantes
caractersticas (no esenciales).
Una abstraccin se centra en la vista externa de un objeto, de modo que sirva para
separar el comportamiento esencial de un objeto, de su implementacin. Definir una
abstraccin significa describir una entidad del mundo real, no importa lo compleja que
pueda ser, y a continuacin utilizar esta descripcin en un programa.
El elemento clave de la programacin orientada a objetos es la clase. Una clase se
puede definir como una descripcin abstracta de un grupo de objetos, cada uno de los
cuales se diferencia por su estado especfico y por la posibilidad de realizar una serie de
operaciones. Por ejemplo, una pluma estilogrfica es un objeto que tiene un estado (lle-
na de tinta o vaca) y sobre la cual se pueden realizar algunas operaciones (por ejemplo,
escribir, poner/quitar el capuchn, llenar de tinta si est vaca).
La idea de escribir programas definiendo una serie de abstracciones no es nueva,
pero el uso de clases para gestionar dichas abstracciones en lenguajes de programacin
ha facilitado considerablemente su aplicacin.
3.9.2. Encapsulacin
.
La encapsulacin o encapsulamiento es la propiedad que permite asegurar que el conte-
nido de la informacin de un objeto est oculta al mundo exterior: el objeto A no conoce
lo que hace el objeto B, y viceversa. La encapsulacin (tambin se conoce como oculta-
cin de la informacin), en esencia, es el proceso de ocultar todos los secretos de un
objeto que no contribuyen a sus caractersticas esenciales.
La encapsulacin permite la divisin de un programa en mdulos. Estos mdulos se
implementan mediante clases, de forma que una clase representa la encapsulacin de
una abstraccin. En la prctica, esto significa que cada clase debe tener dos partes: un
interfaz y una implementacin. La interfaz de una clase captura slo su vista externa y la
implementacin contiene la representacin de la abstraccin, as como los mecanismos
que realizan el comportamiento deseado.
3.9.3. Modularidad
La modularidad es la propiedad que permite subdividir una aplicacin en partes ms
pequeas (llamadas mdulos), cada una las cuales debe ser tan independiente como sea
posible de la aplicacin en s y de las restantes partes.
La modularizacin, como
indica Liskov, consiste en dividir un programa
en mdulos
que se pueden compilar por separado, pero que tienen conexiones con otros mdulos. Al
igual que la encapsulacin, los lenguajes soportan la modularidad de diversas formas.
Por ejemplo, en C++ los mdulos son archivos compilados por separado. La prctica
usual es situar las interfaces de los mdulos en archivos con nombres con extensin .h
108 Estructura de datos
3.9.4. Jerarqua
La jerarqua es una propiedad que permite una ordenacin de las abstracciones. Las dos
jerarquas ms importantes de un sistema complejo son: estructura de clases [jerarqua
es-un (is-a): generalizacin/especializacin] y estructura de objetos [jerarqua par-
te-de (part-o.!): agregacin].
,
No.sedebe
,-'.- ' .. ,' -- "" .c..
. . azul.no .
atrlbut6df .. . .
_.
... ,----
,-- -
3.9.5. Polimorfismo
La quinta propiedad significativa de los lenguajes de programacin orientados a objetos
es el polimorfismo. Esta propiedad no suele ser considerada como fundamental en los
diferentes modelos de objetos propuestos, pero dada su importancia, no tiene sentido
considerar un objeto modelo que no soporte esta propiedad.
Polimorfismo es la propiedad, que indica, literalmente, la posibilidad de que una
entidad tome muchas formas. En trminos prcticos, el polimorfismo permite referirse
a objetos de clases diferentes mediante el mismo elemento de programa y realizar
la misma operacin de diferentes formas, segn sea el objeto que se referencia en ese
momento.
Por ejemplo, cuando se qescribe la clase mamferos, se puede observar que la opera-
cin comer es una operacin fundamental en la vida de los mamferos, de modo que
cada tipo de mamfero debe poder realizar la operacin o funcin comer. Por otra parte,
una vaca o una cabra que pastan en un campo, un nio que se come un bombn o cara-
Abstraccin de datos: tipos abstractos de datos y objetos 109
me lo y un len que devora a otro animal, son diferentes formas que utilizan los distintos
mamferos, para realizar la misma funcin (comer).
El polimorfismo implica la posibilidad de tomar un objeto de un tipo (mamfero, por
ejemplo) e indicarle que ejecute comer; esta accin se ejecutar de diferente forma se-
gn sea el objeto mamfero sobre el que se aplica.
Clases, herencia y polimorfismo son aspectos claves en la programacin orientada a
objetos y se reconocen a estos elementos como esenciales en la orientacin a objetos. El
polimorfismo adquiere su mxima expresin en la derivacin o extensin de clases; es
decir, cuando se obtiene una clase a partir de una clase ya existente, mediante la propie-
dad de derivacin de clases o herencia. As, por ejemplo, si se dispone de una figura que
represente figuras genricas, se puede enviar cualquier mensaje tanto a un tipo derivado
(elipse, crculo, cuadrado, etc.) como al tipo base. Por ejemplo, una clase figura , pueden
aceptar los mensajes dibujar, borrar y mover. Cualquier tipo derivado de una figura es
un tipo de figura y puede recibir el mismo mensaje. Cuando se enva un mensaje, por
ejemplo dibujar, esta tarea ser distinta segn que la clase sea un tringulo, un cuadrado
o una elipse. Esta propiedad es el polimorfismo, que permite que una misma funcin se
comporte de diferente forma segn sea la clase sobre la que se aplica. La funcin dibujar
se aplica igualmente a un crculo, un cuadrado o un tringulo y el objeto ejecutar el
cdigo apropiado dependiendo del tipo especfico.
El polimorfismo requiere ligadura tarda o postergada (tambin llamada dinmica),
y esto slo se puede producir en lenguajes de programacin orientados a objetos. Los
lenguajes no orientados a objetos soportan ligadura temprana o anterior; esto significa
que el compilador genera una llamada a un nombre especfico de funcin y el enlazador
(linker) resuelve la llamada a la direccin absoluta del cdigo que se ha de ejecutar. En
POO, el programa no puede determinar la direccin del cdigo hasta el momento de la
ejecucin; para resolver este concepto, los lenguajes orientados a objetos utilizan el con-
cepto de ligadura tarda. Cuando se enva un mensaje a un objeto, el cdigo que se
llama no se determina hasta el momento de la ejecucin. El compilador asegura que la
funcin existe y realiza verificacin de tipos de los argumentos y del valor de retomo,
pero no conoce el cdigo exacto a ejecutar.
Para realizar la ligadura tarda, el compilador inserta un segmento especial de cdigo
en lugar de la llamada absoluta. Este cdigo calcula la direccin del cuerpo de la funcin
para ejecutar en tiempo de ejecucin utilizando informacin almacenada en el propio
objeto. Por consiguiente, cada objeto se puede comportar de modo diferente de acuerdo
al contenido de ese puntero. Cuando se enva un mensaje a un objeto, ste realmente
sabe qu ha de hacer con ese mensaje.
Concurrencia (multitarea).
Persistencia.
110 Estructura de datos
Genericidad.
Manejo de excepciones.
Muchos lenguajes soportan todas estas propiedades y otros slo algunas de ellas.
As, por ejemplo, Ada soporta concurrencia y Ada y C++ soportan genericidad y manejo
de excepciones. La persistencia o propiedad de que las variables y por extensin, a los
objetos existan entre las invocaciones de un programa, es posiblemente la propiedad
menos implantada en los LPOO, aunque ya es posible considerar la persistencia en len-
guaje tales como Smalltalk y C+, lo que facilitar el advenimiento de las bases de datos
orientadas a objetos como as est sucediendo en esta segunda mitad de la dcada de los
noventa.
Abstraccin de datos: tipos abstractos de datos y objetos 111
I
Ada ha sido, tambin, un lenguaje en este caso basado en objetos que soporta la
mayora de las propiedades orientadas a objetos. Sin embargo, la nueva versin Ada-95
ya soporta herencia y polimorfismo.
Algol
Simula
~ 4
Object Pascal
. Java
Delphi
En los ltimos aos han aparecido lenguajes con soporte de objetos que cada vez se
estn popularizando ms: Clipper 5.2 (ya en claro desuso), Visual BASIC, etc.
De cualquier forma, existe un rE)' actual en los lenguajes orientados a objetos: C++.
La normalizacin por ANSI y AT &T de la versin 3.0 y las numerosas versiones de
diferentes fabricantes, tales como Borland C++ 4.0/4.5/5, Turbo C++ 3.0/3.1 y 4.5, Vi-
sual C++ 4.114.2/5, Symantec 6.0/7.0, etc., hacen que en la segunda mitad de los noven-
ta, c++ ser el lenguaje orientado a objetos ms popular y utilizado en el mundo de la
programacin. A C++ se le ha unido recientemente Java, un lenguaje evolucin de C++,
creado especficamente para programar en Internet pero que puede ser utilizado tambin
en aplicaciones de propsito general.
La evolucin de los lenguajes orientados a objetos se muestra en la Figura 3.8, en
la que se aprecia el tronco comn a todos los lenguajes modernos Algol y las tres
lneas fundamentales: enfoque en Pascal (Ada, Object Pascal), enfoque puro de orien-
tacin a objetos (Simula/Smalltalk) y enfoque en e (Objective-C, C++, Java y Ada-95).
8 Wegner, Peter [1987]: Dimensions ofObject-Based Languajes Design. Nmero especial de SIGPLAN
Notices, 1987.
Abstraccin de datos: tipos abstractos de datos y objetos 113
FORTRAN I
1957 ALGOL 58
FORTRAN 11 COMTRAN
1958
1959 LlSP LGOL60 COBOL
1960 LlSP
1961
1962 BASIC // CPL
1963
1964 SIMULA I
1965
1966 ALGOL-W
1967 SIMULA 67 ALGOL I
1968
1969
Pascal B
1970
1971 Prolog
1972
1973
1974
1975
1976
1977 FORTRAN 77
1978
1979
Smalltalk 80
1980
1981
1982
1983
1984
1985
1986
1987
1988 Common
Object-P LlSP
1989
Oberon ANSIC++
1990
1991
Ada-90
Modula-3
Quick
90
EiHel
Basic
1992
1993 Prolog++
1994 Object-COBOl
Visual BASle
1995 (00 COBOL)
Ada-9S - - - _;-______
Delphi
Java
9Esta tecnologa ha sido extrada y modificada ligeramente con lenguajes de los noventa de Robert
W. Sebesta: Concepts o/ Programming Languages , Addison-Wesley, 2." ed., 1993.
114 Estructura de datos
Basados
en objetos
Basados
en clases
+herencia
Orientados
a objetos
C++ (extensin de C: Borland C++, Microsoft C++, Turbo C++, Visual C++,
Symantec, Watcom ... ).
Objective-C (extensin de C).
Object COBOL (extensin de COBOL).
Object Pascal (extensin de Pascal: Turbo Borland Pascal).
Visual Object (extensin de Clipper).
Delphi (extensin de Turbo Borland Pascal 7.0).
Java (extensin mejorada de C++).
Ada-95 (extensin de Ada-83).
De cualquier forma, Meyer, creador del lenguaje Eiffel, proporciona unos criterios
para considerar la bondad 10 de un lenguaje orientado a objetos, cuyos complementos
configuran, de hecho, una nueva clasificacin. En este sentido, los criterios recogidos en
[Meyer 88] son los siguientes:
1. Modularizacin S S S S S
2. Tipos abstractos de datos S S S S S
3. Gestin automtica de memoria S S En parte S S
4. Slo clases S S En parte S S
5. Herencia No S S S S
6. Polimorfismo (ligadura dinmica) No S S S S
7. Herencia mltiple y repetida No No S S No
10 Meyer, Bertrand: Object Oriented Software Construction, Englewood Cliffs NJ, Prentice-Hall, 1988.
I
116 Estructura de datos
que se pueden realizar sobre los tipos de datos. Los datos no fluyen abiertamente en un
sistema, como ocurre en las tcnicas estructuradas, sino que estn protegidos de modifi-
caciones accidentales. En programacin orientada a objetos, los mensajes (en vez
de los datos) se mueven por el sistema. En lugar del enfoque funcional (invocar una
funcin con unos datos), en un lenguaje orientado a objetos, se enva un mensaje a un
objeto.
De acuerdo con Meyer, el diseo orientado a objetos es el mtodo que con-
duce a arquitecturas de software basadas en objetos que cada sistema o subsistema
evala.
Recordemos, qu son los objetos? Un objeto es una entidad cuyo comportamiento
se caracteriza por las acciones que realiza. Con ms precisin, un objeto se define como
una entidad caracterizada por un estado; su comportamiento se define por las operacio-
nes que puede realizar; es una instancia de una clase; se identifica por un nombre; tiene
una visibilidad limitada para otros objetos; se define el objeto mediante su especifica-
cin y su implementacin.
Una definicin muy elaborada se debe a Meyer: Diseo orientado a objetos, es la
construccin de sistemas de software como colecciones estructuradas de implementa-
ciones de tipos de datos abstractos.
La construccin de un sistema se suele realizar mediante el ensamblado ascen-
dente (abajo-arriba) de clases preexistentes. Las clases de un sistema pueden tener entre
s relaciones de uso (cliente), relaciones de derivacin (herencia) o relaciones de agre-
gacin (composicin) o, incluso, slo relaciones de asociacin. As, por ejemplo, con
una relacin de cliente, una clase puede utilizar los objetos de otra clase; con una rela-
cin de herencia, una clase puede heredar o derivar sus propiedades definidas en otra
clase.
El hardware se ensambla a partir de componentes electrnicos, tales como circuitos
integrados (chips), que se pueden utilizar repetidamente para disear y construir conjun-
tos mucho ms grandes, que son totalmente reutilizables. La calidad de cada nivel de
diseo se asegura mediante componentes del sistema que han sido probados previamen-
te a su utilizacin. El ensamblado de componentes electrnicos se garantiza mediante
interfaces adecuados.
Estos conceptos se aplican tambin con tecnologas de objetos. Las clases (tipos de
objetos) son como los chips de hardware, Cox les llam chips de software, que no slo
se pueden enlazar (ensamblar) entre s, sino que tambin se pueden reutilizar (volver a
utilizar). Las clases se agruparn, normalmente, en bibliotecas de clases, que son com-
ponentes reutilizables, fcilmente legibles.
En la actualidad, existen gran cantidad de software convencional, en su mayora es-
crito normalmente para resolver problemas especficos; por esta razn, a veces es ms
fcil escribir nuevos sistemas que convertir los existentes.
Los objetos al reflejar entidades del mundo real permiten desarrollar aplicaciones
creando nuevas clases y ensamblndolas con otras ya existentes. Normalmente, los de-
sarrolladores experimentados gastan un porcentaje alto de su tiempo (20 al 40 por 100)
en crear nuevas clases y el tiempo restante en ensamblar componentes probados de siste-
mas, construyendo sistemas potentes y fiables.
118 Estructura de datos
Objeto
Mtodos
Datos
Programa Programa
Datos
Taylor" considera que los beneficios del modelado y desarrollo de objetos son:
l. Desarrollo ms rpido.
2. Calidad ms alta.
3. Mantenimiento ms fcil.
4. Coste reducido.
5. Incremento en escalabilidad.
6. Mejores estructuras de informacin.
7. Incremento de adaptabilidad.
Sin embargo, Taylor '2 tambin considera algunos inconvenientes, aunque algunos de
ellos ya han sido superados o al menos reducido su impacto.
11 Taylor, David A. : Object-Ori ented Technology Reading, MA: Addison-Wesley , 1992, pgi-
nas 103-107.
12 [bd., pgs. 108-113.
120 Estructura de datos
RESUMEN
EJERCICIOS
3.1. Construir un tipo abstracto lista enlazada de nodos que contienen enteros.
3.2. Disear un tipo abstracto de datos pila de nmeros enteros y que al menos soporte las si-
guientes operaciones:
Abstraccin de datos: tipos abstractos de datos y objetos 121
PARTE
,
CAPITULO
. , .
structuras e atos lnamlcas:
, un teros
[,'., :", . . '0
" ' ,
, .,- .:.-._;_, .'_ _ _
-- - -- f
_M
J
_ ~ _
, "
1. 'F:i-., '. ,. - -,":.--
CONTENIDO
125
126 Estructura de datos
Un array de requisitos es esttico dado que la cantidad exacta de memoria se fija por
la declaracin del tamao del array. Esta falta de flexibilidad puede ser una desventaja
notable. As, por ejemplo, si en un array de registros se declara para un tamao mximo
de 1.000 registros, el programa no funcionar si se deben almacenar ms de 1.000 regis-
tros en ese array. Por otra parte, si el tamao mximo declarado para un array es mucho
mayor que el total de espacio de memoria requerido, el programa utilizar ineficiente-
mente la memoria, dado que la cantidad de memoria especificada en la declaracin se
reservar, incluso aunque slo se utilice una pequea parte.
Los punteros (apuntadores) 1 permiten la creacin de estructuras de datos dinmi-
cas: estructuras de datos que tienen capacidad de variar en tamao y ocupar tanta
memoria como utilicen realmente. Las variables que se crean y se destruyen durante la
ejecucin se llaman variables dinmicas (tambin annimas). As, durante la ejecu-
cin de un programa, puede haber una posicin de memoria especfica asociada con
una variable dinmica y posteriormente puede no existir ninguna posicin de memoria
para construir y procesar estructuras dinmicas de datos, junto con la estructura dinmi-
ca de datos, por excelencia, la lista enlazada.
.. .. .. .. conti~~ela
...
Una
--~-~",----- .. ..
,"," -'"""'
var
Nombre-var i able : Aidentific ad or -tip o
var
Ptr: ATip oElement o
EJEMPLO 4.1
var
P : Al n teger;
Por ejemplo, la variable P contiene 0591 64 que es la direccin de memoria donde est
la variable entera apuntada 345.
059164 345
Un puntero apunta hacia (a) otra variable cuando contiene la direccin de esa va-
riable.
Estructuras de datos dinmicas: punteros 129
... 345
Es muy til crear un identificador de tipo para los tipos de datos puntero. Se puede crear
dicho identificador y utilizar ese identificador para crear variables punteros .
,'JO - _. .-. ,. .:
.'. - ' ''-''"':
' - " .,_
..
. ,.
tyPe .... .
..-.' .
nbmbr e :" tipo: Aidentificdor-t i po ;,
,"var . .---_ . ,
. -..
. n oinbre-v?r-pt:r : nombf:e-'tipo; ' ",> ", ;
EJEMPLO 4.2
type real
Pu n t er o Real = AR e a l;
A
var
A, B : Punte r oRea l ; B
1. type
--- ."
real
2. var
P : Al nteg e r;
5. var
Pr imero : ~ Rea l;
S i g o Pun tero En t ;
type
Punter o Rea l = ~ Rea l ;
var
P : Pun t eroRea l ;
P es una variable puntero de tipo PunteroReal que apunta a posiciones que contie-
nen reales. La posicin de memoria designada por el valor de la variable puntero P se
representa por v'. La Figura 4.2 representa la relacin entre P y P".
Como P" designa una posicin de memoria, se puede utilizar como cualquier otra
variable Pascal. Se pueden asignar valores a P " y utilizar valores de P " en expresiones
tal como cualquier otra variable. Si P apunta a posiciones que contienen reales, P " es
una variable real. As, en la Figura 4.2 el valor de P " es 3.500.
Sin embargo, estas operaciones no se pueden realizar directamente tras la declaracin,
debido a que el objeto o direccin apuntada p A no tiene existencia. Antes de que un
programa utilice un puntero, se requiere primero espacio para el tipo de datos objeto de
la direccin del puntero. En otras palabras, un programa debe inicializar sus punteros
-su declaracin no basta ; para iniciar un puntero se debe utilizar el procedimiento
New.
3500
Formato
New (P)
p variable puntero
exige que exista suficiente espacio de memoria libre en el montculo la pila de varia-
bles dinmicas (heap) para asignar a la nueva variable. En caso contrario se producir
un error en tiempo de ejecucin.
Se puede representar el valor de una variable puntero por una flecha dirigida a una
celda de memoria. El diagrama
p
?
muestra que la variable puntero P apunta a una celda de memoria cuyo contenido se
desconoce. Esta es la sentencia que existe inmediatamente despus de que se ejecuta
New (P) .
El smbolo P se utiliza para referenciar a la celda de memoria apuntada por la va-
A
desreferencia.
La sentencia de asignacin
25.0
Atencin
P:= 25 .0; asignacin no vlida
Write (P : I0 : 2) ; sentencia no vlida
..
,e ,--,_:','-_--, , ___ ~ ~:;
-
'i",- ,.~,..~:; -,., . . '<':,-. ,<-.':__ -- __
.;_: _-,: .-,--~-.~ . __.J', . ;', .'-' -::
-
__, --, __ '_, <
-
' ,_'.' ,
l.
,:' ' ,,' < :':' ' '' 1<, ;\ ' f ' i':t "' , , ':' : ' ', ,: . : ' ,,1 ' ,, ' , l . . . ' "
., ' ,f .," , L~direc.cip~ ,~~~ IW~lpj,qp: de memoria ~e;lllpla~eNt . cm~; se crea una luira-
" "'b'l:'='d" ... :."." . .. . ':' . . -::''':' ,:' 1)/'\""""':' "" ",:"':< ..,'::' ',' '_,",- ',' .. . . , ,,I""":f;!- ,.", ';' :, .,. , ... . <
'r i'.!;.- ;'",:"if: : : ' , \ - " :' - :r'~'n:,',i ' ; ' :~ l~<:;:::' '>,';:"">!: : "- '(-' . ,~.. j"~; :; " ~' , j'-:, "f> , , . ".
.
"r-----.. . . -- :. .::~'1::~"". ". ,
'
"
i, ':!,~':';_
.- ! , ~, ..
,"
.
'- ,
! ,
,
't' - . .'
...
, "
" .. " -_: - ---
P , ."... ,<,
,,.' ,1
-l;: ~ \ .;h.'
. -
"'!'iiw.;......, <.~ ",,",,,-, ' ''',,+__ . -f' ,,-,_."' _ -- , -_ . _------
< -~
EJEMPLO 4.3
new (Ptr) ;
Ptr ~ : = 'M ckenna ';
La sentencia new (pt r) crea una celda de memoria vaca (o con basura) a la que apun-
ta Ptr. La segunda sentencia sita el valor Mckenna en esa celda de memoria. Un I I
Ptr
Mc Kenna
Implementacin interna
Internamente, los punteros se implementan teniendo en cuenta las direcciones de memo-
ria a las que se apunta. Por ejemplo, supongamos que la direccin de p tres 1015 Y
que la celda de memoria que crea new (ptr) est en la direccin 1256. Por consigUien-
te, el efecto de
__ _ _ o
- __ o
Estructuras de datos dinmicas: punteros 133
new (ptr) ;
pt rA := ' McK e n na ';
1 2 56 McK enna Mc Ke nn a
Pt r Ptr
Atencin
Observe que en la declaracin de un puntero, el circunflejo est situado a la izquierda de
su tipo, mientras que en una sentencia en que se accede a la celda de memoria a que se
est apuntando, el circunflejo aparece a la derecha.
LO 4.4
Realizar el seguimiento del segmento de programa.
var
1. P t r1 : Ac ha r;
2. Pt r2 : Ain t eger ;
begin
3. Ne w (Ptr 1) ;
4. P tr l " : = ' B';
5. Ne w (Ptr 2);
6. P t r 2A := 86 ;
LO 4.5
Deducir la salida del siguiente programa.
program Pun te r o ;
type
Ptrin t = Ai nt e ger;
var
l , J : Pt rint ;
N : in t e g er ;
begin
Ne w ( l) ;
N ew (J) ;
N: = 5;
l A .-
. - N ,'
Wri t e Ln ( l A) ;
. - l ',
J .-
J A .. -
- - 7 ,'
Wri teLn
end.
134 Estructura de datos
EJEMPLO 4.6
Qu se imprime tras ejecutar el siguiente programa?
program Prueba S i mp l e ;
var p, q : Ainteger;
x, y : int ege r;
begin
ne w (P );
P A.. _ - 5 ,.
X: ::::: p '" + 1;
Y . -- pA ,.
new (q) ;
qA: = y + 3;
WriteLn (x, " , y, " , pA, " , qA)
end.
Solucin
6 5 5 8
x 6 5
y 5 8
EJEMPLO 4.7
Cul es la salida de este programa?
program Test ;
type
Estudiante = record
Letr a : char;
Edad: int eger
end;
Estructuras de datos dinmicas: punteros 135
Pu n tEstu = A Estud i a nt e;
var
P I , P2 : PuntEs t u ;
begin
N ew (P 1 ) ;
P l A. Eda d -- l ',
A
P I .L etr a .-
- 'A" ,
WriteLn (PlA.Edad , Pl A. Letra) ;
New (P2) ;
A
P2 .E dad = 2,
P2 A . Letra : = 'B ';
Wr i teLn (P2 A .Edad, P2 A.Letra);
PI := P2 ;
A
P2 .Edad - 3 , -
P2 A . Letra := 'C' ;
Wr it eLn (PlA . Edad, P I A. Letra , P2 A. Edad , P2 A .L etra)
end.
Ejecucin
lA
28
3C3C
var
P : Ain teger;
New (P) ;
. -- 17 ,'
Recuerde
Write (P A) sen t enci a vl i da
Wr i te (P) sentenc i a no v l ida (error)
Asignacin
Las variables dinmicas pueden tener ms de un puntero que est apuntando a ellas.
Tambin los punteros pueden ser modificados de modo que apunten a variables dinmi-
cas diferentes en momentos diferentes.
Estos cambios se pueden realizar con el operador de asignacin (:=). Estudiemos las
asignaciones posibles.
(1) p := q (2)
\.,,~,~ ~-,-
~; . .'."""
.
::', _-- ' :--i.".
No se .
:,;
.. -, -
diferente . . . . ,'. .
"
, . "
, ,
i:
.' ",:. " " ,.......
" ."
.
" , '"
' .
,- ,
4.8
Pl Y P2 son punteros de tipo entero. Qu se imprimir tras la ejecucin del siguiente
segmento de programa? y cmo ser la distribucin en memoria?
new ( p I ) ;
new ( p 2) ;
P IA := 86 ; No se puede acceder a este valor-----
P2 A := 50 ;
P I:: P 2 ;
Writ e Ln (PIA, " , P2A) ;
Solucin
50 50 PI
86
P2
50
Estructuras de datos dinmicas: punteros 137
Formato
dispose (p)
p variable puntero
2. P se vuelve indefinido.
I
p
situacin inicial
?
situacin despus de di spose (p)
p
EJEMPLO 4.9
1. var
p, Q: Ainteger;
begin
2. New ( p) ;
3. pA - 8;
-
4. Q -
- P;
5. QA -- 5;
6. Dispos e ( P)
end
138 Estructura de datos
4.3.5. Constante ni 1
Pascal proporciona una constante predefinida, nil (nulo). La constante nil se utiliza para
dar un valor a una variable puntero que no apunta a ninguna posicin, nil puede ser
asignada a un puntero de cualquier tipo.
p: = nil
p : = ni 1;
p '" : = 5; es ilegal ya que se instruye a la computadora a almacenar 5 en la
posicin apuntada por p, pero debido a la primera sentencia (p: =nil),
p no apunta a ninguna direccin
EJEMPLO 4.10
El segmento de programa
var
p : Ac h a r;
begin
p := nil;
i f p = nil
then
WriteLn ( ' e l punte ro P n o apun ta a n ad a')
else
Wr i t e Ln ( ' P se qu eda i n def in i d o apunta ' ) ;
proporciona la salida
..
,.- ,. . ,_o
,
.~;
............... ij. JC
.',.- .. -. ~r,i "l"--_
se puede ejecutar muchas veces dentro de un programa simple; cada vez que se ejecuta,
crea una nueva celda de memoria. En consecuencia no existe lmite declarado para saber
cuntas celdas de memoria se pueden crear utilizando unos pocos punteros.
Estructuras de datos dinmicas: punteros 139
Los arrays se dice que son estticos debido a que la cantidad mxima de espacio de
memoria que se puede utilizar debe ser declarado por anticipado. Los punteros son din-
micos ya que no hay tal lmite previo, el espacio de memoria se crea durante la ejecucin
del programa.
var
Pu nt eroA , Pun tero B: Aintege r;
las comparaciones:
Pl : = P 2 ;
redirige PIde modo que apunta a la celda de memoria apuntada por P 2. Despus de la
ejecucin de PI: = P2, ambos punteros apuntan a la misma celda.
Se dice que dos punteros son iguales si ambos apuntan precisamente al mismo ele-
mento de datos. En un diagrama ambos apuntan a la misma caja.
Pl
25
P2
La traza de memoria es
p p
Carpe Concha
,
q q
Dien Dien
La salida ser
Concha
Concha
EJEMPLO 4.13
var
enlace: pointer;
FreePtr
HeapPtr ~
Montculo (crece hacia arriba)
SSeg:Sptr ~
Pila libre
SSeg:OOOO ~
Variables globales
Contenid o de una
imagen de
archiv o .EXE
Segmento de cdigo de la unidad System
El diagrama de la Figura 4.4 muestra tambin que la pila crece hacia abajo en la
memoria y el montculo crece hacia arriba en la memoria. Aunque la pila y el montculo
comparten la misma zona de la memoria, ellas nunca deben solaparse (recubrirse).
La mayora de las variables que se declaran en Turbo Pascal son estticas, su tamao
se fija en tiempo de compilacin y no pueden variar. Por el contrario, el montCulo alma-
cena variables dinmicas.
~ El tamao de la zona
Aqu se almacena el cdigo Comienzo del de cdigo es el total
objeto. programa del tamao del cdigo
principal de programa principal
ms el tamao del
cdigo de todas las
unidades utilizadas
por el programa. El
Cdigo unidad n
tamao total del
cdigo slo est
limitado por la
memoria disponible.
Cdigo unidad 2
Cdigo unidad 1
--------------------~~ Tamao de la zona de
Comienzo de datos (suma de todas
datos las variables globales
Se almacenan variables
del programa principal
globales (estticas)
y todas las unidades
y constantes con tipos.
Fin de datos utilizadas). El mximo
es 65.520 bytes.
----------------------~~
El tamao del
montculo se
establece con las
Espacio del montculo no opciones del
utilizado disponible para compilador. Si la
almacenar variables dinmicas memoria disponible es
adicionales. menor que el lmite
~ bajo del montculo, el
programa no se
cargar.
Formato
Formato
FreeMem (varpunt, ta ma o)
EJEMPLO 4.14
GetMem (y, 100);
FreeMem (y, ~OO);
Nota
Formato
MaxAvail
MemAvail devuelve un valor (del tipo entero largo) que indica, en bytes, la cantidad
total de memoria disponible para variables dinmicas.
Formato
MemAvail
EJEMPLOS 4.15
begin
Writeln (MemAvail, 'bytes disponibles');
Writeln( 'el bloque libre ms grande es:', MaxAvail, 'bytes')
end
Programa
En el archivo Marathon van a almacenarse los datos personales de los participantes del
Marathon Jerez-97.
148 Estructura de datos
Anlisis. Este sencillo problema nos sirve para escribir un ejemplo de utilizacin de
variable puntero y variable apuntada o referenciada. El puntero va a referenciar a un
registro con los campos necesarios para representar los datos personales. Es evidente
que podramos utilizar una variable esttica de tipo registro, pero es un ejemplo.
Codificacin
program Marathon (input, output);
uses crt;
type
registro = record
nombre, apellido : string[25J;
direccin : string[30J;
ciudad : string [20J;
edad : integer;
marca : record
n, m, sg: integer
end;
end;
Ptrreg = Aregistro;
var
R : Ptrreg; F: file of registro;
RESUMEN
Un puntero es una variable que se utiliza slo para almacenar la direccin de memoria de otra
variable. Un puntero apunta a otra variable cuando contiene una direccin de la variable.
Pascal tiene mtodos especiales para declaracin, iniciacin y manipulacin de punteros. La
razn principal para utilizar punteros es que ellos hacen posible las estructuras de datos dinmi-
cas, que les permiten crecer, decrecer e incluso desaparecer mientras se estn ejecutando.
152 Estructura de datos
PROBLEMAS
4.1. Escribir las declaraciones necesarias para definir un tipo de datos puntero a un registro de
estudiante con los campos Apellido-I, Apellido-2, Nombre, Fecha-nacimiento y notas. Los
tres primeros campos definirlos de tipo puntero a cadena de 25 caracteres. El campo Fecha
puntero a un registro con los campos da, mes y ao. Y el campo Notas puntero a un array
de 10 elementos.
4.2. Escribir un procedimiento que devuelva los datos correspondientes a un registro de estu-
diante definido en 4.1. En el procedimiento se ha de reservar memoria para cada uno de los
campos del registro.
4.3. Definir un vector de registro del tipo definido en 4.1. Escribir un procedimiento en el que
se d entrada a los registros de los estudiantes de una clase que tiene un mximo de 40
alumnos. Utilizar el procedimiento definido en 4.2.
4.4. Definir un archivo cuyos elementos van a ser los registros definidos en 4. 1, con la salvedad
de que en vez de los campos puntero, los campos sean del tipo apuntado. Escribir un
procedimiento que tome como entrada el vector generado en 4.7 Y escriba los registros en
el archivo.
4.5. Definir de nuevo el registro enunciado en 4.5 para escribir el procedimiento de entrada de
campos del registro con la particularidad de que se reserve memoria con el procedimiento
GetMem. El nmero de bytes a reservar se debe ajustar al tamao real del campo.
4.6. Una ecuacin de segundo grado depende de tres parmetros de tipo real: a, b, c. Escribir un
programa que tenga como datos de entrada los coeficientes de la ecuacin de segundo gra-
do y como salida las races de la ecuacin. Definir los parmetros a, b, c como punte-
ros a nmeros reales de tal forma que en el procedimiento de entrada se reserve memoria
para ellos.
,
CAPITULO
Istas en aza as:
Ista en aza a
CONTE
Una forma de almacenar elementos relacionados es alinearlos, formando una lista lineal
que necesita un enlace por cada elemento, para referenciar al elemento sucesor.
153
154 Estructura de datos
p-
7 15 34 67 nil
En la Figura 5.1 se muestra una lista enlazada de enteros a la que se accede a travs
del puntero P. Una lista es una estructura que se utiliza para almacenar informacin del
mismo tipo, con la caracterstica de que puede contener un nmero indeterminado de
elementos, y que estos elementos mantienen un orden explcito. Este ordenamiento ex-
plcito se manifiesta en que cada elemento contiene en s mismo la direccin del siguien-
te elemento.
Una lista es una secuencia de O a n elementos. A la lista de cero elementos llamare-
mos lista vaca. Cada elemento de una lista se denomina nodo. En un nodo po-
demos considerar que hay dos campos, campo de informacin ( I nfo) y campo de enla-
ce (Enl ac e) o direccin del elemento siguiente.
NIL
... -- NIL
p:=nil
Figura 5.3. lista enlazada sin informacin o inicializacin de lista (lista vaca).
Una lista es una estructura de datos dinmica. El nmero de nodos puede variar rpi-
damente en un proceso, aumentando los nodos por inserciones, o bien disminuyendo por
supresin (eliminacin) de nodos.
Las inserciones se pueden realizar por cualquier punto de la lista. As pueden reali-
zarse inserciones por el comienzo de la lista, por el final de la lista, a partir o antes de un
nodo determinado. Las eliminaciones tambin se pueden realizar en cualquier punto de
la lista, aunque generalmente se hacen dando el campo de informacin que se desea
eliminar.
Listas en/azadas: e/ TAO lista en/azada 155
Los elementos de la lista tienen la propiedad de que sus elementos estn ordenados
de forma lineal, segn las posiciones que ocupan en la misma. Se dice que a j precede a
a j +1 para i = 1, 2, 3, 4, 5, ... , n -1 y que a j sucede a ajol para i = 2, 3,
4, 5, 6, ... , n.
Para formar el tipo de datos abstracto Lis t a a partir de la nocin matemtica de
lista, se debe definir un conjunto de operaciones con objetos de tipo Lista. Las opera-
ClOnes:
begin
P : = Pr im e r o( L ) ;
while P<> nul o do ,
,
begin
Q := Siguiente (P , L) ; ,
,
5.2. IMPLEMENTACiN
, DEL TAO LISTA CON ESTRUCTURAS
ESTATICAS
En la implementacin de una lista mediante arrays, los elementos de sta se guardan en
posiciones contiguas del array. Con esta realizacin se facilita el recorrido de la lista y la
operacin de aadir elementos al final. Sin embargo, la operacin de insertar un elemen-
to en una posicin intermedia de la lista obliga a desplazar en una posicin a todos los
elementos que siguen al nuevo elemento a insertar con objeto de dejar un hueco.
En esta realizacin con estructuras estticas se define el tipo Lis t a como un regis-
tro con dos campos: el primero, es el array de elementos {tendr un mximo nmero de
elementos, pre-establecido}; el segundo, es un entero, que representa la posicin que
ocupa el ltimo elemento de la lista. Las posiciones que ocupan los nodos en la lista son
valores enteros; la posicin i-sima es el entero i.
Declaraciones:
!
!
const ,,
1
Max= 1 00 ;
I
,
-
Listas en/azadas: e/ TAO lista en/azada 157
type
Ti po in fo= {t i po d e l campo i n form a c i n d e c a da nodo}
List a = record
E leme ntos: array [l . . Max] of Tip o info ;
Ultim o: integer
end;
pos icion = O " Max;
El procedimiento Inserprim (X, L), que inserta X como primer nodo, debe des-
plazar una posicin a la derecha todos los nodos, para as poder asignar X en la primera
. .,
poslclon.
Para implementar la operacin Supr ime (X, L) , primero hay que encontrar la po-
sicin que ocupa x, a continuacin se elimina.
Suprimedir:
Q: Pos i e i o n;
Le: bo o l e a n;
begin
Q:= 1;
Le : = fal s e;
while (Q < = L. Ult imo) and not Le do
begin
Le := L .El e ment os [Ql= X
if not Le then Q:= Q+1
end;
if Le then
Loea liza:= Q
else
Loea l i z a := O
end;
Este mtodo de implementacin de listas enlazadas utiliza variables puntero que permi-
ten crear variables dinmicas, en las cuales se almacena el campo de informacin y el
campo de enlace al siguiente nodo de la lista. Con esta implementacin se ajusta la memo-
ria ocupada al tamao real de la lista, no como ocurre en la realizacin mediante estructuras
estticas en las que es necesario prever un mximo de elementos o nodos. Ahora, cada
vez que sea necesario crear un nuevo nodo se llama al procedimiento que capta la memoria
necesaria de la pila de memoria libre, y se enlaza con la lista. De igual forma cuando sea
necesario eliminar un nodo, la memoria ocupada por ste se devuelve a la pila de memo-
ria libre. El proceso es dinmico, la lista crece o decrece segn las necesidades.
Con esta realizacin se evitan los desplazamientos de elementos a la derecha o a la
izquierda en las operaciones de insercin o eliminacin, respectivamente. Por contra,
cada vez que se quiere acceder a un nodo hay que recorrer la lista, a travs de los enlaces
hasta alcanzar su direccin. Tambin hay que tener en cuenta que en esta realizacin de
listas, cada nodo ocupa la memoria adicional del campo de enlace.
Las variables enteras contienen o pueden contener valores enteros, y sucede igual
con variables reales. El tipo de variables puntero (o apuntadores) son aquellas cuyo con-
tenido va a ser la direccin de memoria de un dato. Las variables puntero, al igual que
las variables enteras o reales, son variables estticas, ya que se crean (se reserva memo-
ria para ellas) en tiempo de compilacin.
Pu nte ro= ATipo ap unt ado ;
Con esta declaracin de tipo estamos expresando que los valores que contenga una
variable de tipo Puntero van a ser direcciones de memoria del tipo Tipoapuntado. Grfi-
camente:
p
160 Estructura de datos
Con los punteros se pueden construir toda clase de estructuras enlazadas. Estas es-
tructuras son dinmicas; es decir, el nmero de elementos puede cambiar durante la
ejecucin del programa. Para lo cual hay procedimientos que permiten crear y destruir
elementos durante la ejecucin del programa, y as se ajustan a las necesidades de cada
instante, cosa que no ocurre con las estructuras estticas como los arrays.
Al trabajar con estructuras dinmicas hay que manejar dos clases diferentes de varia-
bles: variables puntero (direccionan un dato) y variables referenciadas (son apuntadas).
type
Ptrentero= Ain t eger ;
Ptrcadena= As t ring[251;
, var
I
Pe: Ptrentero;
Pc: Pt r ca dena;
type
Ptrnodo - APers o na;
Persona - record
No mbre: stri ng[ 25 1;
Direcc: string[501;
Edad : intege r ;
Enlace: Ptrn odo
end;
Variables del tipo puntero Ptrnodo van a estar asociadas con variables referencia-
das del tipo Persona. '
var
P : Pt rn odo;
P Persona
Este procedimiento reserva memoria, crea una variable referenciada cuyo tipo (Per-
sona) est declarado dentro de las definiciones formales. Despus de la ejecucin del
procedimiento new la variable puntero tiene la direccin en memoria de la nueva varia-
ble creada.
,
Listas enlazadas: el TAO lista enlazada 161
Con esta variable se pueden hacer exactamente las mismas operaciones que con una
variable registro del tipo Persona.
new ( P) ;
pA.Nombre:= 'Juan Marco';
readln (PA. Edad) ;
pA.Enlace:= nil;
Existe una operacin inversa a new que permite liberar la memoria referenciada por
una variable puntero: procedimiento dispose.
type
Ptr= AElemento;
Elemento = record
Numero: integer;
Enlace: Ptr
end;
var
PI, P2: Ptr;
P2:= PI;
P2:= PIA.Enlace; Se asigna el campo Enlace de la variable referenciada por P l.
PIA.Enlace:= P2 A .Enlace;
P2:= nil; Es posible hacer que una variable puntero no apunte a nada
as ignando n il.
dispose (PI) ;
PI:= nil;
I,
Supngase los tipos
type
T i po i n f o =
Pt rn o d o = ANodo ;
No do = record
In f o : Tip o i nfo ;
Sgte : Ptrn odo
I end;
Crear lista
Inicia una lista sin nodos, como lista vaca.
procedure Listava c i a( var L: Ptrnodo);
begin
L:= nil
I
end;
I
Esvacia
! Esta operacin es una funcin que determina si la lista no tiene nodos.
,
,
begin
Es v a cia := L = nil
end;
,
,
5.5. BSQUEDA EN LISTAS ENLAZADAS ,
,
1
La operacin de bsqueda en una lista enlazada, requiere una operacin Localiza
que permite localizar la direccin de un nodo que contenga un campo de informacin
1,,
-o
~
determinado; asimismo, se puede plantear una operacin Ex i s t e que sirve para deter- ,,
,
-~
l
~
I
I
Listas enlazadas: el TAO lista enlazada 163
minar si hay un nodo con cierta informacin. La funcin Loca 1 iza devuelve la direc-
cin de un nodo o ni l. Los cdigos fuente de ambas funciones son:
Anterio r:= L
I
el se
An ter i or : = n i l
end
end;
La operacin siguiente devuelve la direccin del nodo siguiente a uno dado, o bien
n i 1 si es el ltimo nodo.
end;
, .
Ultimo (L)
Para obtener la direccin del ltimo nodo se ha de recorrer toda la lista.
function Ultimo(L:P tr nodo ) : Ptrnodo ;
{ El l ti mo de l i s ta vaca co n s i der a mos nil }
begin
if Esv acia ( L ) then
Ult i mo := ni l
else
begin
while LA . Sgte <> n i l do
L:= L ~ . Sgte ;
Ult imo:= L
end
end;
,
5.7. INSERCION DE UN ELEMENTO EN UNA LISTA
La operacin de insercin de un elemento con un campo de informacin X siempre su-
pone crear un nuevo nodo. Para ello se utiliza el procedimiento new. Adems habr que
hacer un movimiento de enlaces. La funcin Crea r devuelve la direccin de un nuevo
nodo.
function Crear(X : T ipo i n f o ): Ptrnod o ;
var
N : Ptrnodo ;
begin
, n ew (N) ;
;
N ~ . In f o : = X;
N ~ . Sg t e : = nil;
Crea r: = N
end;
Inserprim(X,L)
Listas enlazadas: el TAO lista enlazada 165
L-- N1 N2 N nil
A-- x
Inserta(X,P,L)
p-
L- nil
A-....,
i
procedure I n se rt a(X : T i p o i n f o ; P: Ptrn o d o ; var L : Pt r n od o ) ;
var
A : Ptr n odo ; I
begin
A := Crea r ( X) ;
if Esvac ia(L) then
L: = A
elBe if P= L then
begin
AA. Sgte := P ;
L: = A
end
elBe begin {Ah ora es cuando se en l aza el nu evo n o do e n t r e e l n odo
a n t er i or y e l n o d o P }
Anter i or( P ,L ) A. Sg t e : = A;
AA. Sg t e := P
end
end;
I
,
I
166 Estructura de datos
Otra forma de enlazar el nuevo nodo consiste en aadir el nuevo nodo a continuacin
de P e intercambiar el campo de informacin:
elae
begin {E l nuevo nod o es enl azad o a cont inu ac i n de P, d espus s e
intercamb i a el ca mpo Info }
AA . Sgte : = p A. Sgte ;
pA . Sg t e : = A;
AA . lnfo := P A. lnfo ;
pA .lnf o : = X
end;
Inserfin(X,L)
L- N1 N2 N x nil
guierlte al que va a ser borrado y liberar la memoria ocupada por el nodo a borrar. Esta
opera in se realiza con una llamada al procedimiento dispose.
Co las operaciones de supresin de un nodo y Ul t i mo resulta fcil eliminar todos
los nodos de una lista, quedando sta como lista vaca.
,
L- N1 N2 N3 N4 O " - N nil
- -- - - -
168 Estructura de datos
En las listas tratadas anteriormente los elementos de las mismas estn ordenadas por la
posicin que ocupan dentro de la lista. Si el tipo de informacin que representa cada
elemento es un tipo ordinal, o tiene un subcampo ordinal, se puede mantener la lista
ordenada respecto a dicho campo.
Al representar la lista ordenada mediante un puntero externo L , ste apuntar al pri-
mer nodo en el orden creciente de los elementos.
Dada la lista (al, a2, a3 , . . . ,an) estar ordenada si a, <= az <= a 3 <= ...
ano' <= an
La representacin enlazada:
L- ... -- ni!
i
Listas enlazadas: el TAO lista enlazada 169
Si la lista est vaca, el nodo se inserta como el primero de la lista. En caso contrario
se presentan dos casos:
a) El nodo ha de ser el primero de la lista.
b) El nodo ha de situarse entre dos nodos, o bien el ltimo. Al tener la direccin del
anterior, se reajustan los enlaces.
A
L-- 10 15 31 42 91 nil
37
N
PROBLEMA 5.1
Como ejemplo de listas ordenadas, se escribe un programa en el que se forma una lista
ordenada de N nmeros enteros aleatorios. Una vez formada, se eliminan los elementos
repetidos y se muestra la lista.
Anlisis
La unidad Lis t aOrdenada contiene las operaciones de manejo de listas. El progra-
ma Lis t a Or contiene un procedimiento El i mi n a r Du p que sirve para eliminar ele-
mentos duplicados y otro procedimiento Mo s t r a r que visualiza la lista. El algoritmo
de EliminarDup recorre la lista nodo a nodo, comparando el nodo actual con el si- J
I
guiente; si son iguales se libera la memoria del nodo siguiente, se restablecen los punte- ,
ros y contina el proceso con el siguiente nodo. La lista estar formada por nmeros ,
!
enteros generados aleatoriamente de 1 a 99. El nmero de nodos, lo fijamos mediante la "
,
,
constante Elementos = 55.
Interfaz de la unidad
unit ListaOrdenada;
interface
type
Tipoinfo = integer;
Ptrnodo = ANodo;
Listas en/azadas: e/ TAO lista en/azada 171
Nodo = record
Inf o :Tipoinfo;
Sgte : Ptrnodo
end;
function Posinser (X:Tipoinf o ; L:Ptrnodo) : Ptr n od o ;
procedure Inserord e n (X : Tipoinfo, var L:Ptrnodo) ;
function Busc orden (X : T ip oinf o ; L :Ptr nodo) : Pt rn odo ;
implementation
.. . {C dig o correspondiente a los procedimientos / fu ncion es escrit os
anterior ment e }
end .
M = 99; i
var
L,Q:Ptrno do ;
Y: i n t ege r;
172 Estructura de datos
, Solucin
El vector se representa mediante una lista enlazada con un puntero al primer nodo y otro
al ltimo nodo con nmero real aadido, La estrategia de asignacin es la indicada en el
enunciado del problema planteado,
La unidad Ve ctDi na contiene los tipos de datos y las operaciones necesarias para
cumplir los requisitos del problema.
La ventaja de una lista enlazada sobre un array es que la lista enlazada puede crecer y de-
crecer en tamao y que es fcil insertar o suprimir un valor (nodo) en el centro de una lista en-
lazada.
La lista enlazada es una estructura muy verstil. Los algoritmos para insercin y eliminacin
de datos constan de dos pasos:
El TAD lista enlazada es uno de los ms utilizados en gestin de proyectos software, debido a
que la estructura lista suele aparecer en la resolucin de numerosos problemas.
EJERCICIOS
Todos los ejercicios y problemas a los que se hace referencia deben de considerar la lista en-
lazada implementada mediante punteros. La direccin de acceso a la lista est en la variable
puntero L.
.
5.1. Escribir la funcin Cardinal que calcule el nmero de nodos de una lista enlazada.
5.2. Escribir un procedimiento que aada un nuevo elemento a la lista L a partir del elemento
. , .
-eSlmo.
5.3. Escribir un procedimiento que elimine de una lista L el nodo i-simo. 1
5.4. Escribir una funcin que devuelva la direccin del nodo i-simo de la lista L.
5.5. Escribir la funcin INVERSA que tiene como argumento de entrada la lista enlazada L,
devuelva la direccin de otra lista que tenga los nodos en orden inverso, es decir, ltimo
nodo pase a ser el primero, penltimo pase a ser el segundo, y as sucesivamente.
5.6. Escribir un procedimiento que tenga como argumento de entrada una lista L de nmeros
enteros, de la que se sabe que tiene nodos repetidos. El procedimiento crear otra lista
cuyos nodos contendrn las direcciones de los nodos repetidos en la lista L. Definir los
tipos de datos para representar ambas listas.
5.7. Una lista de cadenas de caracteres est ordenada alfabticamente. Escribir un procedimien-
to para suprimir aquel nodo que contenga la cadena S.
5.8. Se quiere implementar una lista enlazada mediante arrays de tal forma que cada elemento
del array contenga dos campos: campo de informacin y un segundo campo que llamare-
mos apuntador. El campo apuntador tiene la posicin que ocupa el siguiente nodo de la
lista, el ltimo nodo tiene el campo apuntador a cero.
Escribir los tipos de datos para esta representacin de la lista.
5.9. Dada la representacin de la lista propuesta en el anterior ejercicio, escribir el procedi-
miento de insertar un nodo como primer elemento de la lista.
5.10. Dada la representacin de la lista 5.8, escribir el procedimiento de insertar un nodo a partir
del que ocupa la posicin P.
5.11. Siguiendo con la representacin propuesta en 5.8, ahora escribir la funcin que localice un
nodo con el campo X.
5.12. Con la representacin de lista propuesta en 5.8, escribir el procedimiento de suprimir el
nodo con el campo de informacin X.
PROBLEMAS
5.1. Dada una lista enlazada de nmeros enteros, escribir las rutinas necesarias para que dicha
lista est ordenada en orden creciente. La ordenacin se ha de hacer intercambiando los
punteros a los nodos.
5.2. Se dispone una lista enlazada ordenada con claves repetidas. Realizar un procedimiento de
insercin de una clave en la lista, de tal forma que si la clave ya se encuentra en la lista la
Conjunto vaco.
Aadir un elemento al conjunto.
Unin de conjuntos.
Interseccin de conjuntos.
Diferencia de conjuntos.
Nota: Los elementos del conjunto que sean de tipo cadena.
5.6. Escribir un programa en el que dados dos archivos de texto F 1, F 2 se formen dos conjun-
tos con las palabras respectivas de F 1 Y F 2 . Posteriollnente encontrar las palabras comu-
nes a ambos y mostrarlas por pantalla. Utilizar la unidad de conjuntos del problema 5.5
para resolver este supuesto.
5.7. Escribir un programa que forme lista ordenada de registros de empleados. La ordenacin
ha de ser respecto al campo entero Sueldo. Con esta lista ordenada realizar las siguientes
accIOnes:
Mostrar los registros cuyo sueldo S es tal que: P 1 ::::; S ::::; P 2 .
Aumentar en un 7 por 100 el sueldo de los empleados que ganan menos de P pesetas.
Aumentar en un 3 por 100 el sueldo de los empleados que ganan ms de P pesetas.
Dar de baja a los empleados con ms de 35 aos de antigedad.
5.8. Se quiere listar en orden alfabtico las palabras de que consta un archivo de texto junto con
los nmeros de lnea en que aparecen. Para ello hay que utilizar una estructura multienlaza-
da en la que la lista directorio es la lista ordenada de palabras. De cada nodo con la palabra
emerge otra lista con los nmero de lnea en que aparece la palabra en el archivo.
Escribir la unidad Li s ta_d e _Ent e r o s para encapsular el tipo lista de nmeros en-
teros.
Escribir la unidad L i s t a _ d e_Pa l abras para encapsular las operaciones que van a
manejar la lista de palabras propuesta.
Escribir un programa que haciendo uso de la(s) unidades anteriores resuelva el pro-
blema.
178 Estructura de datos
5.9. El polinomio P(x) = Go + G1X + G:zX 2 + ... + a"x" deseamos representarlo en una lista enlaza-
da, de tal forma que cada nodo contenga el coeficiente y el grado de un monomio. Escribir
un programa que tenga como entrada los coeficientes y exponentes de cada trmino de un
polinomio, y forme una lista enlazada para representarlo; ha de quedar en orden decrecien-
te respecto al grado del polinomio. En el programa deben de encontrarse las operaciones:
Evaluacin del polinomio para un valor dado de x.
Obtencin del polinomio derivada de P(x).
Obtencin del polinomio producto de dos polinomios.
5.10. Un vector disperso es aquel que tiene muchos elementos que son cero. Escribir un progra-
ma para representar mediante listas un vector disperso. Y realizar las operaciones:
Suma de dos vectores dispersos.
Producto escalar de dos vectores dispersos.
Istas emente en aza as
CONTENIDO
En las listas simplemente enlazadas hay un solo sentido en el recorrido de la lista. Puede
resultar til el poder avanzar en ambos sentidos, de tal forma que los trminos predece-
sor y sucesor no tengan significado puesto que la lista es completamente simtrica. En
cada nodo de una lista doblemente enlazada existen dos enlaces, uno al siguiente nodo y
otro al nodo anterior.
179
180 Estructura de datos
Un nodo de una lista doblemente enlazada puede ser considerada como un registro
con tres campos: un campo informacin y dos campos de enlace.
Lo
4 ni! H o L
--1_ _' - - .- ... A ni!
tener cada nodo dos enlaces, uno al siguiente y otro al anterior, y ser una lista simtrica,
se dispone directamente de las direcciones de los nodos contiguos a uno dado.
Las operaciones anteriores son las operaciones bsicas para manipulacin de listas.
Dependiendo del tipo de representacin elegida y del problema a resolver podrn existir
teros. Con esta implementacin, la lista doble se representa con una variable puntero Ld
a un nodo extremo que por conveniencia le consideramos el primer nodo de la lista.
type
T i poi n for - ... ;
P trndble = ANododble
Nod odb l e = record
I nfo : T ipoinf o ;
Sgt e , An te r: Pt rn db l e
end;
Crear lista
Inicia una lista doble sin nodos, como lista vaca.
procedure Li s t aVac i a (var Ld : Ptrndble) ;
begin
Ld : =nil
end;
P ---,
Esvacia
La funcin EsVaci a devuelve verdadero si la lista est vaca y falso en caso contrario.
function Esva c ia (Ld: Pt r ndble) : boole a n ;
begin
Esvacia : = Ld = n i l
end
Localiza
Devuelve la direccin de un nodo o ni l.
function Loca li za (X : T i poi n f o ; Ld : Ptrndb le) : Ptr n d b le ;
var
T: Pt rn dbl e;
begin
T : = Ld ;
if not Esvaci a (Ld) then
while (T A. Sgte < > n il) and (TA . lnfo < > X) do
T : = TA . Sgte ;
if T A. l n f o < > X then
Loca liza : =ni l
else
Locali za : = T
end;
!
,
Ld := Ld A.S gte ;
I Exis te := Ld = P
end
elee
Msge ( 'Err or e n l lamada ' )
end
Ultimo (Ld)
La operacin Ul tim o obtiene la direccin del nodo que se encuentra en el otro extremo
del nodo que consideramos el primero, el apuntado por Ld.
function Ult i mo (Ld: Pt r nd ble) : Ptrndble;
{El l t i mo de li sta vaca consideramo s n i l}
begin
if Esvacia ( Ld ) then
Ultimo := nil
elee begin
while LdA.Sgt e<> nil do
Ld := LdA. Sgte ;
Ultimo := Ld
end
end;
Cada vez que se realiza la insercin de un nodo con el campo de informacin x, hay
que reservar memoria para dicho nodo. La operacin crear realiza esta operacin.
P ~ . Sgte : = N;
N~ . Ante r: = P
end
end;
nil
nil .. .
L ni I
r-----------,
I I
I
nil ni I
I
I I
L ___________ .J
,
procedure Suprime (X: Tipoinfo; var Ld: Ptrndble);
var
P: Ptrndble;
begin
P := Localiza (X, Ld);
if P<> nil then
Suprimedir (P, Ld)
else
Msge ('No est')
end;
Anula (Ld)
Esta operacin libera la memoria ocupada por todos los nodos de la lista Ld. El estado
final de la lista Ld es vaca.
Una de las formas de realizar esta operacin es suprimir nodos desde aquel que arbi-
trariamente consideramos ltimo hasta el apuntado por Ld. Se fundamenta en las opera-
ciones de Ultimo y Suprimedir.
procedure Anula (var Ld: Ptrndble);
var
P: Ptrndble;
begin
while Ld < > nil do
begin
P := Ultimo(Ld);
,
I
186 Estructura de datos
Suprimedir(P,Ld) ; ,
end
end;
visualiza (Ld)
Esta operacin muestra el contenido de la lista en cualquier momento de manejo de la
mIsma.
procedure Visualiza (Ld: Ptrndble);
begin
while Ld<> nil do
begin
Escribir (LdA. Info) ;
Ld := LdA.Sgte
end
end;
Anlisis
La representacin grfica de las dos listas a crear:
Mdico Referencia Asegurado Referencia
Amador 6 1 Luis M 5 ,
Castro 9 2 Marta B ,l
3 Mertoli 7 ,I
<
4 Tonino l
5 Rufis A 3 1
6 Rios e
j
7 Fausto F
8
nil
8 Slisa N 3
9 Doroteo
---~---- .
- - - --.
- - - --.
Los tipos de datos y operaciones con lista doble de asegurados en la unidad Lis tA sg.
Unidad ListAseg
unit Lis t Aseg ;
interface
type
Ca dn a30 =st ri ng[30] ;
Cadna1 1 =st ri ng [1 1 ] ;
PtrAs= ~NodoAs ;
NodoAs= record
No mbre :Cadna 30 ;
I dt : Cadna11;
S_ asg : Pt r As; {Referenc i a a si guien te asegurado de u n mismo md i co}
Anter , Sgte : PtrAs
end;
{Oper aciones}
procedure Li stavacia (var Ld : PtrAs) ;
function Esva cia ( Ld: Pt r As ) : boole an;
function Localiza (x : Cadnall ; Ld:Pt r As) : PtrA s ;
function Ex i ste (P : PtrAs ; Ld : PtrAs) : boolean;
function Ult i mo (Ld : PtrAs) : PtrAs ;
procedure I nse rta (Nm: Cadna 30; I d : Cadnall ; P :P trAs ;var Ld : Pt rA s) ;
procedure In se rtad (Nm: Cadn a3 0 ; Id : Ca dnal1 ;P: PtrAs ;var Ld :Ptr As) ;
procedure Insertafi n (Nm:Cad n a 30 ; Id : Cadna l 1 ;var Ld :P trAs) ;
procedure Sup r ime (I d: Cadnall ; var Ld : Pt r As) ;
procedure Su pr emedir(P : PtrAs ; var Ld: Pt r As) ;
procedure Vis uali z a (Ld : Ptr As);
implementation
uses crt;
188 Estructura de datos
var
A :P tr As ;
begin
A:= Cre a r (Nm, Id);
if Es vacia (Ld) then
Ld : =A i
el se if p=Ld then {D e l ante del pri mer n odo}
begin
AA . Sg te:=P;
p A. An t e r:= A ;
Ld : =A
end
else if Ex ist e (P , Ld) then
begin {Aho ra e s cuando se enlaza e l n uevo nodo e n tre e l n o d o
ante r i or y el nodo P}
pA . An t erA.Sgte:=A;
AA.Anter:=pA.An ter ;
AA. S gte:=P;
p A.Anter:=A
end
end;
procedure I nse rtad (Nm : Cad n a30 ;I d : Cadn a ll;p: Pt rA s; var Ld :P t rAs ) ;
{Aa d ir nodo c on el campo X a con t i nua cin de l nod o P e n l a l is ta}
var
N : Pt r As ;
begin
if Es v a c i a ( Ld ) then
Ld : =Cr ear(Nm, I d )
else if P = Ultim o( Ld ) then
In se rtafin(Nm,Id,Ld )
else if Existe(P,L d) then
begin {Ahora es cua n do se enl aza el n ue v o nodo, a co n ti nuacin
d el n odo P}
N: =C r ea r (Nm, I d ) ;
pA . Sg t eA . An ter : =N ;
NA. Sg t e :=p A. Sgte ;
p A. Sgte :=N;
NA. An te r:=P
end
end;
{Borrado de n odos}
procedure Sup r ime(Id:Cadna l l ; var Ld: Pt r As) ;
var
P : PtrAs ;
begin
P : =Loca liza(I d , Ld) ;
if P<> nil then
Sup rimedir ( P , Ld)
el se
wri teln ( ' Error en la l lamada .' )
end;
procedure Su p r imedir ( P :PtrAs; var Ld : PtrAs) ;
begin
if Ex i ste (P , Ld) then
begin
if p=Ld then (Primer nodo)
begin
Ld:=LdA.Sg te ;
LdA.Anter: =nil
end
else if P<>Ultimo(Ld) then
begin
pA . An t e r A. Sgte : = p A. Sgte;
p A. Sg t e A. Anter := pA . Anter
end
el Be
p A. Ant erA . Sgte := nil;
dispose(P)
end
end;
Los tipos de datos y operaciones bsicas para formar una lista doble ordenada las
representamos en la unidad Li s tM e d.
Unidad ListMed
unit Li stMe d;
interface
Listas doblemente enlazadas 191
ueee ListAseg;
type
Cadna30=string[30] ;
Cadnall=string[ll] ;
PtrMd=ANodoMd;
NodoMd=record
Nombre:Cadna30;
Fono:Cadnall;{telfono}
L_asg:PtrAs;
Anter,Sgte:PtrMd
end;
end;
begin
NA.Sgte:=L;LA.Anter:=N;
L:=N
end
, elee begin {Aadido a partir de A}
,
NA.Sgte:=AA.Sgte; NA.Anter:=A;
if AA.Sgte<>nil then
AA.SgteA.Anter:=N;
AA.Sgte:=N
end
end
end;
!
La primera accin para crear esta superestructura es dar entrada a los datos de los
mdicos y dar de alta los asegurados del ambulatorio. Por ltimo, asignar (se hace
aleatoriamente) cada asegurado a un mdico, y formar la lista virtual de asegurados de
un mdico.
Realmente hay dos nicas listas, mdicos y asegurados. A nivel lgico se forma una
lista por cada mdico para ello se utiliza el campo S_ asg con el que va enlazando los
asegurados del mismo mdico.
Los nombres de los mdicos y sus nmeros de fono se encuentran en el archivo de
texto Me d i e o s . t x t; al igual que los nombres de las personas adscritas al ambulatorio
que estn en el archivo As e gurad . t x t.
Una vez formada toda esta superestructura pueden plantearse otros problemas, como,
por ejemplo, dado un mdico listar sus asegurados; otra operacin, dado un asegurado
mostrar el doctor que le pertenece, y otras ms que podemos pensar de utilidad. En el
programa se realiza la operacin de listar todos los asegurados que tiene un mdico.
program Ambu l at o r io ;
uses ListAseg,ListM e d, Crt;
var
Lme d , Md : PtrMd ;
Las g : PtrMd ;
Fme d , Fasg : T e x t ;
Nb : Cadna3 0 ;
Ch : char ;
Listas doblemente enlazadas 193
procedure Medicos(var Lm:PtrMd);
,
var
,
Nm:Cadna30;F:Cadnall; ,
J:integer;
\
begin
!
Lm:=nil;
\,
repeat i
readln(Fmed,Nm) ;
readln(Fmed,F) ;
Inserdorden(Nm,F,Lm) ;
until eof(Fmed);
end;
K:=K - l
end;
Posicion:=L
end; ,
,
procedure Asocia(Asg:ptrAs;Lm:PtrMd); I
var
C : integer ;
M:PtrMd;
function Cuantos(L:PtrMd) :integer;
var K:integer;
begin
K:=O;
while L<> nil do
begin
L:=L A.Sgte;
K:=K+l
end;
Cuantos := K
end
,
194 Estructura de datos
begin
randomize;
C:=Cuantos (Lm);if C=O then Asg:=nil; {Para no entrar en el bucle}
while Asg<>nil do
begin
M:=posicion(Lm, random(C)+l);
write(AsgA.Nombre) ;gotoxy(31,wherey);
write( 'tiene asignado al doctor');
writeln(MA.Nombre) ;
{Enlazamos en la lista de asegurados, como el primero de ella}
AsgA.S_asg:=MA.L_asg;
MA.L_asg:=Asg;
Asg:=AsgA.Sgte
end
end;
procedure VerAseg(M:PtrMd);
var A:PtrAs;
begin
{Recorre, visualizando por pantalla, los asegurados de un mdico}
A:=MA.L_asg;
while A<>nil do
begin
write(AA.Nombre) ;gotoxy(31,whereY) ;writeln(AA.Idt);
A:=AA.S_ asg ;
end
end;
Le
4
primero ni ltimo.
Una lista circular, por su naturaleza no tiene primero ni ltimo nodo. Sin embargo,
resulta til establecer un primer y un ltimo nodo. Una convencin es la de considerar
que el puntero externo de la lista circular referencia al ltimo nodo, y que el nodo si-
guiente sea el primer nodo. Todos los recorridos de la lista circular se hacen tomando
como referencia el considerado ltimo.
Sobre una lista circular pueden especificarse una serie de operaciones, y as formar
el T A D lista circular. Estas operaciones coinciden con las definidas en los T AD lista y
lista doblemente enlazada
,.
,
196 Estructura de datos
,
6.5. IMPLEMENTACION
, DE UNA LISTA CIRCULAR MEDIANTE
VARIABLES DINAMICAS
En esta implementacin con punteros, hay un puntero externo Le que referencia al que
arbitrariamente se considera ltimo nodo de la lista. Esta realizacin de lista circular a
su vez es simplemente enlazada, por lo que el sentido de recorrido siempre es el mismo.
Puede hacerse con dos enlaces y as podra recorrerse en ambos sentidos.
type
Tipoinfo - ... ;
Ptrnlc = ANodolc
Nodolc = record
Info: Tipoinfo;
Sgte,
Anter: Ptrnlc
end;
Primero (Le)
function Primero(Lc: Ptrnlc): Ptrnlc;
begin
if not Esvacia(Lc) then
Primero := LcA.Sgte
elee
Primero := nil {Consideracin arbitraria}
end;
Ultimo(Le)
function Ultimo(Lc: Ptrnlc) : Ptrnlc;
begin
Ultimo := Lc
end;
Anterior(P, Le)
function Anterior (P: Ptrnlc; Lc: Ptrnlc) : Ptrnlc;
{Consideramos que el anterior de lista vaca y de direccin no
existente de la lista: nil}
var
A: Ptrnlc;
begin
if Esvacia (Lc) or (P= nil) then
Anterior:= nil
elee begin
A:= Lc;
while (AA.Sgte < > P) and (AA.Sgte < > Lc) do
A :=AA.Sgte;
"'- -- -- - - _._ _ -- --
.. . - -- - -- ------ _ . _ - - - -- --
if AA.Sgte= P then
An te ri o r:= A
elBe
An te rior:= ni l
end
end;
Loealiza(X, Le)
Al igual que ocurre con listas doblemente enlazadas, una versin de Localiza es
la operacin Ex i s te. Es planteada de tal forma que busca la existencia de un nodo,
dada su direccin en una lista circular.
Existe(P, Le)
function Existe ( P: Pt r n l e ; Le: Pt rnl e) : b oo l ean ;
var
T: Ptrnl e ;
begin
if not Es v a e ia(L e ) and ( P < > nil) then
begin
T:= Le ;
while (Le < > P ) and ( Le A. Sgte < > T) do
Le := LeA.Sgte;
Ex i s te := Le = P
end
elBe
Ms ge ( 'Error en ll a ma d a' )
end;
f-
A Al aadir un nuevo nodo: Le A B
~ ~
Inserprim(X, Le)
Aade un nodo con campo de informacin X como nodo que est a continuacin del
considerado el ltimo, Lc. En el caso de que la lista est vaca, crea la lista con dicho
nodo.
Procedure Inserprim(X:Tipoinfo; var Le: Ptrnle);
var
N: Ptrnle;
begin
N := Crear(X);
if Esvaeia(Le) then
Le := N
elae begin
NA.Sgte := LeA.Sgte;
LeA.Sgte := N
end
end;
Inserfin(X, Le)
Aade un nodo con el campo X como ltimo nodo de la lista L c. De estar vaca crea la
lista con dicho nodo. En cualquier caso, esta operacin siempre devuelve la direccin
del nuevo nodo: el ltimo.
200 Estructura de datos
Esta implementacin de listas circulares con nodos que tienen dos punteros, permiten
recorrer la lista circular en sentido del avance del reloj, o bien en sentido contrario. Los
tipos de datos para realizar una lista circular con doble enlace son:
type
Tip oin f o - string;
PtrDne - ANodoDe;
NodoDe = record
Inf o : Tipo inf o ;
Sgte , Anter : PtrDnc
end;
Las operaciones de insercin tienen que contemplar el doble enlace para forlllar la
lista circular. Lo mismo a la hora de suprimir un nodo de la lista. La operacin de reco-
rrer la lista se puede hacer en dos direcciones o bien con el puntero sgte o bien con el
puntero An ter. A continuacin se escribe el procedimiento que recorre la lista hacia
adelante:
.. ..
rt t
a)
Cabecera --,
b)
Figura 6.1. Lista circular doblemente enlazada con un nodo cabecera.
Listas doblemente enlazadas 201
procedure Recorre_D(Ldc:PtrDnc);
var D:PtrDnc;
begin
if not Esvacia (Ldc) then
begin
D: =Ldc;
repeat
Escribir(D A.lnfo) ;
D:=D A.Anter
until D=Ldc
end
end;
Dos cadenas de caracteres estn almacenadas en dos listas circulares. Se accede a di-
chas listas mediante los punteros Le 1, Le 2. Escribir un subprograma que devuelva la
direccin en la cadena Le 2 a partir de la cual se encuentra la cadena Lelo
Solucin
En primer lugar, se escribe una unidad que defina los tipos de datos necesarios y la
funcin que resuelve el supuesto planteado. A esta unidad se la puede aadir otros pro-
cedimientos o funciones para crear listas circulares, visualizarlas ...
unit Lista_ci
interface
type
Tinfo = ehar;
,"
,
,
Ptrlc = ANodolc;
Nodolc= record
Info : Tinfo;
Sgte : Ptrle
endl
function Direccion(L c l, Le2:Ptrlc): Ptrle;
implementation
function Direeeion(Lel, Le2:Ptrlc): Ptrle;
var
A, A2, B: Ptrle; Sw:boolean;
bel1in
A := Lc2;
A2:= Le2;
B := Lel;
repeat
if AA.lnfo = BA.lnfo then
begin
A := AA.Sgte;Sw:=true; I
B := BA.Sgte
end
elee
bel1in
A2 :=A2 A .Sgte;A:=A2;
B := Lcl; Sw:=false
end
until (A = Lc 2 ) or (B=Lcl)and Sw;
if (B=Lel and Sw) then
Direeeion:= A2
elee
Direecion := nil
end;
end.
,
1
i"
,l
,
RESUMEN ,
l
1
1
,,
Las listas doblemente enlazadas son aquel tipo de lista que se puede recorrer avanzando en cual- ,
EJERCICIOS
6.1. Dibujar una lista doblemente enlazada, Ld, de nombres de personas con un nodo cabecera.
Escribir el procedimiento Lista_vaca que inicializa Ld como vaca.
6.2. Escribir la funcin Esvae ia que devuelve cierto si la lista Ld con nodo de encabezamien-
,
to es vaCla.
6.3. Dada la lista doble con nodo de encabezamiento Ld, escribir el procedimiento de insertar
un nodo antes del nodo de direccin P.
6.4. En la lista doble con nodo de encabezamiento borrar el nodo que tiene como campo de
informacin X.
6.S. Dada una lista doble sin nodo de encabezamiento cuya direccin de acceso Ld es el primer
nodo, la infoJlnacin de cada nodo es una cadena de caracteres; escribir un procedimiento
para visitar los nodos del primero (Ld) al ltimo, convirtiendo las cadenas a maysculas; a
continuacin visite los nodos del ltimo al primero (Ld) mostrando los nodos por pantalla.
6.6. Escribir un procedimiento que tenga como parmetro de entrada Le. Suponer que Le apun-
ta al primer nodo de una lista circular doblemente enlazada de caracteres. El procedi-
miento debe de escribir los caracteres de la lista Le en orden inverso, es decir, del ltimo al
pnmero.
c
La salida debe ser: R T J H
6.7. Hacer lo mismo que en el ejercicio 6.6 pero con una lista simplemente enlazada.
6.8. Dibujar una lista circular doblemente enlazada con nodo de cabecera. El nodo de cabecera
es tal que sus dos campos puntero referencian a los nodos extremos de la lista.
i
6.9. Dada la representacin de lista circular propuesta en 6.8, escribir las operaciones Lista_vaca
y la funcin Esvaca.
,"
,
,f 6.10. Con la representacin de lista circular de 6.8, escribir las operaciones de insertar como
,,! ltimo nodo e insertar como primer nodo.
6.11. Con la representacin de lista circular de 6.8, escribir la funcin de localizar el nodo con el
,
campo de informacin X y la operacin de eliminar el nodo con campo de informacin X.
PROBLEMAS
6.1. Dada una lista doblemente enlazada de nmeros enteros, escribir las rutinas necesarias para
que dicha lista est ordenada en orden creciente. La ordenacin se ha de hacer intercam-
biando los punteros a los nodos.
6.2. Tenemos una lista doblemente enlazada ordenada con claves repetidas. Realizar un proce-
dimiento de inserccin de una clave en la lista, de tal forma que si la clave ya se encuentra
en la lista la inserte al final de todas las que tienen la misma clave.
6.3. En una lista simplemente enlazada L se encuentran nombres de personas ordenados alfab-
ticamente. A partir de dicha lista L crear una lista doblemente enlazada LL de tal forma que
el puntero de comienzo de la lista est apuntando a la posicin central. Damos por supuesto
que la posicin central es el nodo que ocupa la posicin n/2, siendo n el nmero de nodos
de la lista. Obviamente, los nodos que se encuentran a la derecha de la posicin central
estn ordenados ascendentemente y los que se encuentran a la izquierda ordenados de ma-
nera decrecientemente.
Listas doblemente enlazadas 205
6.4. Dada una cadena de caracteres almacenada en una lista circular Le, escribir un subprogra-
ma que transforme la cadena Le de tal forma que no haya caracteres repetidos.
6.5. En el archivo LIBROS se encuentran almacenados los datos relativos a la biblitoeca
municipal de Lupiana. Los campos de que consta cada registro son: Autor, Ttulo, N-
mero de ejemplares. Escribir un programa que realice como primera accin formar una
lista doblemente enlazada ordenada respecto al campo Autor, cuya direccin de acceso
sea el nodo que ocupe la posicin central. Con la lista se podrn realizar estas otras opera-
ClOnes:
6.6. Escribir un programa para realizar operaciones con vectores dispersos. Un vector disperso
es aquel cuyo nmero de elementos es grande, sin embargo muchos de esos elementos son
cero. La representacin se ha de hacer mediante una lista doblemente enlazada. Cada nodo
de la lista ha de tener un elemento del vector distinto de cero junto al ndice del elemento.
El programa debe de permitir estas operaciones:
6.7. El polinomio P(x) = ao + a IX + a2x2 +... + a,.x" deseamos representarlo en una lista circular
enlazada, de tal forma que cada nodo contenga el coeficiente y el grado de un monomio.
Escribir un programa que tenga como entrada los coeficientes y exponentes de cada trmi-
no de un polinomio, y forme una lista circular para representarlo. El puntero de acceso a la
lista circular ser el del nodo que contiene al tllnino de grado n, a partir de l se acceder
al tllnino de grado 0, y as sucesivamente. En el programa deben de encontrarse las opera-
ClOnes:
pi a
CONTENIDO
,!
eliminaciones de elementos se realizan por un extremo denominado
cima de la pila. Una analoga es una pila de platos o una pila de cajas.
La implementacin de una pila se puede realizar mediante arrays o
con punteros. El inconveniente de la implementacin de una pila con
un array es que su tamao mximo se debe especificar en tiempo de
compilacin. Para resolver este inconveniente, la implementacin de
una pila se ha de realizar con punteros (apuntadores).
El desarrollo de las pilas como tipos abstractos de datos es tam-
bin otro de los motivos centrales de este captulo. En el mismo se
ver cmo utilizar el TAD Pila para resolver problemas de diferentes
tipos.
,
7.1. ESPECIFICACION FORMAL DEL TIPO ABSTRACTO
DE DATOS PILA
Una pila es una lista ordenada de elementos en la que todas las inserciones y supresio-
nes se realizan por un mismo extremo de la lista. En una pila el ltimo elemento aadido
es el primero en salir de la pila. Por esa razn a las pilas, se las denomina tambin listas
207
208 Estructura de datos
Lifo (Last input jirst output, ltimo en entrar, primero en salir). En la mente se tiene la
imagen intuitiva de una pila. As, si nos referimos a una pila de platos, sabemos que los
platos se toman por arriba, por la cabeza. En la vida cotidiana se encuentran infini-
dad de ejemplos; as a veces se dice que apilamos los libros de un curso ...
Pila
superior de la pila, cima, estar cambiando dinmicamente durante la ejecucin del pro-
grama. Adems del array, una variable entera nos sirve para tener en todo momento el
ndice del array que contiene el elemento cima. Las declaraciones, procedimientos y
funciones para representar el TAD pila forman parte de la unidad pilas.
const
Maxelems = 100; {Depender de cada realizacin}
type
Indicepila = O.. Maxelems;
Tipoelemen = ... {Tipo de los elementos de la pila}
Tipopila = record
Elementos: array[l .. Maxelemsl of Tipoelemen;
Cab: Indicepila
end;
Pilavacia(P)
Esvacia(P)
Cima(P)
Suprime(p)
Sacar(X, P)
Meter(X, P)
1
,
Se desea invertir una cadena de caracteres y se trata de determinar si han sido inverti-
dos correctamente dichos caracteres. Para ello se lee la cadena de caracteres; a conti-
nuacin, en la siguiente lnea los caracteres de la cadena invertidos.
pila: ltimo en entrar primero en salir. El ltimo carcter introducido debe ser igual que
el primer carcter de la cadena invertida.
Para sacar los elementos de la pila se puede seguir la alternativa de utilizar otra va-
riable carcter D y la operacin Sacar:
while not Esvacia(Pila) and Inv do
begin
read(Ch) ;
Sacar(D,Pila)
Inv:= Ch = D;
end;
Pila
Los tipos de datos y operaciones en la realizacin con listas son muy similares a los
ya expuestos en listas enlazadas Pilavacia , Esvacia , Cima, Suprime , Sacar y Meter.
type
Ti poelemen= ... {Tipo d e los el emen tos de l a p i l a}
ptrp l a= ANo doPla;
Nodopla= record
Elemen t o : T i poeleme n;
Enl a ce : PtrP l a
, end;
I Pilavacia(crear pila)
Pi l a := n il
end;
Esvacia
Cima(Pila)
Suprime (Pila)
"'"
Pila
,
I
Sacar(X, pila)
Esta operacin engloba a las dos anteriores. Devuelve el elemento cabeza y lo su-
prime.
I
procedure Sacar( var X: Tipoe l eme n; var Pila : Ptrpla) ;
var
Q : P t rp la ;
I
214 Estructura de datos
begin
if not Esvacia(Pila) then
with pila A do
begin
Q:= Pila;
X:= Elemento;
pila:= Enlace;
dispose(Q)
end
end;
Meter(X, Pila)
----,
-- --
- --
--- -
Pila
nil
Una de las aplicaciones ms tpicas del TAD pila es almacenar los caracteres de que
consta una expresin aritmtica con el fin de evaluar el valor numrico de dicha expre-
sin, Una expresin aritmtica est formada por operandos y operadores, As, la ex-
, ,
preslOn
R = X*Y - (A+B)
est escrita de la forma habitual: el operador en medio de los operando, Se conoce como
notacin infija, Conviene recordar que las operaciones tienen distintos niveles de prece-
dencia,
Par n t esis
() nivel mayor de prioridad
1\
Po t enc ia
Multip l / di v isi n : *, /
Suma / Resta
+, - nivel menor de prioridad
Representan distintas expresiones al no poner parntesis. Igual ocurre con las expre-
Slones:
l
,
..
216 Estructura de datos
Otra forma de escribir las operaciones es mediante la notacin postfija o polaca in-
versa que coloca el operador a continuacin de sus dos operandos.
/
(
-
(
*
El nuevo estado de la pila es
-
(
*
y la expresin
ABC+DEFAj
ABC+DEFAj- Carcter - a la pila y se extrae a su vez -;
ABC+DEFAj-G Carcter G a la expresin; carcter ), son extrados
de la pila los operadores hasta un ( la pila queda *
ABC+DEFAj-G-* Carcter -, se saca de la pila * y se mete -
ABC+DEFAj-G-*H Carcter H se lleva a la expresin
Fin de entrada, se vaca la pila:
ABC+DEFAj-G-*H-
!Operador
/\
3 4
*, I 2 2
+, - 1 1 ,
( O 5
,
,
,
I
Obsrvese que no se trata el parntesis derecho ya que ste provoca sacar operadores 1
de la pila hasta el parntesis izquierdo. El algoritmo de paso de notacin infija a postfija: I,
,,l
l. Obtener caracteres de la expresin y repetir los pasos 2 al 4 para cada carcter.
I,
, , ,
7.5. APLlCACION PRACTICA
, DE LA
, EVALUACION I,
J
DE UNA EXPRESION ARITMETICA :
,I
,
,,
,
,
,
operaciones asociadas.
unit pilaop;
interface
type
Plaopr = ANodopr;
Nodopr= record
Pilas:elTADPila 219
Info: char;
Sgte: Plaopr
end;
implementation
dispose(A)
end;
end;
end.
1,I
,,
j
222 Estructura de datos I
,!
I
Psacar(It, P); j
un ti l I t = ' ( , ; 1
.~
end;
end;
repeat
Psacar(It, P);
J:= J+l;
Ar [J] . e : = 1 t ;
Ar[J] .oprdor:= true;
until Pvacia(P); l,
end; {del procedure} iI
end.
.,i
j
,
7.5.3. Evaluacin de la expresin en postfija ,.:
,,
En un vector ha sido almacenada la expresin aritmtica en notacin postfija. Los ope-
randos estn representados por variables de una sola letra. La primera accin que va a
ser realizada es dar valores numricos a los operandos.
Una vez que tenemos los valores de los operandos la expresin es evaluada. El algo-
ritmo de evaluacin utiliza una pila de operandos, en definitiva de nmeros reales. Al
describir el algoritmo P f es el vector que contiene la expresin. El nmero de elementos
de que consta la expresin es n.
unit Pilaopdos;
interface
type
Plaopdos = ANodopdos;
Nodopdos=record
Info: real;
Sgte: Plaopdos
end;
Pilas:elTADPila 223
program Evalua_Expresion;
uses
ert, ExpPost, Pilaopdos;
var
v: Oprdos;
T: Tag;
1, J:integer;
Valor: real;
procedure Leer_oprdos(E:Tag;N:integer; var V: Oprdos);
{En este procedimiento se asignan valores numricos a los operandos}
var
K: integer;
eh: char;
begin
K:= O;
repeat
K:= K+l;
if not E[K] .Oprdor then {Es un operando, peticin de su valor
numrico}
begin
Ch:= E[K] .e;
write(Ch, '- ');
readln (V[Ch])
end
until K=N
end
RESU N
Una pila es una estructura de datos tipo UFO (last-in-first-out, ltimo en entrar/primero en salir)
en la que los datos se insertan y eliminan por el mismo extremo, que se denomina cima de la pila.
El proceso de insercin se denomina meter o poner y el de eliminacin se denomina extraer,
quitar o sacar.
Aadir un elemento a una pila se llama operacin meter o poner (push) y eliminar un ele-
mento de una pila es la operacin extraer, quitar o sacar (pop).
El intento de poner un elemento en una pila llena produce un error conocido como desborda-
miento de la pila (s tack overf low). El intento de sacar un elemento de una pila vaca produ-
ce un error conocido como desbordamiento negativo de la pila (s tack underf low).
Una pila puede ser implementada mediante un array o mediante una lista enlazada. Una ven-
taja de una implementacin de una pila mediante una lista enlazada sobre un array es que, con la
lista enlazada no existe lmite previo en el nmero de elementos o entradas que se pueden aadir
a la pila.
Las llamadas a procedimientos recursivos se implementan utilizando una pila (de hecho, to- .
das las llamadas a procedimientos, sean o no recursivas, se implementan utilizando una pila).
El TAO Pi la, al igual que eITAO Lis ta y TAO Cola son, posiblemente, los tipos abstrac-
tos de datos ms utilizados en la gestin de proyectos software, dado que la estructura tipo pila es
muy frecuente en numerosos problemas de tratamiento de infolluacin, as como en problemas
matemticos, estadsticos o financieros. Por ejemplo, se puede utilizar una pila para determinar si
Pilas: el TAO pila 225
una secuencia de vuelos existe entre dos ciudades. La pila mantiene la secuencia de ciudades
visitadas y permite a un algoritmo de bsqueda volver hacia atrs. Para ello se sita la ciudad
origen en la parte inferior de la pila, y la ciudad destino en la parte superior, con lo que las suce-
sivas ciudades de trnsito se van colocando en la secuencia correcta.
EJERCICIOS
7.1. Se desea implementar el TAD pila de tal forma que los elementos de la pila sean almacena-
dos en una lista circular. El puntero externo a la lista apunta al elemento cabeza. Escribir
las operaciones de meter, cima, suprimir y esvacia.
7.2. Supongamos que estarnos trabajando en un lenguaje de programacin que no tiene el tipo
de dato puntero. Se plantea la resolucin de un problema utilizando dos pilas de nmeros
reales. Las dos pilas se quiere guardar en un nico array, de tal forma que crecen en sentido
contrario, una de ellas crece desde la posicin l del array y la otra desde la ltima posicin
del array. Escribir la estrategia a seguir para esta representacin, variables necesarias para
contener la posicin del elemento cabeza de ambas pilas.
7.3. Dada la representacin de dos pilas propuesta en 7.2, escribir el algoritmo de la operacin
Crea pi la (Pi lal, Pi la2) que inicializan ambas pilas corno pila vaca. De igual for-
ma escribir las funciones Esvac ial y Esvac ia2 que determinan si las respectivas pi lal
y pi la 2 estn vacas.
7.4. Completar las operaciones de las pilas propuestas en 7.2: Meterl, Meter2 y Supri-
mel, Suprime2. En las operaciones hay que tener en cuenta condiciones de error.
7.5. Utilizando una pila de caracteres, hacer un seguimiento para transformar la siguiente ex-
presin infija a su equivalente expresin en postfija.
E: (X-Y)/Z*W+(Y-Z)"V
7.6. Aplicando el algoritmo de evaluacin de una expresin, obtenga el resultado de las si-
guientes expresiones escritas en postfija .
XY+Z-YX+Z I\-
XYZ+*ZYX-+*
paraX=l, Y=3, Z =2
PROBLEMAS
7.1. Escribir un programa para determinar si frases (cadenas) son palndromos. Utilizar para
ello el TAD pila de caracteres realizado en una unidad. La entrada de datos son las frases y
la salida la propia frase junto a la etiqueta ES PALNDROMO, o bien NO ES PALN -
DRoMo .
. 7.2. Escribir un programa que convierta expresiones escritas en notacin infija (forma habitual)
a notacin postfija. Cada expresin se encuentra en una lnea, el programa ha de terminar
cuando la lnea conste de 3 asteriscos.
7.3. Escribir un programa que convierta expresiones escritas en notacin postfija a notacin
infija. Cada expresin se encuentra en una lnea, el programa ha de terminar cuando la lnea
conste de 3 asteriscos.
226 Estructura de datos
7.4. Escribir un programa que convierta expresiones escritas en notacin postfija a notacin
prefija. Cada expresin se encuentra en una lnea, el programa ha de terminar cuando la
lnea conste de 3 asteriscos.
7.5. Un mapa de carreteras podemos representarlo mediante la matriz simtrica MM de N x N
elementos enteros, donde los valores 1 a N representan los pueblos/ciudades que aparecen
en el mapa.
Los elementos de la matriz son tales que MM(i,j) = O si no hay conexin directa entre el
pueblo i y el pueblo j. MM(i,j) = d si hay conexin directa entre el pueblo i y el pueblo j, y
su distancia es d.
Con esta representacin del mapa queremos escribir un programa que simule el mapa des-
crito y que tenga como entrada dos pueblos (origen, destino) entre los que no hay conexin
directa; decida si hay un camino que pase por los pueblos del mapa y determine la distancia
de ese camino. Utilizar una pila para ir almacenando los pueblos que van formando el ca-
mino recorrido y poder volver atrs si se alcanza un pueblo desde el que no se puede prose-
guir la ruta, y probar con otra ruta.
7.6. Utilizando nicamente las operaciones bsicas sobre pilas: Met er, Cima, Supr ime y
Esvacia, construir las operaciones que realicen las siguientes acciones:
a) Asignar a X el segundo elemento desde la parte superior de la pila, dejando la pila sin
sus dos elementos de la parte superior.
b) Asignar a X el segundo elemento desde la parte superior de la pila, sin modificarla.
e) Dado un entero positivo n, asignar aX el n-simo elemento desde la parte superior de la
pila, dejando la pila sin sus n elementos de la parte superior.
d) Dado un entero positivo n, asignar aX el n-simo elemento desde la parte superior de la
pila, sin modificarla.
e) Asignar a X el elemento fondo de la pila, dejando la pila vaca.
j) Asignar a X el elemento fondo de la pila, sin modificarla. 1
1
7.7. Utilizando las operaciones del TAD pila, escribir una operacin de copia, tal que devuelva 1,,
,,
la copia de una pila. I
7.8. Escribir una funcin para determinar si una secuencia de caracteres de entrada es de la I
fOllna: ,;,
X & Y
Donde X es una cadena de caracteres, e Y es la cadena inversa, siendo & el carcter sepa-
rador.
7.9. Escribir una funcin para determinar si una secuencia de caracteres de entrada es de la
forma:
A#B#C# ...
Donde cada una de las cadenas A, B, e ... son de la forma X & Y, que a su vez estarn
separadas por el carcter #.
,
CAPITULO
..,,0 as CO as e rlO
e CO a
.' ,
,', '" ..
,': ,. .. , ' , .... . ' ' . . '
CONTENIDO
227
228 Estructura de datos
,
8.1. ESPECIFICACION FORMAL DEL TIPO ABSTRACTO
DE DATOS COLA
Una cola es una lista ordenada de elementos, en la cual las eliminaciones se realizan en
un solo extremo, llamado frente o principio de la cola, y los nuevos elementos son aa-
didos por el otro extremo, llamado fondo o jinal de la cola. La Figura 8.1 muestra una
estructura cola en una organizacin original (a) y sus modificaciones (b y e) despus de
eliminar y aadir un elemento de modo sucesivo.
En esta estructura de datos el primer elemento que entra es el primero en salir. Por
esta causa a las colas tambin se les llama listas FIFO (jirst input jirst output). Las
operaciones bsicas que definen la especificacin del TAD cola son:
a) Estructura original
AGHK
frente final
GHK
frente final
GHKL
frente final
Al igual que las pilas, la implementacin de colas puede hacerse utilizando como
depsito de los elementos un array o bien una lista enlazada y dos punteros a los
extremos.
Un array es una estructura esttica y por tanto tiene dimensin finita; por el contra-
rio, una cola puede crecer y crecer sin lmite, y en consecuencia se puede presentar la
posibilidad de que se presente un desbordamiento. Por esa razn dentro de las operacio-
nes de este TAD se incorpora, normalmente, la operacin de verificacin de que la cola
est llena.
La operacin de aadir un nuevo elemento en la cola comienza a partir de la posicin
1 del array
1 234
AGHK
t t
frente final
123 4
Una alternativa a esta situacin es mantener fijo el frente de la cola al comienzo del
array; este hecho supone mover todos los elementos de la cola una posicin cada vez
que se quiera retirar un elemento de la cola.
Estos problemas quedan resueltos con los arrays circulares que se describen ms
adelante. Las operaciones ms importantes incluidas en la especificacin de una cola
con esta representacin son: Crear, Cola Vacia, ColaLlena , A adir y Quitar.
Crear (Qcrear(Q
La operacin Qcrear inicializa la cola como cola vaca.
procedure Qc r ear( var Q : Co l a) ;
begin
Q.Frente := 1;
Q.Fina l := O;
end;
Aadir (Qponer(X,Q
Aade el elemento X a la cola. Se modifica la cola por el extremo final.
procedure Qponer(X : T i poe l e me n; var Q: Co l a) ;
begin
if not Ql l e na(Q) then
with Q do
begin
Final:= Final+ 1 ;
Dat os [Final]: = X
end
end;
Quitar (Quitar(X,Q
Elimina y devuelve el frente de la cola.
procedure Qu i tar( var x : T i poe l emen ; var Q: Cola) ;
procedure Desplazar ;
var l: posi cion ;
Colas y colas de prioridades: el TAO cola 231
begin
for I :~l to Q . F i nal - l do
Q . Da t o s [ 1 J : ~ Q . Da t o s [ 1 + 1 J
end;
begin
X: = Q .Datos[F rent e l ;
Despl azar
end;
,
8.3. IMPLEMENTACION DEL TAD COLA CON ARRAYS
CIRCULARES
La implementacin de colas mediante un array lineal es poco eficiente. Cada operacin
de supresin de un elemento supone mover todos los elementos restantes de la cola.
Para evitar este gasto, imagnese un array como una estructura circular en la que al
ltimo elemento le sigue el primero. Esta representacin implica que aun estando ocupa- '
do el ltimo elemento del array, pueda aadirse uno nuevo detrs de l, ocupando la
primera posicin del array.
Para aadir un elemento a la cola, se mueve el ndice final una posicin en el sentido de
las manecillas del reloj, y se asigna el elemento. Para suprimir un elemento es suficiente
con mover el ndice frente una posicin en el sentido del avance de las manecillas del
reloj. De esta manera, la cola se mueve en un mismo sentido, tanto si se realizan inser-
ciones como supresiones de elementos.
Segn se puede observar en la representacin, la condicin de cola vaca [fren-
te = siguiente (final)] va a coincidir con una cola que ocupa el crculo completo, una
cola que llene todo el array.
Para resolver el problema, una primera tentativa sera considerar que el elemento
final referencie a una posicin adelantada a la que realmente ocupa el elemento, en el
sentido del avance del reloj.
n 1 2
4 ,
Final/"
~Frente
---
" - -,
~*-
_o,
::...-
0_. _
I~-------vr--------~I
i ~Frente
Cola
Final-----n~'{...2
n 1
p S B p 2....--Final
3
A
4
'Frente
T
i ~Frente
Figura 8.3. Evolucin de arrays circulares.
Teniendo presente esta consideracin cuando la cola estuviera llena, el ndice si-
guiente a final ser igual al frente.
Consideremos ahora el caso en que queda un solo elemento en la cola. Si en estas
condiciones se suprime el elemento, la cola queda vaca, el puntero Frente avanza una
posicin en el sentido de las manecillas del reloj y va a referenciar a la misma posicin
que el siguiente al puntero Final. Es decir, est exactamente en la misma posicin rela-
tiva que ocupara si la cola estuviera llena.
Una solucin a este problema es sacrificar un elemento del array y dejar que Final
referencie a la posicin realmente ocupada por el ltimo elemento aadido. Si el array
tiene long posiciones, no se debe dejar que la cola crezca ms que long-lo
n 1 n 1
B p 2 2
/Frente
u
W 3 Final W 3
A
4
~ Frente
Las operaciones definidas en el TAD cola con esta representacin de array circular
son: Siguiente, Crear, Cola Vacia, CalaLlena, Frente, Borrar y Quitar.
Siguiente(J)
La funcin Si gu i en te ( J) obtiene la posicin siguiente a J en el sentido circular de
avance, segn las manecillas del reloj.
function Siguiente(J: integer): integer;
begin
Siguiente:= (J mod Long) +1
end;
Crear(Q)
La operacin de crear inicializa los ndices de la cola de tal manera que la condicin
de cola vaca aplicada sobre la cola creada sea cierta.
procedure Qcrear(var Q: Cola);
begin
Q.Frente:= 1;
Q.Final:= Long;
end;
,
Cola VaCl.a
Cola llena
La operacin Q 11 ena devuelve verdadero si en la cola no pueden aadirse ms ele-
mentos, es decir, si estn ocupadas Long-l posiciones del array.
234 Estructura de datos
Frente (Frente(Q
function Frente (Q : Co l a ) : Ti poe l e men;
begin
if not Qvacia (Q) then
Fr ente := Q . El e men tos [Q . F ren t e ]
end;
Borrar (Qborrar(Q
Esta operacin modifica la cola, elimina el elemento frente de la cola.
procedure Qborr ar( var Q: Co l a ) ;
begin 1
if not Qvacia (Q) then 1
l
Q . Fren te:= Q . Fr e nt e+ l
end;
i
Quitar (Quitar(X, Q 1
1
Elimina y devuelve el frente de la cola. En realidad esta operacin es un compendio de
las operaciones F rente y Qborrar.
procedure Quita r( var x: T i poeleme n; var Q : Col a );
,
,
begin
X : = F rente(Q);
Qb o rra r(Q)
end;
n ~--Final
e 2
3
-Frente
Q
4
o
p
5
6
Qponer(X, Q)
Aade el elemento X a la cola. Se modifica la cola por el extremo final.
Elementos [ Final] : = X
end
end;
,
8.4. IMPLEMENTACION DEL TAD COLA CON LISTAS
ENLAZADAS
Como ocurre con toda representacin esttica, una de las principales desventajas es que
hay que prever un mximo de elementos, de ese mximo no podemos pasamos. La rea-
lizacin de una cola mediante una lista enlazada permite ajustarse exactamente al nme-
ro de elementos de la cola.
Esta implementacin con listas enlazadas utiliza dos punteros para acceder a la lista.
El puntero Frente y el puntero Final.
Frente Final
H K M "'---1 T nil
I
El puntero Frente referencia al primer elemento que va a ser retirado. El puntero
Final referencia al ltimo nodo que fue aadido, en definitiva, al ltimo que ser retira-
do (1 i s t a F i f o). En esta representacin no tiene sentido la operacin que determina
si una cola est llena (Ql le na). Al ser una estructura dinmica crece y decrece segn
las necesidades. Las declaraciones para la representacin de cola mediante listas:
type
Tipoelemen - ... ;
Ptr n odoq = ANodoq ;
Nodoq= record
I nEo : Tipoe l eme n;
Sgte : Pt rnodoq
end;
Cola= record
Fr e n te ,
Final :Pt rnodoq
end;
,
236 Estructura de datos
Las operaciones definidas en la especificacin del tipo en esta estructura son: Crear,
Cola Vaca, Frente, Borrar, Quitar y Poner.
Crear (Qcrear(Q
La operacin Qcr ear inicializa la cola como Cola vaCa.
procedure Qcrea r(var Q : Cola) ;
begin
Q . Frente := nil ;
Q.Fina l:= nil
end;
,
Cola vac1a (Qvacia(Q) )
La operacin Qvacia devuelve verdadero si la cola no tiene elemento.
function Qva c i a(Q : Cola) : boolea n;
begin
Qvacia := Q.Fr ente= n i l
end;
Borrar (Qborrar(Q
Esta operacin modifica la cola, elimina el elemento frente de la cola y es liberado.
procedure Qb o r rar( var Q : Cola) ;
var
A : Ptrnodoq ;
begin
if not Qvac i a(Q) then
with Q do
begin
A : = F re n te ;
Frente := F renteA . Sgte ;
,,
if Frente = nil Then ,
F inal:= nil;
d i s pose(A)
end
end;
Quitar (Quitar(X,Q
Elimina y devuelve el frente de la cola.
procedure Quitar( var X : Tipoele me n; var Q : Co l a);
begin
X : = Fren t e (Q) ;
Qborrar(Q)
end;
Colas y colas de prioridades: el TAO cola 237
Poner (Qponer(X,Q
Aade el elemento X a la cola. Este elemento se aade como ltimo nodo, por lo que se
modifica la cola al cambiar Final.
type
Tipoelemen - . . . ,
Cola= ~Nodoq;
Nodoq= record
rnfo: Tipoelemen;
Sgte: Cola
end;
Las operaciones son similares a las realizadas con listas enlazadas: Crear, Cola Va-
cia, Frente, Borrar, Quitar y Poner. El puntero necesario para realizar inserciones y
supresiones es el mismo: Q. Teniendo en cuenta que Q referencia al ltimo (Final)
y Q"'. Sgte al primero (Frente).
238 Estructura de datos
Le
~
Figura 8.8. Cola implementada con una lista circular con punteros.
Crear (Crear(Q
procedure Qcrear(var Q: Cola);
begin
Q:= nil;
end;
,
Cola vaC1a (Qvacia(Q
function Qvacia(Q: Cola): boolean;
begin
Qvacia:= Q= nil
end;
Frente(Q)
function Frente(Q: Cola): Tipoelemen;
begin
if not Qvacia(Q) then
Frente:= Q.SgteA.lnfo
end;
Qborrar(Q)
procedure Qborrar(var Q: Cola);
var
A: Cola;
begin
if not Qvacia(Q) then
begin
A:= QA.Sgte;
if QA.Sgte= Q then
Q:=nil;
else
QA.Sgte:=QA.SgteA.Sgte;
dispose(A)
end
end;
Colas y colas de prioridades: el TAO cola 239
Quitar(X, Q)
I
Qponer(X, Q)
procedure Qponer(x: Tipoelemen; var Q: Co l a) ;
var
N: Col a;
begin
new(N) ;NA.Inf o : =X;NA.Sgte:=N;{Crea n o do co n campo xl
, if not Qvacia(Q) then
begin
NA. Sgte : = QA .S gte ;
QA . Sgt e: = N
end
Q : = N;
end;
8.6. BleOlAS
Una variacin del tipo de datos cola es la estructura bicola. Una bicola es un conjunto
ordinal de elementos en el cual se pueden aadir o quitar elementos de cualquier extre-
mo de la misma. Es, en realidad, una cola bidireccional.
Los dos extremos de una bicola los llamaremos Izquierdo y Derecho, respec-
tivamente. Las operaciones bsicas que definen una bicola son:
,
Cre arB q (Bq) : inicializa una bicola sin elementos.
Esvaci a (Bq) : devuelve verdadero si la bicola no tiene elementos.
Inserlzq (x, Bq ) : aade un elemento por extremo izquierdo.
InserDch (x , Bq) : aade un elemento por extremo derecho.
i Elimnlzq (x, Bq) : devuelve el elemento Izquierdo y lo tetira de la bicola.
Eli mnD ch (x , Bq) : devuelve el elemento Derecho y lo retira de la bicola.
Para representar una bicola se puede elegir una representacin esttica, con arrays, o
bien una representacin dinmica, con punteros.
En la representacin dinmica, la mejor opcin es mantener la bicola con una lista
doblemente enlazada: los dos extremos de la lista se representan con las variables punte-
ro 1 zquierdo y Derecho, respectivamente.
En la representacin esttica se mantienen los elementos de la bicola con un array
circular y dos variables ndice del extremo izquierdo y derecho, respectivamente.
Al tipo de datos bicola se pueden imponer restricciones respecto al tipo de entrada o
al tipo de salida. Una bicola con restriccin de entrada es aquella que slo permite in-
serciones por uno de los dos extremos, pero pel mite la eliminacin por los dos extremos.
Una bicola con restriccin de salida es aquella que permite inserciones por los dos ex-
tremos, pero slo permite retirar elementos por un extremo.
,
,
i,
240 Estructura de datos
Frente: 3
LUZ AGUA RIO
Final: 5
1 2 3 4 5 6 7 8
Frente: 2
SOL LUZ AGUA RIO
Final: 5
1 2 3 4 5 6 7 8
Frente: 2
SOL LUZ AGUA
Final: 4
1 2 3 4 5 6 7 8
PROBLEMA 8.1
Anlisis
El estacionamiento va a estar representado por una bicola de salida restringida. Por
qu? La salida siempre se hace por el mismo extremo, sin embargo la entrada se puede
hacer por los dos extremos, y as contemplar la llegada de una avioneta nueva, y que
tenga que entrar una avioneta que ha sido movida para que salga una intermedia. La
lnea de espera para entrada de una avioneta (estacionamiento lleno) se representa por
una bicola a la que se aaden avionetas por un extremo, salen para entrar en el estacio-
Colas y colas de prioridades: el TAO cola 241
unit Bicolas;
interface
uses Lifo;
const
Long = 13;
type
Avioneta = string [15] ;
posicion= o .. Long;
Bicola= record
Elementos: array[l .. long] of Tipoelemen;
Salida,
Entrada: posicion
end;
procedure CrearBq (var Bq: BiCola);
function Esvacia(Bq: BiCola): boolean;
function EsLLena(Bq: BiCola): boolean;
procedure InsEntrada(A:Avioneta;var Bq:Bicola);
procedure InsSalida(A:Avioneta;var Bq:Bicola);
procedure EliEntrada(var A:Avioneta;var Bq:Bicola);
procedure EliSalida(var A:Avioneta;var Bq:Bicola);
!
Colas y colas de prioridades: el TAO cola 243
I
244 Estructura de datos
servicio para trabajar. Los diseadores de estos sistemas asignan cierta prioridad a cada
proceso.
El orden en que los elementos son procesados y por tanto eliminados sigue estas
reglas:
Las colas de prioridades pueden implementarse de dos formas: mediante una nica
lista o bien mediante una lista de colas.
Para realizar la representacin, se define en primer lugar el tipo de dato que representa
un proceso.
type
Ti po_i d en tif = ... {Tipo de l i d e ntif icado r d el p r oceso}
Ti po_ proceso = record
Idt: Tipo_ i d e nt i f;
Prio ri dad : int eger
end;
Cp
41 P1 I ~ 1P21 ~I P31 r.lp21 I ~lp221 r. ... -.1 Pn I I
Figura 8.10. Cola de prioridad con una lista enlazada .
246 Estructura de datos
Los nmeros de prioridad tienen el significado habitual: a menor nmero mayor prio-
ridad. Esta realizacin presenta como principal ventaja que es inmediato determinar el
siguiente nodo a procesar: siempre ser el primero de la lista. Sin embargo, aadir un
nuevo elemento supone encontrar la posicin de insercin dentro de la lista, segn el
criterio expuesto anteriormente.
Cp
2 P2 Q2 Ip21 P2K I
n Pn Qn IPn1 PnK I
Cola = record
Numpr i dad : in teger ;
fr e n t e ,
f ina l: Pt rn o do q
end;
Tabl a_cp = array[ l .. Max_p ri orl of Co la;
El tipo Ta bl a_c p es el que define la lista de colas y cada cola representa una prio-
ridad. Las acciones ms importantes al manejar una cola de prioridades son las de aadir
un nuevo elemento, con una determinada prioridad al sistema, y la accin de retirar un
elemento para su procesamiento. Estas acciones se expresan en forma algortmica en la
realizacin de n colas, como se muestra a continuacin.
begin
new(A) ;
AA.lnfo:=X;
AA.Sgte:=nil;
if Qvacia(Q) then
Q.Frente:= A
elBe
Q.FinalA.Sgte:=A;
Q.Final:= A
end;
Nu mcola := J
elee
Numco l a := o
end;
begin
N := random( Nt) + 1 ; {Tarea al azar}
X .Ta rea : = Ta rea(N );
N := random(Max _ prio) + 1 ; {Prioridad al azar}
X. P rior:= N;
{Busca de Nmero de cola de prioridad}
N := Nu mco la(X. Pr ior);
if N= O then
begin
writeln( ' Overf l ow en tabla de colas ' ) ;
ha lt( l )
end;
Tcp[N ] . P rd : = X . Prior ;
Qponer(X , T cp[N])
writ eln( ' S E GENERA TAR EA N Q : ' , J)
end;
else begin
J:= J + 1;
generar_pr o c (Tablaq,j);
end;
repeat
pr o ce s ar_pr oc (Tablaq, Hm);
until not Hm
end.
PROBLEMA 8.2
Anlisis
Partimos de que los nmeros estn dispuestos de tal forma que hay uno por lnea. El
objetivo es obtener la suma de todos estos nmeros y mostrarlo por pantalla.
Para leer los nmeros, los hacemos dgito a dgito (como caracteres).
Esta lectura capta los dgitos de mayor peso a menor peso; como la suma se realiza
en orden inverso, guardamos los dgitos en una pila de caracteres. As, el ltimo dgito
que entra (la unidad) es el primero en salir.
A partir de este hecho, podemos seguir dos estrategias:
Esta alternativa nos peIlnite que no haya ningn tipo de restriccin en cuanto al n-
mero de dgitos. Como contrapartida, el proceso es ms lento, hay que realizar muchas
operaciones de creacin y liberacin de nodos.
Colas y colas de prioridades: el TAO cola 253
El programa que presentamos sigue la segunda alternativa. Para ello utilizamos dos
unidades, la unidad de manejo de pilas y la unidad de manejo de listas fifo. Presentamos
nicamente la seccin de interface de pila, la codificacin puede verse en las diversas
realizaciones de pilas escritas en el captulo anterior.
procedure Qcrea r ;
begin
C . Frente := ni l ;
C .F inal : = nil
end;
)
~
function Qvacia;
begin
Qvacia := (C .Fren te - nil)
end;
procedure Qponer;
var
A: pt rno d.,q;
begin
new (A) ;
AA.lnfo ..-- X,
AA.Sgte := nil;
if Qvacia(C) then
C.Frente := A
else
C. Final A.Sg te := A;
C .Final:= A
end;
procedure Qborrar;
var
A:Ptrnodoq;
begin
if (not Qvacia(C) )then
begin
A := C.Frente;
C. Frente : = C.FrenteA.Sgte;
dispose(A)
end
end
function Frente;
begin
if (not Qvacia(C)) then
Frente := C.FrenteA.lnfo
end
procedure Quitar;
begin
X : = Frent e (C) ;
Qborra r(C)
end;
begin
end.
begin
Abrir(Datos) ;
Qcrear( Lf o);
while not eo f (Dat os) do
begin
Leer n u mero(Datos , P l a);
Su ma r(Pl a, L fo)
end;
if not Qvacia(L f o) then
begin
wri teln( ' Res u l t ado d e l a suma d e n me r os gr an des ');
Esc ri b i r(L f o)
end
end.
RESUMEN
El proceso de insercin de datos se denomina acolar (enquering) y el proceso de eliminacin se
llama desacolar (dequering).
Una cola es una estructura de datos del tipo FIFO (jirst-in, first-out , primero en entrar, prime-
ro en salir); tiene dos extremos: una cola, donde se insertan los nuevos elementos, y una cabecera
o frontal , de la que se borran o eliminan los elementos.
Colas y colas de prioridades: el TAO cola 257
El tipo abstracto de datos cola se suele implementar mediante listas enlazadas por las mismas
razones que en el caso de las pilas: facilidad para gestionar el tamao variable o dinmico frente
al caso del tamao fijo.
Numerosos modelos de sistemas del mundo real, tanto fsicos como lgicos, son del tipo cola;
tal es el caso de la cola de trabajos de impresin en un servidor de impresoras, la cola de priorida-
des en viajes, programas de simulacin o sistemas operativos. Una cola es el sistema tpico que se
suele utilizar como buffer de datos, cuando se envan datos desde un componente rpido de una
computadora (memoria) a un componente lento (por ejemplo, una impresora).
Cuando se implementa una pila, slo se necesita mantener el control de una entrada de la
lista, mientras que en el caso de una cola, se requiere el control de los dos extremos de la lista.
Una cola de prioridad se puede implementar como un array de colas ordinarias o una lista
enlazada de colas ordinarias.
EJERCICIOS
8.1. Se ha estudiado en el captulo la realizacin de una cola mediante un array circular; una
variante a esta representacin es aquella en la que se tiene una variable que tiene la posi-
cin del elemento Frente y otra variable con la longitud de la cola (nmero de elementos),
LongCo 1 a, y el array considerado circular. Dibujar una cola vaca; aadir a la cola
6 elemento; extraer de la cola tres elementos; aadir elementos hasta que haya over f low.
En todas las representaciones escribir los valores de Frente y LongCola.
8.2. Con la realizacin de 8.1 escribir las operaciones de Cola: Qcrear, Qvacia, Qponer,
Frente y Qborrar.
8.3. Con la realizacin de una cola descrita en 8.1,2 consideremos una cola de caracteres. El
array consta de 7 posiciones. Los campos Frente, LongCola actuales y el contenido de
la cola:
Frente = 2 LongCola = 3 Cola: J, K, M
Escribir los campos Frente, LongCola y la Cola segn se vayan realizando las si-
guientes operaciones:
a) Se aaden los elementos F, J, G a la cola.
b) Se eliminan dos elementos de la cola.
e) Se aade el elemento A a la cola.
d) Se eliminan dos elementos de la cola.
e) Se aaden los elementos B, C, W a la cola.
f) Se aade el elemento R a la cola.
8.4. La realizacin de una cola mediante un array circular sacrifica un elemento del array; esto
se puede evitar aadiendo un nuevo campo a la representacin: Vac io de tipo lgico.
Escribir una unidad en la que se defina el tipo de datos y se implementen las operaciones de
manejo de colas.
8.5. Considere la siguiente cola de nombres, representada por un array circular con 6 posicio-
nes, los campos Frente, Final y Vacio:
Frente= 2, Final= 4, Vacio= Falso Cola: ,Mar,Sella,Licor,
Escribir el contenido de la cola y sus campos segn se realizan estas operaciones:
1,
,
8.6. Una bicola con restriccin de entrada slo permite insercciones por uno de sus extremos,
permitiendo extraer elementos por cualquier extremo. Definir e implementar las operacio-
nes para este tipo de datos.
8.7. Una bicola con restriccin de salida slo permite extraer elementos por uno de sus extre-
mos, permitiendo insertar elementos por cualquier extremo. Definir e implementar las ope-
raciones para este tipo de datos.
8.8. Consideremos una bicola de caracteres representada en un array circular. El array consta de
9 posiciones. Los extremos actuales y el contenido de la bicola:
Izquierdo = 5 Derecho = 7 Bieola: A, e, E
Escribir los extremos y la bicola segn se vayan realizando las siguientes operaciones:
a) Se aaden los elementos F, J a la derecha de la bicola.
b) Se aaden los elementos R, W, V a la izquierda de la bicola.
e) Se aade el elemento M a la derecha de la bicola.
d) Se eliminan dos letras a la izquierda.
e) Se aaden los elementos K, L a la derecha de la bicola.
f) Se aade el elemento S a la izquierda de la bicola.
PROBLEMAS
8.1. Con un archivo de texto se quieren realizar estas acciones: formar una lista enlazada, de tal
forma que en cada nodo est la direccin de una cola que contiene todas las palabras del
archivo que empiezan por una misma letra. Una vez formada esta estructura, se desea vi-
sualizar las palabras del archivo, empezando por la cola que contiene aquellas palabras que
empiezan por la letra a, luego las de la letra b, y as sucesivamente.
8.2. Una empresa de reparto de propaganda contrata a sus trabajadores por das. Cada repartidor
puede trabajar varios das continuados o alternos. Los datos de los repartidores se almace-
nan en una lista simplemente enlazada. El programa a desarrollar contempla los siguientes
puntos:
Crear una estructura de cola para recoger en ella el nmero de la seguridad social de
cada repartidor y la entidad anunciada en la propaganda para un nico da de trabajo.
Actualizar la lista citada anteriormente (que ya existe con contenido) a partir de los
datos de la cola.
La informacin de la lista es la siguiente: nmero de seguridad social, nombre y total de
das trabajados. Adems, est ordenada por el nmero de la seguridad social. Si el trabaja-
dor no est incluido en la lista debe aadirse a la misma de tal manera que siga ordenada.
8.3. En un archivo de texto se quiere determinar todas las frases que son palndromo. Para ello
se sigue la siguiente estrategia: aadir cada carcter de la frase a una pila y a la vez a una
cola. La extraccin de caracteres simultnea de ambas y su comparacin determina si la
Colas y colas de prioridades: el TAD cola 259
frase es o no palndromo. Escribir un programa para determinar todas las frases palndromo
del archivo de texto. Considerar que cada lnea de texto es una frase.
8.4. En un archivo de texto se encuentran los n;sultados de una competicin de tiro al plato, de
tal forma que en cada lnea se encuentra Apellido, Nombre, nmero de dorsal y nmero de
platos rotos. Se desea escribir un programa que lea el archivo de la competicin y determi-
ne los tres primeros. La salida ha de ser los tres ganadores y a continuacin los concursan-
tes en el orden en que aparecen en el archivo (utilizar la estructura cola).
8.5. El despegue de aeronaves en un aeropuerto se realiza siguiendo el orden establecido por
una cola de prioridades. Hay 5 prioridades establecidas segn el destino de la aeronave.
Destinos de menos de 500 km tienen la mxima prioridad, prioridad 1, entre 500 y 800 km
prioridad 2, entre 800 y 1.000 km prioridad 3, entre 1.000 y 1.350 km prioridad 4 y para
mayores distancias prioridad 5. Cuando una aeronave recibe cierta seal se coloca en la
cola que le corresponde y empieza a contar el tiempo de espera. Los despegues se realizan
cada 6 minutos segn el orden establecido en las distintas colas de prioridad. El piloto de
una aeronave puede pasar el aviso a control de que tiene un problema, y no puede despegar
por lo que pasa al final de la cola y se da la orden de despegue a la siguiente aeronave.
Puede darse la circunstancia de que una aeronave lleve ms de 20 minutos esperando, en
ese caso pasar a formar parte de la siguiente cola de prioridad y su tiempo de espera se
inicializa a cero.
Escribir un programa que simule este sistema de colas mediante una lista nica, cada vez
que despegue un avin saldr un mensaje con las caractersticas del vuelo y el tiempo total
de espera.
8.6. Resolver el problema 8.4 realizando el sistema de colas mediante un array de 5 colas.
PARTE
,
CAPITULO
ecurslvl a
a orltmos recursIvos
CONTENIDO
9.1. Recursividad.
9.2. Cundo no utilizar recursividad.
9.3. Algoritmos divide y vence.
9.4. Implementacin de procedimientos recursivos mediante pilas.
9.5. Algoritmos de vuelta atrs.
9.6. Problema de la seleccin ptima.
9.7. Problema de los matrimonios estables.
RESUMEN.
EJERCICIOS.
PROBLEMAS.
9.1. RECURSIVIDAD
Un objeto recursivo es aquel que forma parte de s mismo. Esta idea puede servir de
ayuda para la definicin de conceptos matemticos. AS, la definicin del conjunto
263
264 Estructura de datos
de los nmeros naturales es aquel conjunto en el que se cumplen las siguientes ca-
, .
ractenstlcas:
O es un nmero natural.
El siguiente nmero de un nmero natural es otro nmero natural.
Mediante una definicin finita hemos representado un conjunto infinito.
El concepto de la recursividad es muy importante en programacin. La recursividad
es una herramienta muy eficaz para resolver diversos tipos de problemas; existen mu-
chos algoritmos que se describirn mejor en trminos recursivos.
Suponga que dispone de una rutina Q que contiene una sentencia de llamada a s
misma, o bien una sentencia de llamada a una segunda rutina que a su vez tiene una
sentencia de llamada a la rutina original Q. Entonces se dice que Q es una rutina re-
cursiva.
Un procedimiento o funcin recursivos han de cumplir dos propiedades generales
para no dar lugar a un bucle infinito con las sucesivas llamadas:
Cumplir una cierta condicin o criterio base del que dependa la llamada re-
cursiva.
Cada vez que el procedimiento o funcin se llamen a s mismos, directa o indirec-
tamente, debe estar ms cerca del incumplimiento de la condicin de que depen-
de la llamada.
recursivas a procedimientos o funciones tienen un coste de tiempo mucho mayor que sus ,
,,I
Recursividad: algoritmos recursivos 265
PROBLEMA 9.1
Se tiene una lista enlazada que se referencia por un puntero externo al primer nodo
de la lista. Se desea imprimir los nodos del ltimo al primero. Los tipos de datos que se
utilizan en la lista son:
type
Tipoinfo - . . . ,
Puntero = ANodo;
Nodo = record
Info: TipoInfo;
Sgte: Puntero
end;
nil
Codificacin
procedure I mpri melnvers o( L: Pun tero);
begin
if L <> nil then
begin
I mprimelnver so( L A. Sg t e ) ;
write(LA.lnfo)
end
end;
Codificacin
uses Pi las;
procedure Imprime i nverso (L : Puntero ) ;
var
Pi la: p trpila;
P : Puntero;
begin
Pcrear (Pila) ;
P : = L;
while P <> nil do
begin
Pmeter( P, Pila) ;
P := P A.S g t e
end;
{En l a pi l a estn todas las direcciones de l os nodos }
while not Pvacia ( Pil a) do
begin
Psacar(P, Pi la);
Escribir(PA.lnf o)
end
end;
PROBLEMA 9.2
Multiplicacin de dos nmeros enteros por el mtodo de la montaa rusa.
Descripcin: El mtodo consiste en formar dos columnas, una por cada operando.
Las columnas se forman aplicando repetidamente los pasos siguientes:
Recursividad: algoritmos recursivos 267
Una vez hecho esto, se suman los valores de la columna del multiplicador que se
correspondan con valores impares de la columna de multiplicandos. La suma es el pro-
ducto.
Codificacin
El problema se resuelve con una funcin que tiene como entrada dos enteros X, Y, Y
devuelve el producto aplicando el mtodo de la montaa rusa.
,,
I
268 Estructura de datos
A B e
De este modo se va progresando, reduciendo cada vez un nivel la dificultad del pro-
blema hasta que el mismo slo consista en mover un solo disco. La tcnica consiste en ir
intercambiando la finalidad de los postes, origen destino y auxiliar. La condicin de
terminacin es que el nmero de discos sea 1. Cada accin de mover un disco realiza los
mismos pasos, por lo que puede ser expresada de manera recursiva.
El procedimiento recursivo TorresH resuelve el acertijo o juego.
begin
if N=l then
Mov imi e nt o (N, A, e)
else begin
To rr es H (N - 1, A, e , B ) ;
Mov imiento(N, A, e) ;
Torres H(N - 1, B , A, C)
end
end;
program Dibujar;
uses c rt;
type
eoo r d = record
X : r eal ;
y : rea l
end;
var
O, F : Coo rd;
procedure Dib_sgmto(O, F: eoord) ;
var
M: eoo r d ;
begin
with M do
if (O.X+O .S) < F. X then
begin
X := ( O . X+ F. X) / 2 ;
y := (O . Y+F. Y) / 2 ;
Dib_ sg mt o(O , M) ;
if WhereX > 7 0 then
Goto XY( S , Wh e re Y + 1 ) ;
wr i t e (I X : 3 : 1, , , , Y : 3 : 1, ' )
( I , I I ) ;
Dib_sgmt o (M, F ) ;
end
end;
begin
el rsc r; GotoXY ( 5,1 ) ;
O.X := 1 ; O.Y := 2 ;
F. X := 1 2 ; F. Y := 7 ;
Di b _ sgmt o (O, F )
end.
270 Estructura de datos
Cada vez que se hace una llamada recursiva a P, los valores actuales de los argumen-
tos y de las variables locales se meten en sus pilas para ser procesadas posteriormente.
Asimismo, cada vez que hay un retomo a P procedente de una llamada recursiva ante-
rior, se restauran los valores de variables locales y argumentos de las cimas de las pilas.
Para la obtencin de la direccin de retomo vamos a suponer que el procedimiento P
contiene una llamada recursiva en la sentencia N. Entonces guarda en otra pila la direc-
cin de retomo, que ser la sentencia siguiente, la N + 1. De tal forma que cuando el
nivel de ejecucin del procedimiento P actual termine, alcance la sentencia end final,
usar dicha pila de direcciones para volver al nuevo nivel de ejecucin. De esta forma
cuando la pila de direcciones se quede vaca volver al programa que llam al subpro-
grama recursIVO.
PROBLEMA 9.3
Hacemos una traza del estado de las pilas en la ejecucin de funcin producto, por el
mtodo de la montaa rusa, para los valores de 19 y 45.
1 no nO+Prod ...
2 360 ProductoO
4 180 ProductoO
9 90 90+Prod ..
19 45 45+Prod ..
Pila Pila Pila de
de X de Y direcc.
Recursividad: algoritmos recursivos 271
l. Definir una pila para cada variable local y cada argumento, y una pila para alma-
cenar direcciones de retorno.
2. En la sentencia n donde se haga la llamada recursiva a P:
(1) Meter en las respectivas pilas los valores actuales de las variables locales y
argumentos; (2) Meter en la pila de direcciones la direccin de la siguiente
sentencia.
Inicializar los argumentos con el valor actual de ellos y empezar la ejecucin
desde el principio del procedimiento.
3. Vuelta de la ejecucin despus de la llamada recursiva:
Si la pila de direcciones est vaca, devolver control al programa invocador.
Sacar de las pilas los valores de la cima. Llevar la ejecucin a la sentencia
extrada de la pila de direcciones.
,
2. Llamada recursiva.
a) Guardar en pilas:
Meter (N, PilaN)
Meter ( A, PilaA)
Meter(B, PilaB)
Meter(C, PilaC)
Meter (e Pas o 3 > , PilaDir )
C ~ t
e) Volver a paso 1.
e) Volver a paso 1.
Para realizar la codificacin del algoritmo no recursivo de las Torres de Hanoi es ne-
cesario una pila de enteros (P ila N) y tres pilas de elementos char (Pi l aA , p i la B,
p i 1 aC ). Para simular direcciones de retomo se utili za otra pila de enteros en la que se
guarda 1 o 2, segn se simule la primera llamada o la segunda llamada recursiva. Los
tipos de datos y las operaciones estn en las unidades de pilas.
uses pi l acha r, P i l a in t ;
procedure Ha n o i t e r (N : i nteg er ; A, B , C : c h a r ) ;
var
Pil a A , P il a B , p ilaC : Pil a c ha r . Pt rPil a ;
Pi laN , P i l aD : P ilaint . PtrPi la ;
Paso : in t eger;
T : c ha r ;
begin
P i lachar .Pc re a r( P i laA ) ;
P ila cha r . Pcr ear (P i l a B ) ;
P ilachar . Pcrear (PilaC) ;
P il a i n t . Pcrea r (Pi laN) ;
p il ain t . Pc rear ( Pi l aD ) ;
P i laint . Pm e t e r( l,P il aD ) ;
while not P i l aint . Pv acia (PilaD) do
i f (N = 1 ) then
begin
Mov e r di sco(N ,A , C) ;
P i la int . P s a car (P as o , pi l aD) ;
if not P i lain t . Pva c i a(P il aD) then
begin
Pi la cha r . P saca r(A, pilaA) ;
Pi la cha r . P sac a r (B, pilaB) ;
P i la c h a r . Ps ac ar(C , PilaC) ;
P il a i n t . Psaca r ( N ,P il aN)
end
end
else begin
P i l aint. P saca r(Pas o , Pil aD ) ;
Case Pas o of
1 : begin
Pila char . Pme t er ( A,Pi laA) ;
P i l a c h a r . Pmeter (B ,P ilaB ) ;
Pi l ach a r . Pm eter IC , PilaC) ;
P ilai nt . Pmet e r(N, Pi l a N) ;
P il a i nt . Pmete r (2, P il aD ) ; {Pa so ac tual }
P i 1 a i n t . Pme t er ( 1 , p i 1 a D) ;
N := N - l;
T := B ; B : = C ; C : = T
end;
2 : begin
Move r d iscO ( N,A, C) ;
{No e s n e c esario alm ac ena r los argum e n to s A, B, C , N p ue s no
se utilizan }
Pi l a i n t . Pmet er (1, Pi l aD) ;
274 Estructura de datos
N := N-1;
T := B; B := A ; A : = T
end
end
end
end;
Esta solucin resulta un tanto farragosa debido a la utilizacin de 5 pilas. Una sim-
plificacin fcil que puede hacerse es utilizar una nica pila, en sta se guarda el estado
completo de los argumentos y la direccin de retomo. En la unidad p i 1 a S t a t est
declarado el tipo elemento, un registro con los campos necesarios para guardar A, B, e,
N y Di r , y adems las operaciones de manejo de pilas.
Los tipos de datos en la unidad Pi laSt a t:
type
Elemento = record
Pa , Pb , Pe : ehar ;
Nd , Oir: in te g er
end;
Ptr P i l a = AI te mp;
I te mp = record
I nf o : Ele me n t o ;
Sgte : PtrP il a
end;
El procedimiento Ha n o i ter 2 :
case Dir of
1: begin
Dir := 2;
Pmeter (T, Pila ); {Estado actual}
Estado(T,Pa,Pc,Pb,Nd-l,l) ;
Pmeter(T,Pila) ;
end;
2: begin
Mover_disco (Nd, Pa, Pc);
Estado(T,Pb,Pa,Pc,Nd-l,l) ;
Pmeter(T,pila) ;
end
end
end
end;
program Torrehanoi;
uses P il aint , Pilachar, Pilastat , crt, printer ;
const
Maxnumdiscos = 15;
var
N: integer;
A,B,C: char;
mover_torre(N-1,A,C,B) ;
mo ver_disco(N,A,C) ;
mover_t orre(N-1,B ,A,C)
end;
end;
Pi l aint .Pcrear(PilaN} ;
P i laint.Pcrear(PilaD} ;
Pilaint.Pmeter(l,PilaD} ;
while not Pilaint.Pvacia(pilaD} do
if (N = 1) then
begin
Mover_disco(N,A,C) ;
Pilaint.Psacar(Paso,PilaD) ;
if not Pilaint.Pvac i a(pilaD) then
begin
Pilachar.Psacar(A,Pi l aA) ;
Pilachar.Psacar(B,PilaB} ;
Pilachar.Psacar(C,PilaC} ;
Pilaint.Psacar(N,P i laN}
end
end
else begin
Pilaint.Psacar(Paso,PilaD) ;
Case Paso of
1: begin
Pilachar.Pmeter(A,PilaA) ;
Pilachar.Pmeter(B,PilaB) ;
pilachar.Pmeter( e ,Pilae) ;
Pilaint.Pmeter(N,Pi l aN} ;
Pilaint. Pmeter (2, Pi l aD); {Paso ac t ual }
Pilaint.Pmeter(l,PilaD} ;
N := N- 1;
T := B; B : = e ; e := T
end;
2 : begin
Mover_disco(N,A , e} ;
Pilain t . Pmeter(l,Pila D} ;
N := N- 1;
T := B; B := A; A : = T
end
end
end
end;
Algori t mo Caball o ;
inicio
Repetir
Seleccio nar n uevo movimiento del caballo
si (Est e n tablero) y (No pas ya) entonces
An ota r movi mi e n to e n e l table ro
si (No comp l etado t able ro) entonces
Nuevo ensay o : Caballo
{Vuelta de l l ama d a recurs i va }
si (No se a l can z so lu cin) entonces
Borrar anotac~ o n ante r~or
fin_si
fin si
fin si
hasta (Completa do t ab l ero) o (No ms p os i b l es mov imientos)
fin
En los algoritmos de vuelta atrs siempre hay nuevas tentativas en busca de solucin,
nuevos ensayos. En el caso de que un ensayo no conduzca a alcanzar la solucin, se da
marcha atrs. Esto es, se borra la anotacin hecha al realizarse el ensayo y se vuelve a
hacer otro, en el caso de que sea posible (en el caso de un caballo, ste puede realizar
hasta ocho movimientos desde una posicin dada).
Para describir con ms precisin el algoritmo, definimos los tipos de datos para re-
presentar el tablero y los movimientos.
const
N= 8 ;
type
Tab l ero = array[l .. N, 1 .. N) of i n teger ;
var
T : Ta bl e r o ;
Para la accin de seleccionar un nuevo movimiento, hay que tener en cuenta que
dada una posicin el caballo puede realizar 8 posibles movimientos. En una matriz de
dos dimensiones se guardan los 8 desplazamientos relativos para conseguir un siguiente
salto. La figura nos muestra los desplazamientos:
3 .2
.4 1
5 .a
+
.6 .7
Para no penalizar en tiempo de ejecucin, las variables array son definidas globales.
En las sentencias del bloque principal se inicializa las posiciones del tablero y los
desplazamientos relativos para obtener nuevas coordenadas.
begin
H[l,l] -- 2 ; H[2,1] -- 1;
H[1,2] -- 1 ,. H[2,2] -- 2;
H[1,3] -- -1,, H[2,3] -- 2 ,.
H[1,4] -- ~ 2 ; H[2,4] -- 1 ,.
H[1,5] - - 2 ; H[2,5] -- -1;
H[1,6] -- -1 ; H[2,6] -- -2;
H[1,7] -- 1 ; H[2,7] -- -2;
H[1,8] -- 2 ; H[2,8] -- -1;
for I -- 1 to N do
for J -- 1 to N do
T[I,J] .. -- O ;
{El caballo parte de la casilla (l,l)}
T[l,l] -- 1 ;
Caballo(2,1,1,S) ;
if S then
for I := 1 to N do
begin
for J := 1 to N do
wr i t e (T [ I , J] : 4 ) ;
writeln
end
el se
writeln('NO SE ALCANZA SOLUCION')
end.
Recursividad: algoritmos recursivos 281
procedimiento EnsayarSolucion
Inicio
Inicializar cuenta de opciones de seleccin
repetir
Se lec cio nar nuevo paso hacia l a soluci n
si vl id o entonces
Anotar el paso
si no completada solucin entonces
EnsayarSolu c in a partir del nuev o paso
si no alcanza solucin completa entonces
.
borrar anotac~on
,
fin_si
fin_si
fin
Hasta (Completada solucin) o (No ms opciones )
fin
Este esquema puede tener variaciones. En cualquier caso siempre habr que adaptar-
lo a la casustica del problema a resolve~.
unit PilaC;
Ii interface
const
I
N = 8;
,
type
I ndice = 1. .N;
Tipoelem = record
Nummov: integer;
, Salto: integer;
X: Indice;
Y: I ndi ce
end;
282 Estructura de datos
PtrPila =Altemp;
Itemp = record
Info: Tipoelem;
Sgte: PtrPila
end;
begin
A : = Pi l a ;
X : = Pila A.I nfo ;
Pila := Pila A. Sgte;
d i spose( A)
end
end;
begin
end.
Esta unidad la utilizamos para escribir el programa que iterativamente encuentra to-
das las rutas que puede seguir el caballo para recubrir el tablero.
284 Estructura de datos
begin
for Fila := 1 to N do
for Columna := 1 to N do
Tablero[Fila, Columna] ..-
- O
end;
,
un salto de caballo} ,,
e,,
IncX[1] := 2; IncY[1] := 1;
IncX[2] := 1; IncY[2] := 2; ,
I
IncX[3] := -1; IncY[3] := 2; ,
IncX[4] -- -2; IncY[4] -- 1; ,
IncX[5] -- -2; IncY[5] -- -1; ,I
1
IncX[6] - -1; IncY[6] -- -2;
IncX[7] --
IncX[8] -
1 ; IncY[7] -- -2;
2 ; IncY[8] - -1;
I
end;
l
procedure Escribetablero(var Tablero :Tabla);
var
Fila, Columna: Indice;
begin
for Columna := N downto 1 do
begin
for Fila := 1 to N do
write (Tablero [Fila, Columna]: 5) ;
writeln
end;
end;
begin
clrscr;
Rl := [l..N];
Incre(Incx, Incy);
Iniciartablero(Tablero) ;
Write ('Introduzca casilla inicial:');
Nummov : = 1;
with R do
begin ,
,
readln (X, Y) ;
Nummov : = 1;
Tablero[X,Y] := Nummov;
Salto := 8
end;
Pcrear (Cp) ;
Pmeter(Cp, R);
Recorrido := false;
Soluciones := O;
while not Pvacia(Cp)do J
;
begin ,
if Recorrido then j
begin
Pcima (Cp, R);
with R do
Tablero[X,Y] := O;
Salto := R.Salto;
Pborrar (Cp) ;
,
1
Recursividad: algoritmos recursivos 285
end
end
else (N o p~d o coloca ~ s n Num~ov+l a partir de N,l mmC)V \
while not Colocado and not ? vaci a ( Cp ) do
286 Estructura de datos
A continuacin son expuestos problemas tpicos que son resueltos siguiendo la es-
trategia de los algoritmos de vuelta atrs.
,
Recursividad: algoritmos recursivos 287
columna i. Por esta coincidencia el parmetro i nos sirve de ndice de columna dentro de
la cual podremos colocarla en los ocho posibles valores de fila.
En cuanto a los tipos de datos para representar las reinas en el tablero, como lo que
nos interesa es detelIuinar en qu fila se sita la reina que est en la columna i , defini-
mos un vector entero. El contenido de una posicin del vector ser 0, o bien el ndice de
fila donde se sita la reina.
, const
N= 8 ; { N mer o d e r ei n a s }
type
Fila = array[l . . N] of i nteger;
CODIFICACiN
const
N= 8; {Nmero de reinas}
type
Fi las = array[ l .. N] of int e ger;
var
Re i nas: Filas;
Soluc i o n: b oo l ean ;
1: in t eger ;
end;
begin
K : = (J ; {In ici.a liza r pos ibl es mo vim ient o s}
repeat
K : ~K + l ;
S : .:. : t illse ;
Reinus [I] {T enta tiv a d e co l ocar re l na 1 en ti l a K,
: = K; a l u ve z
q uelia a n otado m ovi~i e n t o)
if Val ido(I ) then
if T < 8 then 18 Pllede su!;ti tuir se por NI
begin {No comp let ad o e l p roble ma}
Co lo caI' _ Re ina s(I + 1, S I ;
if not S then ( Vuelta atr s)
Reinas[I] : = (J
end
else (L as 8 rein as c ol oc a das )
S : = true
until S or (K = 8)
end;
begin
Colocar Reinas(l, So lucion) ;
if s ol u ci on then
fa r 1 : - 1 t o 8 do
write(Reinus[l] : 5 )
end.
unit P i la R ;
interface
c on st
N = 8;
type
Rang o l .. N ;
7
P tr Pila = AN odo ;
Nodo = record
NI' , Co l: word ;
sg te : Pt r Pila
end
procedure PcI' e ar (var Pila : P trPi l a) ;
function Pva cia ( P ila : Plr P il a) : bool ea n ;
Recursividad: algoritmos recursivos 289
program ReinaA_It;
{Sita N reinas sin atacarse en tablero N*N. Da una sola solucin}
uses Crt, PilaR;
type
Tipocol = array [Rango) of boolean;
DiagonalDchalzda = array [2 .. 2 * N) of boolean;
( Fila(nmero de reina) + Columna = cte.}
DiagonallzdaDcha = array [1 - N .. N - 1) of boolean;
{F ila o nmero de reina - columna = cte.}
var
Col , Nf, Nr, i: integer;
Colibre: Tipocol; {NO hay reina en fila j-sima}
Ddch: DiagonalDchalzda; {no hay reina en Diagonal Dcha -Izda }
Dizq: DiagonallzdaDcha; {no hay reina en Diagonal Izda-Dcha}
Cp: Ptrpila;
Colocado : boolean;
begin
ClrScr;
write( 'Intr oduzca dimensin del tablero: ');
repeat
L
290 Estructura de datos
r eadl n ( Nf )
until Nf < = N;
for i : =1 to Nf do Col ibr e[ i] := t rue ;
for i : =2 to 2 *Nf do Dd c h[i] : = tr ue ;
for i : = 1 - Nf to Nf - 1 do Dizq [ i l : = t rue ;
Pcre a r(Cp) ; Nr := O; Co l : = O;
Pm e t er (C p, Nr , Col ) ;
while (Nr < Nf) and not Pvac i a(C p) do
begin
Nr : = Nr + 1 ; Colo cado : = fals e ;
while not Co locado and (C ol < Nf ) do
begin
Co l := Col + 1 ;
if Co libr e[Col] then
if Ddch[Nr + Col] then
if Diz q[ Nr - Co l] then
begin
Ocupa r (Co l ibr e , Ddc h, Di zq , Nr , Col) ;
Colocado : = t rue;
Pm e t e r (C p , Nr , Co l );
CA l := O
end
end;
if not Col oca d o then
begin
if Cp A. Nr < > O then
begin
Lib e rar(C olib re , Ddch, Diz q, Cp ' .Nr, CpA . Col);
Nr : = CpA .Nr - 1 ;
Col := CpA . Col ;
end;
Pbo rrar (Cp)
end
end;
const
N = ... { m ximo de pesos prev i s t o }
type
Vector = array [ l . . N] of in t ege r;
var
Peso s: Ve ctor;
El algoritmo para solucionar el problema tiene como tarea bsica aadir un peso
nuevo, probar si con ese peso se alcanza la solucin, o se avanza hacia la solucin. Es
una bsqueda sistemtica de la solucin hacia adelante. Si llegamos a una situacin de
impasse, en la que no se consigue el objetivo por que siempre es superado, entonces
se retrocede para eliminar el peso aadido y probar con otro peso para inspeccionar si a
partir de l se consigue el objetivo. Esto es, realizar otra bsqueda sistemtica.
La bolsa donde se meten los pesos viene representada por un tipo conjunto. Al aa-
dir un peso, la anotacin se realiza acumulando el peso y metiendo en la bolsa, el con-
junto, el ndice del peso. Para borrar la anotacin se opera a la inversa.
CODIFICACiN
const
N = . . . , {mx im o de pesos previsto }
type
Vec t or - array[l . . N] of i nteger ;
var
Pesos : Vec tor;
Bo l sa : set of 1 .. N;
So l uc i o no boolean;
V : in teger ; {Obje tivo}
{V : Es el objet i vo }
{Candidato : I nd i ce de l peso a aa dir }
{Cuenta : Sum a parc i a l de pesos }
begin
Ca n dida t o : = Ca n d i dato - 1;
Pborrar( Pstat ) ;
end
else if Cim a (Pstat) = 1 then
begin {Se ex cluye al c andidato y se vuelve a prob a r}
Bols a : = Bol sa - [Candidato ];
P i la real. Ps a car (Cuenta , Pcu e n t);
Ca ndidato := Ca ndidat o + 1;
Pborr ar (Pstat) ;
Pmeter(2, Pstat)
end
el se if C im a (Pstat) = 2 then
begin
Candi dato : = Ca n d idat o - 1 ;
Pborrar( P stat )
end
until Pv a c ia (Ps t at) or S
end;
ALGORITMO
El viajero parte de una casilla inicial. Desde una casilla puede moverse a cuatro posibles
casillas (hacia el Norte, el Oeste, el Sur o el Este). El movimiento estar permitido si en
la nueva casilla no hay un muro. Cada vez que se pasa por una casilla se marca con
un '*' para as saber el camino seguido hasta la salida. Si llegamos a una situacin de
impasse, es decir estamos en una casilla desde la cual ya no podemos avanzar: se
desanota la casilla, se marca la casilla como si fuera un muro para no volver a pasar por
296 Estructura de datos
CODIFICACiN
q : =A[ q ];
end;
wr i t e ( , , : 1 0 - N)
end; ,
procedure permu ta( K,N: Apu n tado r ) ; .\
,
,
j
Recursividad: algoritmos recursivos 297
var
p : Apuntador ;
begin
P .. -- O ,.
repeat
A[K ] :=A[pJ;
A[p] .'-K'- ,
if K = N then
procesopermuta c i o n
else
pe r muta(K+1.N) ;
{Ah ora se " co l o ca" en la a n t eri o r , rep r esentad o por A [K ] )
A [ p] : =A [ K] ;
p : = A [ p];
until p = O;
write l n ;
end;
begin
c lr scr ;
repeat
write( 'N u mero de e l eme n t o s a permutar:') ;re ad ln(N);
until N in [l .. Maxgr a d o] ;
write l n( 'Permut aci o n es de ': 50 ,N, 'el e mentos ' );
A [ O] : = O;
Permu t a (l , N);
X := readkey
end.
de la seleccin actual, el criterio para seguir con el proceso de seleccin actual es que el
valor total todava alcanzable despus de esta exclusin no sea menor que el valor pti-
mo (mximo) encontrado hasta ahora. Cada tarea realiza las mismas acciones que la
tarea anterior, por lo que puede expresarse recursivamente. Al estar buscando la selec-
cin ptima, hay que probar con todos los objetos del conjunto.
Consideramos que el valor mximo alcanzable inicialmente es la suma de todos los
valores de los objetos que disponemos. Debido a la restriccin del peso, posiblemente el
valor ptimo alcanzado sea menor.
CODIFICACIN
program Optima(inpu t , ou tput);
uses crt;
const
N = 10 ;
type
Indice - 1 .. N;
Objet o - Record
va l: i nteger;
pso : integ er
end;
Li sta = array [Indicel of Objeto ;
Conj = set of Indice;
var
A: Lista;
Psomx, Tpeso,
Tvalor, Mva lor ,
T, K: intege r ;
Ac t, Opt o Conj ;
Tv := O; Tp := o;
for K := 1 to N do
begin
write( 'Objeto', K,'.', 'Peso y Valor:');
readln(G[K] .pso,G[K] .val);
Tv := Tv + G[K] .val;
Tp := Tp + G[K] .pso
end
end;
Va Ex : = Va - A [ 1 ] . val ;
{VaE x es e l va l or mx i mo q u e pod r a alca n za r la se l ecc i n ac t ua l)
if VaEx > Mvalor then
if 1 < N then
Maleta ( 1+1, Pt , Va Ex, Mv alor)
el Be begin
Opt := Act;
Mvalor : = Va Ex
end;
{s i Va Ex < Mvalor es i ntil seguir ensaya n do ya que no va a
s u p er ar e l va l o r pt im o act u a l : Mval o r}
end;
begin
c l rscr ;
write l n ('Entrada de ' , N , 'Objetos') ;
Obje t os (A , Tval o r , Tpeso) ;
c l rs cr;
wri te ('Peso: ') ;
for K := 1 to N do
wr i t e (A [ K] . P s o : 6 ) ;
write l n ;
write ('v al or : ') ;
for K : = 1 to N do
wr ite (A [ K]. va l: 6) ;
wr it e ln;
{ El p eso mxi mo i r varian d o d esde el mni mo , h as t a al canzar e l
mx i mo o 10 pruebas , cada prueba au menta e l peso e n 3 un i dades}
T := Min (A) ; Psomx : = T ;
repeat
Ac t := [ ]; Op t : = [ 1;
Mvalor : = O;
Maleta (l, O,T va l or , Mvalor ) ;
so lu c ion (Opt,Psomx , Mvalo r ) ;
Psom x := Psomx+3
until (Psomx > Tpeso) or (Pso mx > T+I0 * 3)
end.
ALGORITMO
const
N = ... ; {N me ro de pa rej as}
ty pe
T ipohombre = 1 .. N;
Tipomuje r = 1 .. N;
Pr efhombre s = array [Tipoh o mbre , 1 .. NJ of T ipomujer;
Pr ef muje re s = array [Ti pomu j er, l .. NJ of Ti pohombr e ;
Par h o mbres= array [Tipohombre J of Ti po mu j e r;
,
1
302 Estructura de datos
Solter a [J] a true quiere decir que la mujer J todava no ha encontrado pareja. Para
determinar si un hombre K ha encontrado pareja puede utilizarse otro array similar al de
Soltera, o bien sencillamente si K < H es que K ya encontr pareja (H es el hombre actual
que busca pareja).
Con todas estas consideraciones de tipos de datos ya podemos proponer una solu-
cin ms elaborada:
tal que Rhm [H , M 1 contiene el orden que ocupa, o rango, de la mujer M en la lista de
preferencias del hombre H. De igual forma, Rmh [M, H 1 contiene el orden del hombre H
en la lista de preferencias de la mujer M. Ambas matrices se determinan inicialmente a
partir de las matrices de preferencias.
El predicado <Estable> parte de la hiptesis de que lo normal es la estabilidad y se
buscan posibles fuentes de perturbarla. Recordemos que se est analizando la estabili-
dad de la posible pareja H y M, siendo M la mujer que ocupa la posicin R en la lista de
preferencias de H (M f- Phb [H , R 1 ) . Hay dos posibilidades:
1. Puede haber otra mujer Mm, por la que H tenga ms preferencia que M, y a su
vez Mm prefiera ms a H que a su actual pareja.
De forma simtrica.
2. Puede haber otro hombre Hh, por el que M tenga ms preferencia que a H, y a su
vez ese hombre prefiera ms a M que a su actual pareja.
La posibilidad 1 se dilucida comparando los rangos Rhm [Mm, H J YRmh [Mm, F [Mm J J
para todas las mujeres ms preferidas que M por el hombre H. Es decir, para todas las
Mm f- Phb [H, 1 1 tales que 1 < R . Adems, todas estas mujeres tienen ya pareja,
ya que si alguna estuviera soltera el hombre H la hubiera elegido ya. Esta posibilidad
puede expresarse:
Es t able ~ true
1 ~ 1
mientras (1 < R) Y Est able hacer
Mm ~ Phb [ H,I ]
si no so ltera[Mm] entonces
Estable ~ Rmh [ Mm, H] < Rmh [ Mm, F [Mm] ] {Es e s table s i p r e f iere ms }
fin si {a su act u al pare ja }
fin_mientras
1 ~ 1
Tope ~ Rm h[M,H ]
mientras (1 < Tope) y Estab le hacer
Hh ~ P m j [M ,I]
1 ~ 1 +1
si Hh < H entonces { Hh ya tiene par eja }
Est able ~ Rhm [ Hh, M] > Rhm[ Hh , V[H h]] {Es table s i Hh pr efi ere }
fin si { a su actual p areja . }
CODIFICACiN
program MatrimonioEstable;
uses
crt;
const
N = 9; {Nmer o de parejas a formar}
type
Tipohombre = 1 .. N;
Tipomujer = 1 .. N;
Prefhombres = array [Tipohombre, 1 .. Nl of Tipo mu je r;
prefmujeres = array [Tip o muje r , 1 .. Nl of Tipohombre;
Parhombres = array [Tipohombrel of Tip omujer;
procedure Escribir;
var
H: Tipohombre;
begin
write('Solucin: ');
for H := 1 to N do
write('<H', H, ',M', V [H), '>; ');
writeln
end;
RESUMEN
La recursin (recursividad) pellnite resolver problemas cuyas soluciones iterativas son dificiles
de conceptualizar: un procedimiento o funcin que se \lama a s misma. Normalmente, una solu-
cin recursiva es menos eficiente en trminos de tiempo y operaciones suplementarias que entra-
an las \lamadas extra a procedimientos; sin embargo, en numerosas ocasiones el uso de la recur-
sin permite especificar una solucin muy natural y senci\la a problemas que en caso contrario
seran muy difciles de resolver. Por esta razn, la recursividad es una herramienta muy importan-
te y potente para la resolucin de problemas con programacin.
El uso apropiado de la recursividad se debe considerar antes de su utilizacin. Una vez toma-
da la decisin, el programador debe tener mucha precaucin en proporcionar condiciones de ter-
minacin para detener las llamadas recursivas. Es muy fcil entrar en un bucle infinito si no se
incluyen condiciones de terminacin adecuadas.
Algunos lenguajes de programacin no permiten la recursividad. Por consiguiente, un progra-
mador puede desear resolver un problema utilizando tcnicas recursivas mediante el uso de pseu-
docdigo. Incluso, como en el caso de Pascal, que soporta recursividad, el programador puede
tratar de intentar reducir las operaciones y el tiempo auxiliar implicado en el proceso recursivo
simulando la recursividad.
EJERCICIOS
1 si x ~ y
G(x, y) =
G(x-y+I)+l SI Y<x
1 si x = 1
H(x) =
H(x / 2) + 1 si x> I
,
Recursividad: algoritmos recursivos 307
9.4. Eliminar la recursividad de la funcin C(n,k). Escribir la funcin C(n,k) de forma iterativa
utilizando una pila para eliminar la recursividad.
9.5. Dada la siguiente funcin recursiva:
a) Qu hace la funcin ?
b) Hacer un seguimiento con esta llamada: Reves(l).
A(m,n) = n+ l si m = O
A(m,n) = A(m-l,l) si n = O
A(m,n) = A(m-I,A(m,n-l si m > O Y n > O
PROBLEMAS
9.1. En el problema de las 8 reinas se encuentran 92 soluciones diferentes. Hacer los cambios
necesarios en el procedimiento de resolucin para que nos muestre nicamente las solucio-
. , .
nes no slmetncas.
9.2. Escribir un programa que tenga como entrada una secuencia de nmeros enteros positivos
(mediante una variable entera). El programa debe de hallar la suma de los dgitos de cada
entero y encontrar cul es el entero cuya suma de dgitos es mayor. La suma de dgitos ha
de ser con una funcin recursiva.
9.3. Sea A una matriz cuadrada de n x n elementos, el determinante de A podemos definirlo de
manera recursIva:
a) Si n = 1 entonces Deter(A) = al.l'
b) Para n > 1, el determinante es la suma alternada de productos de los elementos de una
fila o columna elegida al azar por sus menores complementarios. A su vez, los menores
complementarios son los detellninantes de orden n-l obtenidos al suprimir la fila y
columna en que se encuentra el elemento.
Podemos expresarlo:
n
Det(A)= L (-ly+J *A[i,j] * Det(Menor(A[i,j])); para cualquier columna}
; = 1
o
n
Det(A)= L (-ly+J *A[i,j] * Det(Menor(A[i,j])); para cualquier fila i
j ~ 1
Se observa que la resolucin del problema sigue la estrategia de los algoritmos divide y
vence.
Escribir un programa que tenga como entrada los elementos de la matriz A, y tenga como
salida la matriz A y el determinante de A. Eligiendo la fila 1 para calcular el determinante.
9.4. Escribir un programa que transforme nmeros enteros en base lOa otro en base B. Siendo
la base B de 8 a 16. La transformacin se ha de realizar siguiendo una estrategia recursiva.
9.S. Escribir un programa para resolver el problema de la sub secuencia creciente ms larga. La
entrada es una secuencia de n nmeros a" a2' a3, ... , a n ; hay que encontrar la subsecuencia
ms larga ail, a2, ... ak tal que a1 < aj2 < a3 ... < ak Y que il < i2 < i3 < ... < ik. El programa
escribir tal subsecuencia.
Por ejemplo, si la entrada es 3, 2, 7, 4, 5, 9, 6, 8, 1, la subsecuencia creciente ms larga
tiene longitud cinco: 2, 4, 5, 6, 8.
9.6. El sistema monetario consta de monedas de valor PI' P2, P3' ... ,Pn (orden creciente) pesetas.
Escribir un programa que tenga como entrada el valor de las n monedas en pesetas, en
orden creciente, y una cantidad X pesetas de cambio. Calcule:
a) El nmero mnimo de monedas que se necesitan para dar el cambio X.
b) Calcule el nmero de formas diferentes de dar el cambio de X pesetas con lap monedas.
Aplicar tcnicas recursivas para resolver el problema.
9.7. Dadas las m primeras del alfabeto, escribir un programa que escriba las diferentes agrupa-
ciones que se pueden formar con n letras (n < m) cada una diferencindose una agrupacin
de otra por el orden que ocupan las letras, o bien por tener alguna letra diferente (en defini-
tiva, formar variaciones Vm,n).
Recursividad: algoritmos recursivos 309
9.8. En un tablero de ajedrez se coloca un alfil en la posicin (xo, Yo) Y un pen en la posicin
(1, ), siendo 1 < = ) < = 8. Se pretende encontrar una ruta para el pen que llegue a la
fila 8 sin ser comido por el alfil. Siendo el nico movimiento permitido para el pen el de
avance desde la posicin (i,) a la posicin (i + 1, ). Si se encuentra que el pen est
amenazado por el alfil en la posicin (i,), entonces debe de retroceder a la fila 1, columna
) + l o) - 1 {(l,) + 1), (1,) - 1)}.
Escribir un programa para resolver el supuesto problema. Hay que tener en cuenta que el
alfil ataca por diagonales.
9.9. Dados n nmeros enteros positivos, encontrar combinacin de ellos que mediante sumas o
restas totalicen exactamente un valor objetivo Z. El programa debe de tener como entrada
los n nmeros y el objetivo Z; la salida ha de ser la combinacin de nmeros con el opera-
dor que le corresponde.
Tener en cuenta que pueden formar parte de la combinacin los n nmeros o parte de
ellos.
9.10. Dados n nmeros, encontrar combinacin con sumas o restas que ms se aproxime a un
objetivo Z. La aproximacin puede ser por defecto o por exceso. La entrada son los n n-
meros y el objetivo y la salida la combinacin ms prxima al objetivo.
9.11. Dados n nmeros encontrar, si existe, la combinacin con los n nmeros que mediante
sumas o restas totalice exactamente el objetivo Z.
9.12. Dados n nmeros, encontrar la combinacin con los n nmeros que mediante sumas o res-
tas ms se aproxime a el objetivo Z.
9.13. Un laberinto podemos emularlo con una matriz n x n en la que los pasos libres estn repre-
sentados por un carcter (el blanco, por ejemplo) y los muros por otro carcter (el # por
ejemplo). Escribir un programa en el que se genere aleatoriamente un laberinto, se pida las
coordenadas de entrada (la fila ser la 1), las coordenadas de salida (la fila ser la n) y
encontrar todas las rutas que nos llevan de la entrada a la salida.
9.14. Realizar las modificaciones necesarias en el problema del laberinto 9.12 para encontrar
la ruta ms corta. Considerando ruta ms corta la que pasa por un menor nmero de ca-
sillas.
9.15. Una regin castellana est formada por n pueblos dispersos. Hay conexiones directas entre
algunos de estos pueblos y entre otros no existe conexin aunque puede haber un camino.
Escribir un programa que tenga como entrada la matriz que representa las conexiones di-
rectas entre pueblos, de tal forma que el elemento M(i,j) de la matriz sea:
Tambin tenga como entrada un par de pueblos (x,y) y encuentre un camino entre ambos
pueblos utilizando tcnicas recursivas. La salida ha de ser la ruta que se ha de seguir para ir
de x a Y junto a la distancia de la ruta.
9.16. En el programa escrito en 9.14, hacer las modificaciones necesarias para encontrar todos
los caminos posibles entre el par de pueblos (x,y).
9.17. Referente al problema 9.14, escribir un programa que genere una matriz P de n x n en la
que cada elemento P(i,j) contiene el camino ms corto entre el pueblo i y el pueblo j. Utili-
, . , . .
zar umcamente tecmcas recursIvas.
9.18. El celebre presidiario Seor S quiere fugarse de la crcel de Carabanchel, por el sistema de
alcantarillado, pero tiene dos problemas:
310 Estructura de datos
1) El dimetro de la bola que arrastra es de 50 cm, resulta demasiado grande para pasar
por algunos pasillos.
2) Los pasillos que comunican unas alcantarillas con otras tienen demasiada pendiente y
slo puede circular por ellos en un sentido.
Ha conseguido hacerse con los planos que le indican el dimetro de salida de las al-
cantarillas, as como el dimetro de los pasillos y el sentido de la pendiente que lo
conectan.
Suponiendo que:
1) El Nmero de alcantarillas es N.
2) El Seor S se encuentra inicialmente en la alcantarilla 1 (dentro de la prisin).
3) Todas las alcantarillas (excepto la 1) tienen su salida fuera de la prisin, si bien puede
que sean demasiado estrechas para sacar la bola fuera.
4) Se puede pasar de un pasillo a otro a travs de las alcantarillas estrechas aunque a
travs de dichas alcantarillas no se pueda salir al exterior.
5) Todos los pasillos tienen un dimetro, si bien ste puede ser demasiado estrecho para
poder pasar con la bola.
Escribir un programa que contenga al menos estos procedimientos:
a) Un procedimiento para generar aleatoriamente los dimetros de los tneles del alcanta-
rillado as como los dimetros de salida de las distintas alcantarillas. (Tenga en cuenta
que si se puede ir de la alcantarilla i a la j por el tnel, entonces no se puede ir por el
tnel desde j hasta i.)
b) Un procedimiento de backtraking que resuelva el problema del seor S.
e) Procedimientos para escribir en pantalla el sistema de conexiones as como la posible
solucn encontrada.
,
CAPITULO
o es In arios
10.1. Concepto
de rbol.
10.2. Arboles binarios.
10.3. Arboles de expresin.
10.4. Construccin de un rbol binario.
10.5. Recorrido de un rbol.
10.6. Aplicacin de rboles binarios: evaluacin de expresiones.
10.7. Arbol binario de bsqueda.
10.8. Operaciones con rboles binarios de bsqueda.
RESUMEN.
EJERCICIOS.
PROBLEMAS.
REFERENCIAS BIBLIOGRFICAS.
311
0,
10.1. CONCEPTO DE ARBOL
Un rbol (en ingls, tree) es una estructura que organiza sus elementos, denominados
nodos, formando jerarquas. Los cientficos utilizan los rboles generales para represen-
tar relaciones. Fundamentalmente, la relacin clave es la de <<padre-hijo entre los nodos
del rbol. Si existe una arista (rama) dirigida del nodo n al nodo m, entonces n es el
padre de m y m es un hijo de n. En el rbol de la Figura 10.1, los nodos B y C son hijos
del nodoA. Los hijos del mismo padre se llaman hermanos, por ejemplo B y C. Cada nodo
de un rbol tiene al menos un padre, y existe un nico nodo, denominado raz del rbol,
que no tiene padre. El nodo A es el raz del rbol de la Figura 10.1. Un nodo que no tiene
hijos se llama hoja del rbol. Las hojas del rbol de la Figura 10.1 son C, D, E Y F.
. , ' "
.". hola
I
La relacin padre-hijo entre los nodos se generaliza en las relaciones ascendiente ,
(antecesor) y descendiente. En la Figura 10.1 A es un antecesor de D, y por consiguien-
te D es un descendiente de A. Obsrvese que no todos los nodos estn relacionados por
las relaciones ascendente/descendiente: B y C, por ejemplo, no estn relacionados. Sin
embargo, el raz de cualquier rbol es un ascendiente de todos los nodos de ese rbol. Un
subrbol de un rbol es cualquier nodo del rbol junto con todos sus descendientes.
Un subrbol de un nodo n es un subrbol enraizado en un hijo de n. Por ejemplo, la
Figura 10.2 muestra un subrbol de la Figura 10.1. Este subrbol tiene a B como su raz
y es un subrbol del nodo A.
A Padre
A
D F
B, e hermanos
Figura 10.1. Arbol general.
-
o
Figura 10.2. Un subrbol del rbol de la Figura 10.1.
Terminologa complementaria
Adems de los trminos ya citados anteriormente, existen otros tambin de gran impor-
tancia.
1 Las definiciones de altura, profundidad y nivel, como se seala en [Franch 93], pg. 220, son contra-
dictorias en algunos textos, que no definen algunos de estos conceptos o los definen slo para un rbol y no
para sus nodos; o bien empiezan a numerar a partir del cero y no del nodo, etc. En nuestro caso y al igual
que hace Franch preferimos numerar a partir del uno para que el rbol vaCo tenga una altura diferente al
rbol con un nico nodo.
Luis y Juana
Luis
(Carchelejo) Juana Mara
Luis
Graciela Victoria
(Madrid)
B B C B
D H
10.2.1. Terminologa
En un rbol binario los hijos se conocen como hijo izquierdo e hijo derecho, lo que
supone automticamente una diferencia. Los dos rboles de la Figura 10.5 no represen-
tan el mismo rbol binario, ya que sus hijos izquierdo y derecho estn en orden inverso.
Un nodo que no tiene hijos se denomina hoja.
Por consiguiente, los nodos H, r, E, F Y J son hojas en el rbol de la Figura 1O.4-b.
Los nodos con descendientes se denominan nodos interiores.
El nodo raz se dice que est en el nivel 1 en el rbol, los nodos B y e estn en el
nivel 2, y los nodos D, E, F Y G estn en el nivel 3. La altura del rbol se define como el
nivel ms alto del rbol. Por consiguiente, la altura del rbol (b) de la Figura 10.4 es 4.
Cualquier nodo sin sucesores se denomina un nodo terminal. Por ejemplo, los no-
dos H, r, E, F, J son todos hojas o nodos terminales, en el rbol 10.4 (b).
En la Figura 10.7, los nodos B, D Y E forman el subrbol izquierdo. De modo similar
C, F y G forlllan el subrbol derecho. Cada uno de estos subrboles es un verdadero
rbol.
Los subrboles izquierdo y derecho de un rbol binario deben ser subconjuntos disjun-
tos de nodos. Esto es, ningn nodo puede estar en ambos subrboles.
1 1
2 3 3 2
I
D Padre
,
,,
,,
I
,,
,
j,
,
,
.- ...... _ - -------
o E F G
A A
B e B e
o E F G o E I
(a) (b)
Figura 10.8. rbol binario: (a) completo; (b) no completo.
, , ,
,
D E F G
I
La altura de un rbol es el nmero de nodos en el camino ms largo desde la raz
a una hoja; dicho de otro modo, la altura de un rbol es el nmero de niveles distintos.
As, en un rbol general T, en trminos de los niveles de sus nodos se define como
sigue:
c_
Figura 10.10. rboles binarios con los mismos nodos pero alturas diferentes.
318 Estructura de datos
Un rbol binario completo de altura h es un rbol binario que est relJeno a partir
del nivel h - 1, con el nivel h relleno de izquierda a derecha (Figura 10.12). Ms formal-
mente, un rbol binario de altura h es completo si:
Todos los nodos de nivel h - 2 Y superiores tienen dos hijos cada uno.
Cuando un nodo tiene un descendiente derecho a nivel h, todas las hojas de su
subrbol izquierdo estn a nivel h .
Figura 10.11. Arbol binario lleno de altura 3.
rboles binarios 319
(d)
,
Figura 10.13. Arbol binario: (a) equilibrado, (b) completamente equilibrado;
(e) y (d) rboles no equilibrados.
320 Estructura de datos
, .
, .- - -
", '"
, ,.',,;', . 1
-_._.- -': '
. .:... _.- ,
:,. ::_---,--- -
,,
En el rbol de la Figura 10.14 los posibles recorridos pueden ser:
,
1
o K
B E H M
J
L
A e F
Figura 10.14. Arbol binario.
I
Arboles binarios 321
+ e
A B
EJEMPLO 10.1
Deducir las expresiones que representan los siguientes rboles binarios
A e
y B A
z
(a) (e)
(b)
322 Estructura de datos
+ -
x y A B
,
Figura 10.16. Arbol de expresin (x+y) * (A - B) .
Solucin
a) X* (Y / - Z )
b) A + [( B *-(C+D )]
e) [A* ( X+Y) J *C
EJEMPLO 10.2
Dibujar la representacin en rbol binario de cada una de las siguientes expresiones
a) X *Y / [ (A+B) * C ]
b) (X*Y l A) + ( B* C)
Solucin
e B e
A B y
(a) (b)
, ,
10.4. CONSTRUCCION DE UN ARBOL BINARIO
Los rboles binarios se construyen de igual forma que las listas enlazadas, utilizando
diferentes elementos con la misma estructura bsica. Esta estructura bsica es un nodo
_ _ _ o __ ~ ~ . _~ _ _ __
, ... "
Arboles binarios 323
+ -
x A B
y z
,
Figura 10.17. Arbol de expresin [x+ ( y*Z) 1* (A-B).
con un espacio de almacenamiento para datos y enlaces para sus hijos izquierdo y
derecho. Existe una diferencia clara con las listas y es el enlace de los nodos; esto se
debe a que el rbol es bidimensional, tiene una estructura de registro ms compleja
y tiene muchos punteros ni 1 frente a uno solo que aparece al final de una lista en-
lazada.
Con este formato cada nodo tiene tres elementos: datos, un puntero izquierdo y un
puntero derecho. Los punteros son otros nodos que llevan a declaraciones muy similares
a las de una lista enlazada.
type
Pt rAr bo l = ANod o Arbol
No doArb ol = record
Da to s:NombreTipo;
Izda, Dch a: PtrA rb o l; ( p unter os a hi j os )
end; (Nod o Ar b o l )
Dada esta definicin, un rbol se puede construir mediante llamadas sucesivas a new,
cada una de las cuales asigna un nodo nuevo al rbol.
La implementacin de un rbol binario comienza disponiendo al principio de una
variable puntero externo T que apunta a la raz del rbol. Si el rbol est vaco, T es
nil. La Figura 10.18 ilustra esta implementacin. La definicin recursiva de un rbol
binario conduce a que cada rbol binario no vaco conste de un subrbol izquierdo y un
subrbol derecho, cada uno de los cuales es un rbol binario. AS, si T apunta a la raz de
un rbol binario, entonces T " . 1 z do apunta a la raz del subrbol izquierdo y T " . De ho
apunta a la raz del subrbol derecho.
324 Estructura de datos
Nombre
Izdo. Ocho .
El procedimiento para crear una hoja de un rbol y una funcin que comprueba si un
nodo es una hoja se muestran a continuacin:
,
10.5. RECORRIDO DE UN ARBOL
Para visualizar o consultar los datos almacenados en un rbol se necesita recorrer el
rbol o visitar los nodos del mismo. Al contrario que las listas enlazadas, los rboles
binarios no tienen realmente un primer valor, un segundo valor, tercer valor, etc. Se pue-
de afirmar que el raz viene el primero, pero quin viene a continuacin? Existen di fe-
,
rboles binarios 325
Segn sea la estrategia a seguir, los recorridos se conocen como enorden (inorder),
preorden (preorder) y postorden (postorder)
preorden (nodo-izdo-dcho) (NID)
enorden (izdo-nodo-dcho) (IND)
postorden (izdo-dcho-nodo) (IDN)
3. Recorrer el subrbol derecho (D).
El algoritmo correspondiente es
En o rden(A)
Si el ar b o l n o e st a v a c ~ o entonces
inicio
Recorrer el su ba r bol izqu ier d o
visitar el n odo raiz
Re corre r el subarbo l d er echo
fin
En el rbol de la Figura 10.19, los nodos se han numerado en el orden en que son
visitados durante el recorrido enorden. El primer subrbol recorrido es el subrbol iz-
quierdo del nodo raz (rbol cuyo nodo contiene la letra B. Este subrbol consta de los
nodos B, D Y E Y es a su vez otro rbol con el nodo B como raz, por lo que siguiendo el
orden IND , se visita primero D, a continuacin B (nodo o raz) y por ltimo E (derecha).
Despus de la visita a este subrbol izquierdo se visita .el nodo raz A y por ltimo se
visita el subrbol derecho que consta de los nodos C, F y G. A continuacin, siguiendo el
orden I ND para el subrbol derecho, se visita primero F, despus C (nodo o raz) y por
ltimo G. Por consiguiente, el orden del recorrido de la Figura 10.19 es D-B-E-A-F-C-G.
326 Estructura de datos
A
Visita de los nodos: D, S, E, A, F, e, G
4
S e
2 6
D E F G
1 3 5 7
A
Visita los nodos : A-B-D-E-C-F-G
1
B C
2 5
o E F G
3 4 6 7
El algoritmo recursivo es
si A n o es ta y ac io entonces
~n~c~o
A
Visita los nodos D-E-B-F-G-C-A
7
B C
3 6
o E F G
1 2 4 5
EJEMPLO 10.3
Deducir los tres recorridos del rbol binario siguiente:
E z
A G p
Solucin
Preorden :MEAGZPQ (NID)
Enorden :AEGMPQZ ( IND)
Postorden :AGEQPZM ( IDN)
const LongMax = 30 (longitud mxima del nombre)
10.6. APLICACiN DE RBOLES BINARIOS:
EVALUACiN DE EXPRESIONES
Una expresin aritmtica est formada por operandos y operadores aritmticos. As, la
.,
expreSlOn
R =(A+B)*D+A*B / D
R est escrita de la forma habitual, el operador en medio de los operando, se conoce
como notacin infija. Recordemos que ya hemos realizado la aplicacin de evaluar una
expresin utilizando nicamente el T AD pila. Ahora va a ser utilizada tanto las pilas
como el T AD rbol binario para la evaluacin. La pila ser utilizada para pasar la expre-
sin de infija a postfija. La expresin en postfija ser almacenada en el rbol para que la
evaluacin se realice utilizando el rbol binario. En primer lugar, recordamos la priori-
dad de operadores, de mayor a menor:
,.
ParenteslS ()
Potencla
A
Multipl / divisin
* I /
Suma / Resta
+, -
Representan distintas expresiones al no poner parntesis. Igual ocurre con las expre-
SlOnes:
330 Estructura de datos
A*B /( A+C) (infija) ~ A*B / AC+ ~ AB* / AC+ ~ AB*AC+ / (polaca inversa)
A*B / A+C (infija) ~ AB* /A+C ~ AB*A /+C AB*A/ C+ (polaca inversa)
(A-B) ~ C+D (infija) ~ AB - ~ C+D AB-C ~+D ~ AB-C~D+ (polaca inversa)
Una vez que se tiene la expresin en postfija la formacin del rbol binario es fcil: se
crean dos nodos del rbol con respectivos operandos que se enlazan como rama izquier-
da y rama derecha del nodo operador. As, la expresin A * B - C * D + H se transforma en
postfija: AB*CD*-H+ y el rbol de la expresin:
.
+
I -
,
.
H
..
i
.
.
,
* *
A B e D
Pasos a seguir
A la hora de evaluar una expresin aritmtica en notacin infija se siguen estos pasos:
l. Transformar la expresin de infija a postfija.
2. Formar a partir de la expresin en postfija el rbol de expresin.
3. Evaluar la expresin utilizando el rbol.
:.
!
..
!
.
rboles binarios 331
En el algoritmo para resolver el primer paso se utiliza una pila de caracteres. Para el
segundo paso se utiliza otra pila y el rbol de caracteres. Y en el tercer paso un vector
con los valores numricos de los operandos que es utilizado para evaluar la expresin en
el rbol.
Partimos de una expresin en notacin infija que tiene operandos, operadores y puede
tener parntesis. Los operandos vienen representados por letras, los operadores van a ser:
A (potenciacin), *, /, +, _ .
unit Pilaptr;
interface
type
PtrA = ANodoAb;
NodoAb = record
e : char;
Izqdo,
Drcho : PtrA
end;
Plaptr = ANodopt;
Nodopt = record
Info: PtrA;
,,
Sgte: Plaptr
end;
,;,
~.
'O"
332 Estructura de datos
R:= A3
end;
9 5
4 9
EJEMPLO 10.4
Arbol binario de bsqueda
55 4 menor que 30
30 menor que 55
41 mayor que 30
75 mayor que 55
30 75 85 mayor que 75 r
I,
,
4 41 85 ,
,
,
,,
,
i'
336 Estructura de datos
8 3 1 20 10 5 4
en un rbol binario de bsqueda. Siguiendo la regla, dado un nodo en el rbol todos los
datos a su izquierda deben ser menores que todos los datos del nodo actual, mientras que
todos los datos a la derecha deben ser mayores que dichos datos. Inicialmente el rbol
est vaco y se desea insertar el 8. La nica eleccin es almacenar el 8 en el raz:
3 20
Cada nuevo elemento se inserta como una hoja del rbol. Los restantes elementos se
3 20
8
1 10
3 20
8
1 5 10
3 20
1 5 10
4
338 Estructura de datos
Una propiedad de los rboles binarios de bsqueda es que no son nicos para los
datos dados .
EJEMPLO 10.5
Solucin
12
8 16
7 11
PROBLEMA 10.1 2
Este programa genera un rbol binario de nmeros enteros con un nmero aleatorio de
nodos y en un rango de valores tambin aleatorio. Se utiliza un procedimiento recursivo
para contar el nmero de nodos del rbol, otro procedimiento para mostrar los nodos
ordenados ascendentemente y un procedimiento de altas para insertar cada nuevo n-
mero generado en su correspondiente nodo.
! Diagrama de estructura
i PROGRAMA
,
! NMERODENODOS
2 Este problema ha sido extrado de la obra Pascal y Turbo Pascal: Un enfoque prctico, de Luis Joya-
nes, Ignacio Zahonero y ngel Hermoso, McGraw-Hill, 1995, y con permiso de los autores.
Arboles binarios 339
CODIFICACiN
program NumeroDeNodos;
{Este programa genera un rbol binario de nmeros enteros, y
posteriormente muestra y cuenta el nmero de nodos}
uses
Crt;
const
MaxNumNodos = 30;
MaximoValor - 100;
type ,
RangoNodos = o, ,MaxNumNodos - 1 ;
TipoClave = l .. Maximovalor;
Punter o = ANodoArbol;
NodoArbol - record
Clave : TipoClave;
Izdo ,
Ocho : Puntero
end;
var
Raiz : Puntero;
NodosGenerados,
NodosContados,
Indi ce : RangoNodos;
Val o r : TipoClave;
funtion Nodos (P : Punt ero) : RangoNodos;
{Funcin recursiva para contar el nmero de nodos del rbol. El nmero de
nodo s es la suma del nmero de nodos de cada uno de sus subrboles
izquierdo y derecho ms el nodo raz}
begin
if P = nil then
Nod os := O
else
Nodos : = 1 + Nodos (PA.lzdo) + Nodos (PA .Dcho)
end;
procedure InOrden (P : Puntero);
begin
if P < > nil then
begin
InOrden (PA .Izd o) ;
Write (p A.C lave : 5);
Inorden (PA.Dcho)
end
end;
NodoAltaA.Dcho := nil;
Padre := nil;
Actual := Root;
while Actual <> nil do
begin
Padre := Actual;
if ActualA.Clave >= Valor then
Actual := ActualA.Izdo
elee
Actual := ActualA.Dcho
end;
if Padre = nil then {se situar como raiz}
Root := NodoAlta
elee
if padreA.Clave >= Valor then
PadreA.Izdo := NodoAlta {se sita a la izquierda}
elee
padreA.Dcho := NodoAlta {se sita a la derecha}
end;
begin
ClrScr;
Randomize;
NodosGenerados := Random (MaxNumNodos);
Raiz : = nil;
Writeln (' conjunto de nodos generados al azar': 52); ,,
for Indice := 1 to NodosGenerados do
begin
Valor := Random (maximoValor) + 1;
Write (valor:5);
Altas (Raiz o valor) {insercin del nodo en el rbol}
end;
WriteLn;
WriteLn;
NodosContados := Nodos (Raiz);
WriteLn( 'recorrido InOrden. Nodos encontrados':65);
InOrden (Raiz); i
WriteLn; I,
WriteLn; ,
]
WriteLn ('Numero de nodos generados: 'o NodosGenerados); 1
,,
;
WriteLn ('Numero de nodos contados: 'o NodosContados) ,
i,
end. ,
I
1
,
!
'1
,
De lo expuesto hasta ahora se deduce que los rboles binarios tienen naturaleza recursi- I
I
va y en consecuencia las operaciones sobre los rboles son recursivas, si bien siempre i
, ,,
, ,I
Insercin de un nodo. !,
,,
Recorrido de un rbol.
Supresin de un nodo.
,
,,
,
I
i,
,,
I
,,
i
1
j
,
Arboles binarios 341
10.8.1. Bsqueda
La funcin de bsqueda de una clave devuelve la direccin del nodo que contiene a
la clave, o bien ni 1 en caso de encontrarse en el rbol.
funct10n busqueda (R: Ptr; x: TipoInfo): Ptr;
var Esta: boolean;
beg1n
Esta:=false;
wh1le not Esta and (R < >nil) do
1f RA.elemento=X then
Esta:=true
el Be 1f RA.elemento >X then
R:= R A. izquierdo
elBe
R:= RA.derecho;
busqueda := R
end;
10.8.2. Insercin I
El mecanismo de enlace del nodo creado con el nodo antecedente se explica tenien-
do presente el significado de paso de parmetros por referencia (var).
La funcin Cr earNo d o reserva memoria y devuelve su direccin.
10.8.3. Eliminacin
La operacin de eliminacin de un nodo es tambin una extensin de la operacin de
bsqueda, si bien es ms compleja que la insercin debido a que el nodo a suprimir
puede ser cualquiera y la operacin de supresin debe mantener la estructura de rbol
binario de bsqueda despus de la eliminacin de datos. Los pasos a seguir son:
l. Buscar en el rbol para encontrar la posicin de nodo a eliminar.
2. Reajustar los punteros de sus antecesores si el nodo a suprimir tiene menos de
dos hijos, o subir a la posicin que ste ocupa el nodo descendiente con la clave
inmediatamente superior o inferior con objeto de mantener la estructura de rbol
binario.
100
25 6
begin
if R=n i l then wr i te ln ( ' No es t l a c l ave' )
elBe if X<R ~ . e le mento then
El i mi na r (R ~. izq uier do , X)
elBe if X>R ~ . e l emento then
El i mi n ar (R~.derec h o, X)
el Be begin
Q : = R;
if Q ~ . de r ec h o = ni l then {No t i ene d os des c end i e n tes}
R : = Q~.i zq u i erd o
el Be if Q~.i z quie rd o = n i l then
R : = Q ~ .de r ec h o
el Be
Ree mpl az a r (Q ~ .i zqu i e rd o) ;
d i s pose(Q)
end
end;
begin
en_orden (p~.izquierdo) ;
Wri te (p ~ . e l emen t o : 6) ;
e n_or den (p~ . de r echo)
end
end;
7 2 15
2 8
1 2
(a)
(b)
6
Figura 10.22. Arboles binarios de diferente altura.
Nota
begin {Altura }
if T = nil then
Al t ura : = O
elee
Altura:=l+Max(Altura(T A.lzdo) , Al t ura(T A.Dc h o))
end; {A l t ura }
RESUMEN
En este captulo se introdujo y desarroll la estructura de datos dinmica rbol. Esta estructura,
muy potente, se puede utilizar en una gran variedad de aplicaciones de programacin.
x
x padre o raz ,
y hijo izquierdo de x
z hijo derecho de x
,
y z
I En un rbol binario, cada elemento tiene cero, uno o dos hijos. El nodo raz no tiene un padre,
~
I
pero s cada elemento restante tiene un padre. X es un antecesor o ascendente del elemento Y.
La altura de un rbol binario es el nmero de ramas entre el raz y la hoja ms lejana. Si el
,
,,
,
rbol A es vaco, la altura es O. La altura del rbol siguiente es 6. El nivelo profundidad de un
,, elemento es un concepto similar al de altura. En el rbol siguiente el nivel de 30 es 4 y el nivel ,
,
, de 36 es 6. Un nivel de un elemento se conoce tambin como profundidad.
,
, Un rbol binario no vaco est equilibrado totalmente si sus subrboles izquierdo y derecho
tienen la misma altura y ambos son o bien vacos o totalmente equilibrados.
- -- - - - J
rboles binarios 347
60
-
37
75
25
62
15 30
69
28 32
36
Los rboles binarios presentan dos tipos caractersticos: rboles binarios de bsqueda y r-
boles binarios de expresiones. Los rboles binarios de bsqueda se utilizan fundamentalmente
para mantener una coleccin ordenada de datos y los rboles binarios de expresiones para almace-
nar expresIOnes.
EJERCICIOS
10.1. Considrese el rbol siguiente:
a) Cul es su altura?
b) Est el rbol equilibrado? Por qu?
e) Listar todos los nodos hoja.
d) Cul es el predecesor inmediato (padre) del nodo U?
e) Listar los hijos del nodo R.
j) Listar los sucesores del nodo R.
,1
s
T v
w
x
348 Estructura de datos
10.2. Explicar por qu cada una de las siguientes estructuras no es un rbol binario:
A A
B e B B e
D E F E D
D
.
1. M,Y,T,E,R
2. R,E,M,Y,T
3. T,Y,M,E,R
4. C,O,R,N,F,L,A,K,E,S
a) Dibujar el rbol binario de bsqueda que se construye cuando las letras se insertan en
el orden dado.
b) Realizar recorridos enorden, preorden y postorden del rbol y mostrar la secuencia de
letras que resultan en cada caso.
10.4. Para los rboles del ejercicio 10.1, recorrer cada rbol utilizando los rdenes siguientes:
NDI, DNI, DIN.
10.5. Dibujar los rboles binarios que representan las siguientes expresiones:
a) (A+B) I (C-O)
b) A+B+C / 0
e) A- (B- (C-D) I (E+F))
d) (A+B) * ((C+D) / (E+F))
e) (A-B) / ((C*D) - (E / F))
10.7. Escribir una funcin recursiva que cuente las hojas de un rbol binario.
10.8. Escribir un programa que procese un rbol binario cuyos nodos contengan caracteres y a
partir del siguiente men de opciones:
'- - ----------------.----------------------------------------_ ...
PROBLEMAS
10.1. Crear un archivo de datos en el que cada lnea contenga la siguiente informacin:
Columnas 1-20 Nombre
21-31 Nmero de la Seguridad Social
32-78 Direccin
Escribir un programa que lea cada registro de datos de un rbol, de modo que cuando el
rbol se recorra utilizando recorrido en orden, los nmeros de la seguridad social se orde-
nen en orden ascendente. Imprimir una cabecera DATOS DE EMPLEADOS ORDENA-
DOS POR NUMERO SEGURIDAD SOCIAL. A continuacin se han de imprimir los tres
datos utilizando el siguiente formato de salida:
Columnas 1-11 Nmero de la Seguridad Social
25-44 Nombre
58-104 Direccin
10.2. Escribir un programa que lea un texto de longitud indeterminada y que produzca como
resultado la lista de todas las palabras diferentes contenidas en el texto, as como su fre-
cuencia de aparicin.
10.3. Se dispone de un rbol binario de elementos de tipo integer. Escribir funciones que cal-
culen:
a) La suma de sus elementos.
b) La suma de sus elementos que son mltiplos de 3 .
10.4. Escribir una funcin booleana IDENTICOS que pellnita decir si dos rboles binarios son
iguales.
10.5. Escribir un programa que tenga como entrada de datos el archivo generado en el proble-
ma 10.1; de forma interactiva permita:
,
REFERENCIAS BIBLlOGRAFICAS
Aho, Alfred v., y Ullman, Jeffrey D.: Foundations ofComputer Science, Computer Science Press,
1992.
,
Cormen, Thomas H.; Leiserson Charles, E. , y Rivert Ronal, L.: lntroduction fo Algorithms, The
,
, Mit Press, McGraw-Hill, 1992.
,
Carrasco, Hellman y Veroff: Data Structures and problem solving with Turbo Pascal, The Benja-
min/Cummings, 1993.
I
!
!
,;
,
I - - - - -- - - - - -- - - - - - - - - - - - - - -
rboles binarios 351
UII
. '. ' .. . , J '. , ','", ' , ,,, .. "
..
, "J ,',", .
CONTENIDO
11.1. Eficiencia
, de la bsqueda en un rbol binario.
11.2. Arbol binario equilibrado (AVL).
11.3. Creacin de un rbol equilibrado de N claves.
11.4. Insercin en rboles equilibrados. Rotaciones.
11.5. Eliminacin de un nodo en un rbol equilibrado.
11.6. Programa para manejar un rbol equilibrado.
RESUMEN.
EJERCICIOS.
PROBLEMAS.
pulacin son el motivo central de este captulo. Los mtodos que des-
,
criben este tipo de rboles fueron descritos en 1962 por los matemti-
cos rusos G. M. Adelson-Velskii y E. M. Landis.
,
,
,
La eficiencia para una bsqueda de una clave en un rbol binario de bsqueda vara
353
354 Estructura de datos
Sin embargo, si la mitad de los elementos insertados despus de otro con clave K
tienen claves menores de K y la otra mitad claves mayores de K, se obtiene un rbol
equilibrado (tambin llamado balanceado), en el cual son suficientes un mximo de
Lag 2 (n) comparaciones para obtener un elemento.
Como resumen, en los rboles de bsqueda el nmero promedio de comparaciones
que debe de realizarse para localizar a una determinada clave es N/ 2. Esta cifra en el
rendimiento de la bsqueda resulta ser poco eficiente.
Para mejorar el rendimiento en la bsqueda surgen los rboles equilibrados.
,
11.2. ARBOL BINARIO EQUILIBRADO (AVL)
La altura o profundidad de un rbol binario es el nivel mximo de sus hojas. La altura de
un rbol nulo se considera cero.
Un rbol equilibrado es un rbol binario en el cual las alturas de los dos subrboles
para cada nodo nunca difieren en ms de una unidad. A los rboles equilibrados tambin
se les llama rboles AVL en honor de Adelson- Velskii-Landis que fueron los primeros
en proponer y desarrollar este tipo abstracto de datos.
La Figura 11.2 nos muestra un rbol AVL.
R
......,0
L
Figura 11.2. Arbol binario equilibrado (AVL).
rboles equilibrados 355
, ,
11.3. CREACION DE UN ARBOL EQUILIBRADO DE N CLAVES
Considerando la formacin de los rboles balanceados, se parecen mucho a la secuencia
de los nmeros de Fibonacci:
No = O
N = 1
Nh = N h . + 1 + N h. 2
Para conseguir un rbol AVL con un nmero dado, N, de nodos hay que distribuir
equitativamente los nodos a la izquierda y a la derecha de un nodo dado. En definitiva,
es seguir la relacin de recurrencia anterior, que podemos expresar recursivamente:
R :P trae ;
N :i n te ger ;
factor de equilibrio de los restantes nodos, debido a que dicho factor queda como el que
tena antes de la insercin, pues el efecto de la reestructuracin hace que no aumente la
altura.
Las violaciones del factor de equilibrio de un nodo pueden darse de cuatro maneras
distintas. El reequilibrio o reestructuracin se realizan con un desplazamiento particular
de los nodos implicados, rotando los nodos. Hay rotacin derecha (D) de un nodo y
rotacin izquierda de un nodo (I).
Los cuatro casos de violacin del balance de un nodo los mostramos en las siguien-
tes figuras, as como la reestructuracin que equilibra el rbol:
a) El rbol original
....... -1
B o
,, """' -2
e
-1
A o
b) El rbol original
A
,
.......0
I B
....... 0
rboles equilibrados 359
c) El rbol original
........ 0
........ -1
d) El rbol original
""""'-1
e
,......., -2
B o
A
360 Estructura de datos
Restructurar el rbol implica mover, rotar los nodos del mismo. Las rotaciones pue-
den considerarse simples o compuestas. La rotacin simple involucra a dos nodos,
la rotacin compuesta involucra a tres nodos. Las rotaciones simples se realizan, o
bien por las ramas DD o 1 1. Las rotaciones compuestas se realizan por las ramas DI
o ID .
o -1
,,-.. o
68
45 o
29 o
Una vez insertado el nodo con la clave 29, al regresar por el camino de bsqueda
cambia los factores de equilibrio, as el del nodo 45 pasa a -1, Y en el nodo 68 se
pasa a -2. Se ha roto el criterio de equilibrio y debe de reestructurarse. Al ser
los factores de equilibrio -1 y -2 debe de realizarse una rotacin de los nodos JI
para rehacer el equilibrio. Los movimientos de los punteros para realizar esta ro-
tacin 11
,,-.. o
45
29 o
rboles equilibrados 361
........ 01
45
_12
29 o 29 o 68 .... n
-o ......... 01
75 .... n1
90 o
Una vez insertado el nodo con la clave 90, a la derecha del nodo 75, y regresar por
el camino de bsqueda para as calcular los nuevos factores de equilibrio, se ob-
serva que dicho factor queda incrementado en 1 pues la insercin ha sido por la
derecha. En el nodo con clave 68 queda roto el equilibrio. Para reestructurar se
realiza una rotacin DD. Los movimientos de los punteros para realizar esta rota-
clOn DD:
n A. Drcho nl A
. Iz qd o
nl A.Iz qdo n
n nI
Una vez realizada la rotacin, los factores de equilibrio de los nodos implicados
ser O, como ocurre en todas las rotaciones simples, el rbol queda como sigue:
........ 1
45
-o
68 o
Insercin de la clave 70
........ 12
45 .... n
.........0-1
75 .... n1
......... 0
n2
Para insertar el nodo con la clave 70 se sigue el camino: derecha de 45, izquierda
de 75 y se inserta por la derecha del nodo 68. Al regresar por el camino de bs-
362 Estructura de datos
nl A .Izqdo f- n2 A .Drcho
n2 A .Drch o f- ni
n A.Drcho f- n2 A .Izqdo
n2 A .Izqdo f- n
n f- n2
valor antes de la insercin del nodo referenciado por n2 segn esta tabla:
,
si
nA. Fe f- O O -1
ni FeA f- 1 O O
n2 .Fe
A
f- O O O
Insercin de la clave 34
n --. 45 -1-2
90
I
rboles equilibrados 363
n1 A . Drcho ~ n 2 A . lzqdo
n2 . lzqdo
A
~ n1
nA . lzqdo n2 A . Drcho
n 2 A . Drc ho ~ n
n ~ n2
si n2 A
. Fe= O n2 A .F e= 1
n A.F e ~ 1 O O
n 1 . Fe
A
~ o O -1
n 2 Fe
A
~ O O O
begin
new(Nuevo) ;
with Nuevo A do
,
364 Estructura de datos
begin
Inf o : =x;
Izqd o :=nil;
Drc h o := n i l ;
Fe := O
end;
Crear : =Nuevo
end;
Nl ~ .Fe:=O
end
elee begin
NA. Fe:= 1;
N1 A .F e := - 1
end;
N: =N1 ;
end;
NA.Fe:= O;
NI A .Fe:=O
end
el Be begin
NA.Fe: = -1;
NI A.F e: = 1
end;
N:=N l ;
end;
o: R A.F e := - l;
-1: begin (hay que reestru c tur a r ya que
( t ipos de Rotacin)
A
if (N1 .F e = 1) then {Rotacin dd}
Rot ac i o n_dd(R, NI)
elee (Rotac in d i)
Rotacion_di(R,N1) ;
hh := false;
end
end
end
elee begin ( x = RA. l nf o )
write ln ('No est p r ev ist o i nse rt a r claves repe t i das ' ) ;
hh:=false
end
,, end;
,
!;
, ,
Una vez eliminado el nodo siguiendo los criterios establecidos anteriormente, se re-
gresa por el camino de bsqueda calculando los nuevos factores de equilibrio (Fe) de los
nodos visitados. Si en alguno de los nodos se viola el criterio de equilibrio, debe de
restaurarse el equilibrio.
En el algoritmo de insercin, una vez que era efectuada una rotacin el proceso ter-
minaba ya que los nodos antecedentes mantenan el mismo factor de equilibrio. En la
eliminacin debe de continuar el proceso puesto que se puede producir ms de una rota-
cin en el retroceso realizado por el camino de bsqueda, pudiendo llegar hasta la raz
del rbol.
En los procedimientos se utiliza el argumento boolean hh, ser activado cuando la
altura del subrbol disminuya debido a que se haya eliminado un nodo, o bien porque al
reestructurar haya quedado reducida la altura del subrbol.
,........ -1
-1
69
En el rbol de la figura va a ser eliminado el nodo con la clave 42: al ser un nodo
hoja el borrado es simple, se suplime el nodo. Al volver por el camino de bsqueda para
determinar los Fe, resulta que el Fe del nodo con clave 39 pasara a ser -2 ya que ha
decrementado la altura de la rama derecha, es violado el criterio de equilibrio. Hay que
reestructurar el rbol de raz 39.
-1 -2
Rotacin i i porque
39 ~n nA.Fe ~ (-1-1) Y n 1 A .Fe <= o
n1
11
Estructura de datos
,,-...-1
55
-1
Ahora se elimina el nodo con la clave 21. Al tener dos ramas, toma el nodo ms a la
derecha de la rama izquierda que es el de clave 11. Al volver por el camino de bsqueda
para calcular los Fe, el factor de equilibrio del nodo 11 pasara a ser 2 y por tanto hay
reestructurar el rbol de raz 11.
Rotacin di porque
12 n A. Fe ~ (1 +1) y n1 A . Fe < o
26 . - n2
I
Arboles equilibrados 369
,.....1
65
.........1
58
73
..... n2
370 Estructura de datos
67
62 73 86
~-- - - - - -- - - - - ------------ - - - -
rboles equilibrados 371
var
q:Ptrae;
procedure bor(var d: Ptr ae ; var hh: boolean);
begin
if dA.Drcho<>nil then 1
begin
bor(dA.Drcho, hh);
if hh then (Ha disminuido rama derecha)
Equilibra r2 (d, hh)
end
else begin
q A.lno:=
. f dA.ln f o ;
q:=d;
d: =d A.l zqdo;
hh:= true
end
end;
,
begin
if not ArbolVacio(R) then
if x < RA. in fo then
372 Estructura de datos
begin
bor r ar _ bal an ceado(R A. Izqdo, hh, x);
if h h then
Equi l ibr ar l(R , hh)
end
else if x>R A.in fo then
begin
bo rra r _ balanceado(R A. Drcho , hh , x ) ;
if h h then
Equil i brar2(R , h h)
end
else begin {Ha sido e n c o n trado el n od o}
q:=R;
if q A.D r cho= nil then
begin
R := q A.lzqdo ;
h h : = true {D is mi n uy e la altura}
end
else if q A. l z q do =n il then
begin
R: =q A. Drc h o ;
h h : = true
end
el se begin
bo r( qA . lzqdo, hh ) ;
if h h then
Equi l i b r arl (R, h h)
end;
d is pos e (q) ;
end
end;
, ,
11.6. MANIPULACION DE UN ARBOL EQUILIBRADO
unit u Av l ;
interface
type
T i poinfo = integer ;
Ptr a e = ANod o ae ;
Nodoae = record
Info : Tipoinfo;
Fe : -1. .1 ;
-
RESU N
Un rbol AVL o equilibrado es un rbol binario de bsqueda en el que las alturas de los subrbo-
les izquierdo y derecho del raz difieren a lo sumo en uno y en los que los subrboles izquierdo y
derecho son, a su vez, rboles equilibrados.
Arboles equilibrados "
Insercin de un nodo. Se puede insertar un nuevo nodo en un rbol equilibrado utilizando en ,
primer lugar el algoritmo de insercin de rbol binario, comparando la clave del nuevo nodo !
con el raz e insertando el nuevo nodo en el subrbol izquierdo o derecho apropiado. i
,
Supresin de un nodo. La supresin de un nodo x de un rbol equilibrado requiere las mismas
ideas bsicas, incluyendo rotaciones simples y dobles, que se utilizan por insercin. ~
,
Arbol de Fibonacci. Es un rbol equilibrado que se define as:
1
,
l. Un rbol vaco es el rbol de Fibonacci de altura O. j
1
1
1
I, i
1
l
1
!
1
I
,
Arboles equilibrados 377
EJERCICIOS
11.1. Dibuje el rbol AVL T que resulta de insertar las claves 14,6, 24,35,59, 17,21,32,4, 7,
15, 22 partiendo de un rbol vaCo.
11.2. Dada la secuencia de claves enteras: 100,29, 71,82,48, 39, 101,22, 46, 17, 3,20, 25, 10.
Dibujar el rbol avl correspondiente. Eliminar claves consecutivamente hasta encontrar un
desequilibrio cuya restauracin sea del tipo rotacin simple, rotacin compuesta.
11.3. En el rbol T resultante del ejercicio 11.1 realiza eliminaciones consecutivas de claves y
reequilibrios, si fueran necesarios, hasta encontrar una rotacin compuesta.
11.4. Tenemos que el rbol equilibrado B est vaCo. Encontrar una secuencia de n claves que al
ser insertadas siguiendo el procedimiento descrito en el captulo, se realicen al menos una
vez las distintas rotaciones: 11, DD, ID, DI. Cul es el valor mnimo de n para una secuen-
cia del tipo descrito?
11.5. Encontrar un rbol equilibrado con n claves de tal forma que despus al eliminarlas se
realicen las cuatro rotaciones para restablecer el equilibrio.
11.6. a) Cul es el nmero mnimo de nodos en un rbol equilibrado de altura lO? b) Generali-
zando, cul es el nmero mnimo de nodos de un rbol equilibrado de altura n?
11.7. El procedimiento de insertar una clave en un rbol equilibrado est escrito de manera re-
cursiva. Escribir el procedimiento de insertar en un rbol equilibrado de forma iterativa.
11.8. Escribir el procedimiento de borrar una clave en un rbol equilibrado de forma iterativa.
PROBLEMAS
11.1. Se quiere leer un archivo de texto y almacenar en memoria todas las palabras de dicho
texto y su frecuencia. La estructura de datos va a ser tal que permita realizar una bsqueda
en un tiempo O(logn), sin que dependa de la entrada de datos, por lo que se requiere utili-
zar un rbol av!. El archivo de texto se llama carta.dat, se pide almacenar dicho texto en
memoria, utilizando la estructura de rbol indicada anteriormente. Posteriormente se ha de
realizar un procedimiento, que dada una palabra nos indique el nmero de veces que apa-
rece en el texto.
11.2. En un archivo de texto se encuentran los nombres completos de los alumnos del taller de
teatro de la universidad. Escribir un programa que lea el archivo y forme un rbol binario
de bsqueda con respecto a la clave apellido. Una vez formado el rbol binario de bsque-
da, formar con sus nodos un rbol de fibonacci Tn.
11.3. Los n pueblos del distrito judicial Lupianense estn dispuestos en un archivo. Cada regis-
tro del archivo tiene el nombre del pueblo y el nmero de sus habitantes. Escribir un pro-
grama para disponer en memoria los pueblos de la comarca de la siguiente forllla: en un
vector almacenamos el nmero de pueblos, cada elemento del vector tiene el nombre del
pueblo y la raz de un rbol AVL con los nombres de los habitantes de cada pueblo. Al no
estar los habitantes almacenados en el archivo se tienen que pedir por entrada directa al
usuano.
Nota: Como es conocido el nmero de nodos de cada rbol AVL, aplicar la construccifm
de rbol de fibonacci.
11.4. Al problema 11.3 se desea aadir la posibilidad de manejar la estructura. As , aadir la
opcin de cambiar el nombre de una persona de un determinado pueblo; habr que tener
en cuenta que esto puede suponer que ya no sea un rbol de bsqueda, por ello ser nece-
378 Estructura de datos
sario eliminar el nodo y despus crear otro nuevo con la modificacin introducida. Tam-
bin queremos que tenga la opcin de que dado el pueblo A y el pueblo B, se elimine el
pueblo A aadiendo sus habitantes al pueblo B; en cuyo caso hay que liberar la memoria
ocupada por los habitantes de A.
11.5. Un archivo F contiene los nombres que formaban un rbol binario de bsqueda equi-
librado R, y que fueron grabados en F en el transcurso de un recorrido en anchura de R.
Escribir un programa que realice las siguientes tareas: a) Leer el archivo F para recons-
truir el rbol R. b) Buscar un nombre determinado en R, en caso de encuentro mostrar la
secuencia de nombres contenidos entre la raz de R y el nodo donde figura el nombre
buscado.
11.6. Una empresa de servicios tiene tres departamentos, comercial (1), explotacin (2) y comu-
nicaciones (3). Cada empleado est adscrito a uno de ellos. Se ha realizado un redistribu-
cin del personal entre ambos departamentos. El archivo EMPRESA contiene en cada re-
gistro los campos Nmero-Idt, Origen, Destino. El campo Origen toma los
valores 1, 2, 3 dependiendo del departamento inicial al que pertenece el empleado. El
campo Destino toma los mismos valores, dependiendo del nuevo departamento asignado
al empleado. El archivo no est ordenado. Escribir un programa que almacene los registros
del archivo EMPRESA en tres rboles AVL, uno por cada departamento origen, y realice el
intercambio de registros en los rboles segn el campo destino .
,
CAPITULO
,,
o es
-- ..- - - - 0 ,- '
.. . _ ..
" . . .. ,.
CONTENIDO
,
rboles B para la bsqueda por clave de datos comprimidos.
,
,
,
Es costumbre denominar a los nodos de un rbol B, pgina. Cada nodo, cada pgina, es
una unidad a la que se accede en bloque.
Las estructuras de datos que representan un rbol B de orden m tienen las siguientes
, .
caractenstlcas:
379
380 Estructura de datos
I L S X
....... .......
A e D J K M o Q R T U Y Z
type
Ti poclave= I
Ptrb= ~ Pagina;
posicion = O.. Max;
Pag ina = record
Cuenta : O .. max;
Claves: array [1 .. max] of Tipoclave;
Ramas: array [Posi c i on] of Ptrb;
end;
La razn de indexar Ramas desde O est en que cada pgina tiene un nmero de
ramas igual al de claves ms 1, Y que es la forma ms fcil de acceder a la rama ms a la
izquierda.
6 11 5 4 8 9 12 21 14 10 19 28 3 17 32 15 16 26 27
382 Estructura de datos
Con las cuatro primeras se completa el primer nodo (recordar que tambin es lla-
mado pgina), eso s, ordenadas crecientemente a la manera de rbol de bsqueda.
4 5 6 11
L.
4 5 8 11
4 5 8 9 11 1 2
La clave 21 sigue por el camino de bsqueda, derecha del nodo raz. El nodo
donde debe de insertarse est lleno, se parte en dos nodos, y la clave mediana 11
asciende por el camino de bsqueda para ser insertada en el nodo raz:
6 11
4 5 8 9 12 21
Las siguientes claves, 14, 10, 19, son insertadas en los nodos de las ramas que
se corresponden con el camino de bsqueda:
6 11
4 5 8 9 10 12 1 4 19 21
6 11 19
4 5 8 9 10 12 14 2 1 28
6 11 1 9
~ ...
3 4 5 8 9 10 12 14 1 5 17 21 28 32
Al llegar la clave 16, baja por el camino de bsqueda (rama derecha de clave
11 en nodo raz). El nodo donde va a ser insertado est lleno. Se produce la divi-
sin en dos del nodo y la ascensin de la clave mediana 15:
6 11 1 5 19
3 45 8 9 10 12 14 16 17 21 28 32
Por ltimo, al insertar las claves 26 Y 27, primero se llena el nodo ms a la dere-
cha del ltimo nivel con la clave 2 6. Con la clave 27, que sigue el mismo camino
de bsqueda, ocurre que provoca que se divida en dos el nodo y ascienda al nodo
padre la clave mediana 27. Ahora bien, ocurre que el nodo padre tambin est
lleno por 10 que tambin se divide en dos, sube la clave mediana 15, pero como el
nodo dividido es la raz, con esta clave se forma un nuevo nodo raz: el rbol ha
crecido en altura. El rbol crece hacia arriba, hacia la raz.
15
lo ...
, r
6 11 19 27
345 8 9 10 1 2 14 16 17 2 1 26 28 32
En esta formacin de rbol B que hemos ido realizando podemos observar estos dos
hechos relevantes:
l
384 Estructura de datos
el Raz
Inserta
t
EmpujaArriba t Mdna
Empujar
Rama?
vacla
Si
Mdna XR
R,
R Mdna
BuscarNodo MeterHoja DividirNodo
El procedimiento de insercin recibe la clave nueva y la raz del rbol B. Este proce-
dimiento pasa control al procedimiento empujar que baja por el camino de bsqueda
determinado por Buscarnodo, hasta llegar a un nodo hoja. El procedimiento Me-
terHoj a realiza la accin de aadir la clave en el nodo. Si el nodo tiene ya el mximo
de claves, es llamado el procedimiento dividimodo para que a partir del nodo lleno se
formen dos nodos y ascienda la clave mediana.
rboles B 387
Procedimiento MeterHoj a
A este procedimiento se llama cuando ya se ha determinado que hay hueco para aadir
a la pgina una nueva clave. Se le pasa como argumentos la clave, la direccin de la
pgina (nodo), la direccin de la rama con el nodo sucesor, y la posicin a partir de la
cual se inserta.
..
388 Estructura de datos
Claves [K+l J : = X;
Ramas[K+IJ:= Xder;
Cuenta:= Cuenta+l
end
end;
procedure DividirNodo(X:Tipoclave;Xder,P:Ptrb;K:Posicion;
var Mda: Tipoclave; var Mder:Ptrb);
var
I, Posmda: Posicion;
begin
if K <= Min then {Min es la posicin central}
{La clave se situa a la izquierda}
Posmda:= Min
else
Posmda:= Min+l;
new(Mder) ; { Nuevo nodo }
with PAdo
begin
for I:= Posmda+l to Max do
begin
Mder A . Claves [I-PosmdaJ : =Claves [IJ ; {Es desplazada la mitad
derecha al nuevo nodo,la clave mediana se queda en nodo
izquierda}
MderA.Ramas[I- PosmdaJ:= Ramas[IJ i
end; ,
,j,
!
MderA.Cuenta:= Max- Posmda; {Claves en el nuevo nodo} ,
'j
j
Cuenta:=Posmda;{Claves que quedan en nodo izquierda} "
,,
I
{Insercin de clave X y su rama derecha} ..
if K<= Min then
Meterhoja(X,Xder,P,K) {inserta en nodo izquierda}
el se
Meterhoja(X, Xder, Mder, K-Posmda);
,,
,i,
{extrae mediana. del nodo izquierdo} ,:1
Mda:= Claves [CuentaJ ; i
MderA.Ramas[OJ:= Ramas [CuentaJ ; {Ramao del nuevo nodo es la rama de .,i,
i
la mediana} !
Cuenta:= Cuenta-l {Disminuye ya que se quita la mediana} l,
end I
end; I i
,,I
I
, ,
,I
!
j
!
Arboles B 389
La versin no recursiva utiliza una pila para almacenar la direccin del nodo y el
ndice de la rama.
procedure Inord en B (R : P trb) ;
var
1 :in t eg er ;
P : Pt rb;
Pila : p trpla ;
begin
Pcrear(Pila) ;
P := R ;
repeat
l := O;
while not Arb olvac io(P ) do
begin
Pmeter(P , I, Pila ) ;
P : = PA .R amas[ Il
end;
if not Pvacia(pila) then
begin
Psa c ar( P, l, Pil a ) ;
1: = 1+ 1;
if l <= pA . Cuenta then
begin
wr i te l n(PA . Clavesl I l ) ; { P r oce so d e l a clavel
if 1 < pA .C uenta then
Pme te r ( P , 1, Pi 1 a) ;
P: = P A.Ramas [ I ]
end
end
until Pvac ia( Pi la) an d Ar bolvacio(P)
end ;
390 Estructura de datos
, ,
12.7. ELlMINACION DE UNA CLAVE EN UN ARBOL B
DE ORDEN m
Al igual que las inserciones de una clave siempre se hacen en una pgina hoja, las elimi-
naciones siempre se harn en una pgina hoja. Es evidente que una clave no tiene por
qu estar en un nodo hoja, para eIlo se aplica la siguiente caracterstica de los rboles B:
si una clave no est en una hoja, su clave predecesora o sucesora (predecesora o suceso-
ra en el orden natural) estar en un nodo hoja.
. 45
..
16 26 79 172
5 9 15 18 22 24 29 3 2 4 8 57 82 126 192 2 32
Una primera consecuencia es que si la clave a eliminar no est en una hoja, se pondr
I
a la clave predecesora en la posicin ocupada por la clave eliminada y se suprimir la
clave en la hoja. As se observa la figura con el rbol B de orden 5.
Se quiere eliminar la clave 1 6, esta clave no est en una hoja; el sucesor inmediato
de 16 , que es 1 8, se pone en la posicin de 1 6 y luego 1 8 se suprime en el nodo hoja en
que se encuentra:
. 45
..
18 26 79 172
5 9 15 22 2 4 29 32 48 57 82 126 1 92 23 2
que el rbol siga siendo un rbol B: se procede a examinar las hojas inmediatamente
adyacentes al nodo con el mismo antecedente. Si una de estas hojas tiene ms del nme-
ro mnimo de claves, puede moverse una de eIlas para as restablecer el mnimo de clave.
Para que las claves del rbol sigan dividiendo a las claves de sus nodos descendientes a
la manera de rbol de bsqueda, el movimiento de claves consiste en subir una clave al
, _,~_ o.
rboles B 391
nodo padre para que a su vez descienda de ste otra clave al nodo que se quiere restaurar.
As queda restaurado el nodo y sigue siendo un rbol B.
En el rbol resultante de la eliminacin anterior se elimina ahora la clave 2 4. El
nodo que la contiene tiene dos claves, entonces se elimina la clave y se analiza los nodos
contiguos del mismo antecedente. Resulta que en el nodo izquierda tiene tres claves, por
lo que asciende la clave 1 5 al nodo padre, y a su vez de ste desciende la clave 1 8 para
ser insertada en el nodo a restaurar. El rbol resultante:
L
45
..
.,
15 26 79 1 72
5 9 18 22 29 32 48 57 82 1 26 192 232
An queda otro caso ms complejo que los dos anteriores. Al eliminarla clave 22
del nodo hoja, ste se queda con una menos que el mnimo y las dos hojas contiguas
tienen nicamente el mnimo de claves. La estrategia a seguir en este caso: se toma la
hoja a eliminar, su contigua y la clave mediana de ambas, procedente del nodo antece-
dente, y se combinan como un nuevo nodo hoja. Claro est que esta combinacin puede
dejar al nodo antecedente con un nmero de claves menor que el mnimo, entonces el
proceso se propaga hacia arriba, hacia la raz. En el caso lmite, la ltima clave ser
extrada de la raz y luego disminuir la altura del rbol B.
Partiendo del ltimo rbol B, ahora queremos eliminar la clave 22. El nodo donde se
encuentra se queda con una sola clave, y los nodos adyacentes tienen justamente el m-
nimo de claves. La siguiente combinacin restaura al nodo:
1 5 26
5 9 18
L
45
..
r
26 79 17 2
5 9 1 5 18 29 3 2 48 57 82 12 6 192 23 2
Este proceso ha dejado al nodo antecedente con una sola clave, menos que el mnimo
necesario. El proceso se propaga al nivel anterior, producindose esta combinacin:
392 Estructura de datos
45
26 79 17 2
26 45 79 122
5 9 15 18 29 3 2 4 8 57 82 12 6 192 232
CI Raz
Eliminar
CI.
,,
Raz t Encontrar
EliminarRegistro
Act
K K K
K
Encontrar
BuscarNodo Quitar Sucesor r--R-e-s-ta....
b-Ie-ce-r- Restaura el nodo
act t Ramas [K]}
Act
{Elimina la clave {Reemplaza
en nodo hoja} clave por la
que le sucede}
K
Mover Mover
Combina
derecha izquierda
Procedimiento Eliminar
El procedimiento E l i minar tiene la misma estructura que I nse rtar. Tiene como
misin principal devolver la nueva raz si la raz inicial se ha quedado sin claves.
Procedimiento EliminarRegistro
Este procedimiento controla el proceso de borrado de una clave. Primero busca el nodo
donde se encuentra la clave a eliminar. Si el nodo es una hoja, llama a la rutina que
elimina. De no ser hoja, es hallado el inmediato sucesor de la clave, se coloca en el nodo
donde se encuentra la clave; despus se suprime la clave sucesor en el nodo hoja.
La forma ms fcil de expresar este proceso es la recursiva; al retornar la llamada
recursiva debe de comprobar si hay un nmero de claves suficientes, mayor o igual que
el mnimo necesario (2 en el caso de rbol B de orden 5), de no ser as hay que mover
claves al nodo para alcanzar el nmero necesario de claves.
procedure Eli minarRegistro(el : T i poc l ave ; R : Ptrb;
var En con t rado : boo l ean) ;
var
K: Posic i o n;
begin
if Arbolvac io (R) then
Encon trado:= false {Se ha l l e gado "d ebajo " de una h oj a, la c l ave no
est e n el rbo l }
elae with R A do
begin
Buscarno d o(el, R, Enc on trado , K) ;
if Encontrado then
if Ra mas [ K-l ]= n i l then {L as r amas estn i n d e xadas desde n dice O
a Max, por 10 que este n odo es h oja}
Qu ita r (R, K)
elae begin {No e s ho ja}
Sucesor(R , K); {Reemp l aza e l aves [ K)por su sucesor}
Elimi n arRegistr o(C l a ves [ K] , Ra mas[K ] , Encontrado) ; {Elim i na la
c lave suceso r a e n su nodo}
394 Estructura de datos
Procedimiento Sucesor
En esta rutina se busca la clave inmediatamente sucesor de la clave K, que por la propie-
dad de los rboles B est en una hoja, y sta reemplaza a la clave K.
procedure Sucesor(P: Ptrb; K: Posicion);
var
Q: Ptrb;
begin
Q:= pA.Ramas[K];
while QA.Ramas[O]<> nil do
Q:= QA.Ramas[O];
{Q referencia a un nodo hoja}
PA.Claves[K]:= QA.Claves[l]
end;
,
rboles B 395
Procedimiento Restablecer
En este procedimiento se realizan las acciones ms complejas del proceso. Restaura
el nodo p Ra ma s [K) el cual se ha quedado con un nmero de claves menor que el
A
, .
mmlmo.
El procedimiento siempre toma una clave a partir del hermano de la izquierda (cla-
ves menores), slo utiliza al hermano derecho cuando no hay hermano izquierdo. Puede
ocurrir que no pueda tomar claves y entonces llamar a Combin a para formar un nodo
con dos nodos.
Mover l zqda(P , 1 )
elee
Combin a(P , 1)
end;
Procedimiento MoverDerecha
Este procedimiento mueve una clave del nodo antecedente ( p) al nodo que se est res-
taurando. A su vez, asciende la clave mayor del hermano izquierdo al nodo antecedente.
Procedimiento MoverIzquierda
Realiza la misma accin que el procedimiento Moverderecha , salvo que ahora la clave
que asciende al nodo antecedente es la clave menor (izquierda) del nodo a restaurar.
Procedimiento Combina
En este procedimiento se forman un solo nodo con dos nodos. Combina el nodo que est
en la rama K con el que est en la rama K - 1 Y la clave mediana de ambos que se encuen-
tra en el nodo antecedente. Una vez finalizado el proceso, libera el nodo obsoleto.
- - - -- -- -
rboles B 397
,
12.8. TAO ARBOL B DE ORDEN m
unit Ar b o lB ;
interface
const
Or de n -- S ,,
Ma x - Or d en - l ; {Nm e ro m x imo d e c la v e s en un nodo }
Min = (O r den-l ) d i v 2; {Nme ro mn i mo d e cla v es e n un n od o di st into
de la ra z}
398 Estructura de datos
type
Tipoclave - in tege r;
Ptrb = APag in a ;
posicion = O .. Max;
Pagina= record
Cu enta: O ., max;
Claves: array [1 .. maxJ of Tip oclave ;
Ramas: array [PosicionJ of Ptr b ;
end;
Esta unidad se emplea a ttulo de ejemplo para crear un rbol B de orden 5, conside-
rando el tipo de las claves entero.
Las claves son generadas aleatoriamente para evitar problemas, antes de insertar la
,,
,
CODIFICACION
program Procesa_arbolB(input,output);
uses crt , Arbo l b;
const
Mx=9999;
Arboles B 399
var
Rb: P trb ;
C l: intege r;
Op,N : integer;
procedure Menu( var Opc : int eg er);
begin
clrscr;
gotoxy(10,2 ) ; wr it e1n(' 1 . I n se rtar n claves') ;
goto x y(10 , 4); wr i teln(' 2 . Ins er tar 1 cla ve');
gotoxy(10,6); write l n ( ' 3 . E li minar c la ve') ;
gotoxy(10 , 8) ; write1n( '4. Listar clav e s') ;
g oto xy (10 , 10) ;wri t el n( '5. Fin p roc eso ' );
repeat
go t oxy (10,13) ; wr i teln (' Op ci n ?: ');
readln(Op c)
un ti 1 Op c in [1. . 5 1 ;
end;
procedure Annade_C l aves (var Rb:P t rb;N:integer);
var
K:O .. 1 00 ;
X:int ege r;
P:Posi c i on ;
Es ta : boo1ean;
Nd:Pt rb ;
begin
K: = O;
write ( ' C la ves in s ert ad as: ' ) ;
repeat
X: = r an dom (Mx) ;
Buscar(X,Rb,Esta,Nd,P) ;
if not Es ta then
begin
I n serta(X , Rb) ;
w rit e( X ,' '};
K :=K +l ;
end
unti1 K=N;
writel n;
end;
begin {B loque pri n cipal}
Rb : =nil;
Ra ndomize;
repeat
Menu (Op) ;
case Op of
1 : begin
cl r scr; go to xy (4,5) ;
write ( ' Cant as c l ave s: ? : ' ) ; read ln (N) ;
Annade _c lav es ( Rb,N)
end;
2 : An na de_c l aves(Rb, 1 ) ;
3 : begin
write('Clave que se desea e li mi na r:?');readln( C l);
E l iminar( Cl , Rb)
end;
400 Estructura de datos
4: Mo s trarB(Rb)
end;
repeat until readkey i n [ #0 .. #2551
until Op=5
end.
, ,
12.9. REALlZACION DE UN ARBOL B EN MEMORIA EXTERNA
const
Orden= 5;
Max=Orden-l; {Nme r o m xim o de c laves en un nodo}
Min=(Orden-l) div 2 ; {Nmero mnimo de claves en un nodo d i stinto de l a
raz}
type
Tipoclave=
I
Apuntador= in teg e r;
rboles 8 401
po sicio n = O .. Max;
Pagina= record
Cuenta : O .. Max;
Claves : array [ 1 .. Max] of Tipoclave ;
Ramas: array [Posi c i on] of Apuntador
end;
Fi c hero = file of Pagina;
Flibre = file of integer;
Para adaptarse a la nueva manera de direccionar los nodos y para grabar o cargar la
estructura son necesarias estas nuevas rutinas.
Funcin Hueco
,
Devuelve la posicin del siguiente registro libre. Este puede venir de la pila de registros
liberados, o bien el registro siguiente al ltimo concedido.
Procedimiento Inicial
Ser el primer procedimiento en ser llamado. Asigna archivos y vuelca en la pila los
nmero de registros liberados. Devuelve la raz del rbol B.
Pc rear (Pila) ;
assign(F, 'datosab.da t ');
assign(Fh , 'hue cos . dat ' );
{$i - }
reset (Fh) ;
if ioresult < > O then
begin
rewrite(Fh) ;
rewrite(F) ;
R:= Yacio { c onstante predefi n ida, parametr i za rbol vaco}
end
else begin
rese t (F) ;
if eof (Fh) then
R : = Yac io
402 Estructura de datos
else
read (Fh , R) {El pr ime r r egist ro es l a r a l Z del rb o l Bl
end;
{$ i + l
while not eo f (F h ) do
begin
r ea d (F h , 1 ) ;
Pme te r (Pila, I )
end
end;
Procedimiento de Finalizar
Este procedimiento ser el ltimo en llamarse. En l se escribe como primer registro el
nmero de registro de la raz del rbol. A continuacin, los registros liberados que estn
en la pila.
procedure f in (var Fh: Fl ibr e ; var F: Arch iv o ;
R : Apunt ad or; var Pi l a : Tpi la );
var
H: Apuntado r ;
begin
re set(Fh );
writ e( Fh , R) ;
while not Pvaci a(P i l a) do
begin
wr i t e (F h , Ci ma (Pi la) ;
Pb o rra r (Pi la )
end;
close(Fh) ;
cl ose( F )
end;
begin
if R <> v a cio then
begin
seek( F ,R);
read(F , Pg) ;
recorrer(Pg . Ra mas[O ] ,F ) ;
for 1 := 1 to Pg. Cuenta do
begin
write(Pg . Cl aves [ 1 ], ' ');
recor rer (Pg . Ramas[I] ,F )
end
end
end;
A continuacin se muestra la unidad para realizar el tipo abstracto de datos rbol B en archivo.
A las rutinas anteriores , se aaden las ya escritas para el proceso de insercin y el
proceso de borrado de claves. Presentan pequeas diferencias debido fundamentalmente
a la no utilizacin de punteros para acceder a un nodo o pgina.
Ahora este acceso se realiza con:
see k ( F, R) ;
read (F , Pg) ;
var R : integer); .
;
procedure F in (var Fh : Fl i br e;var F: Archivo ; R: Apunt a dor) ;
procedure Li be r a r (P:Ap un t ad o r ; var Pila : Tpil a );
'
procedure Recorre r (R: Apu n tador; var F: a r chivo) ; -
.
.
I
t
procedure Restablecer (P : Apuntador ; K:Posic i on ;var F : Arc hi vo) ;
procedure Qu it ar ( P : Ap un tador ; K : Posic i o n;" var F:Archivo) ;
I procedure Su ceso r (P : Apun tado r; K: Po si cio n; var F: Ar ch ivo) ;
:
I procedure Moverder echa( P:Apu n tador ; K: Pos i c i on ;var F : Archivo);
!-
o
seek(F, R);
read (F, Pg);
recorrer(Pg.Ra mas[O ) ,F);
for I:=1 to Pg.Cuenta do
begin
write(Pg.C1aves [I),' ');
recorrer(Pg.Ramas[I), F)
end
end
end;
begin
Encontrado:=false;
K:=O
end
elBe begin
K:= P.Cu enta ;
while (Clave < P.Claves[k)) and (k >l) do
k:=k-1;
Encontrado: = (Clave = P.C l aves[k ) )
end
end;
Sube: boolean;
Mdna: Tipoclave;
N, Xr: Apuntador;
begin
Empujar(Cl,R,Sube,Mdna,Xr,F) ;
, if Sube then
,,
- - - _ . - _._-
rboles B 407
begin
P.Cuenta:=l;
P . C 1 ave s [1] : = Mdna;
P.Ramas [0] := R;
P . Ramas [1] : = Xr;
N:= Hueco (Pila, F);
seek(F , N);
wr i t e (F, P);
R:= N
end
end;
end
else begin
s eek(F ,R) ;
read(F ,Pg) ;
buscarnodo(Cl,Pg,Esta,K) ;
if Esta tben
begin
write l n ( ' Clave ya e xi s te. Revisar c d i go');
ha lt (1)
end
else begin
Empujar ( C l ,pg.ramas [ K] ,EmpujaArriba , Md n a,Xr,F);
if EmpujaArriba then .
if Pg .C uenta < Max then
begin
EmpujaArriba:=false;
Meterhoja(Mdna,Xr,Pg,K) ;
seek(F,R) ;
write(F,Pg)
end
else begin
Empu j aArriba : =true;Di vi dirNodo(Mdna,Xr , Pg,K,Mdna,Xr,F) ;
seek( F ,R);
wri t e(F,Pg)
end
end
end
end;
408 Estructura de datos
see k ( F ,X d ) ;
write(F , Md e) ;
,
end
,I
rboles B 409
begin
EliminaRegistro(Cl,Raiz,Encontrado,F) ;
if not Encontrado then
writeln( 'No Encontrada la clave a eliminar')
else begin
seek(F,Raiz) ;
read(F,Pg) ;
if Pg.Cuenta = O then
begin
Aux:= Raiz;
Raiz:= Pg.Ramas[O];
Liberar(Aux,Pila)
end
end
end;
begin
seek(F,P);
read (F, Aux) ;
if K > o then
begin
J:=Aux.Ramas[K-l] ;
seek(F,J) ;
read ( F , Aux) ;
if Aux.Cuenta > Min then
Moverderecha(P,K,F)
else
Combina(P,K,F)
end
else begin
seek(F,P);
read (F , Aux) ;
j:= Aux.Ramas[l]; ,
seek(F,J);
read ( F , Aux) ;
if Aux.Cuenta > Min then
Moverizquierda(P,l,F)
else
Combina(P,l,F)
end
end;
end;
read(F,Auxdr) ;
i Auxiz.Cuenta:=Auxiz.Cuenta+1;
Auxiz.C l aves[Auxiz.Cuenta] :=Aux.Claves[K];
412 Estructura de datos
Auxiz.Ramas[Auxiz.Cuenta) : =Auxdr.Ramas[O);
Auxdr.Ramas[O) : =Auxdr.Ra ma s [l);
Aux.Claves[K):= Auxdr.C l ave s [l);
Auxdr.Cuenta:=Auxdr. Cuenta-l;
for j:=l to Auxdr. Cuenta do
begin
Auxdr. Claves [j) : =Auxdr. Claves [j +1) ;
Auxdr.Ramas[j) :=Auxdr.Ramas[j+l]
end;
seek ( F,P);
wr i te ( F , Aux) ;
seek(F,Aux.Ramas[k-l ] ) ;
wr i te(F,Auxiz) ;
seek(F,Aux.Ramas[k) ;
write(F,Auxdr )
end;
begin
;
liberar(Dcho,Pila)
end;
begin
end.
rboles B 413
program Arbol_b;
uses crt, ArbolB,Pilapun;
const
B= 999;
var
F:Ar ch ivo;
Fh:Flibre;
Apun,R,D:Apuntador;
Re, L, Cl: integer;
Pos:Pos i c i o n;
En co n t rado:boolean;
Res:char;
begin
R:=vacio;
c lrscr;
Ini c ializa (F, Fh, R) ;
randomize;
writeln ('Elementos presentes');
Re co rrer(R,F) ;
repeat
writel n ;
Reco rrer(R,F )
end
,
until (Re = 3);
,
Fin(Fh,F,R);
RESUMEN
Un rbol-B es una estructura de datos que se puede utilizar para implementar una tabla que reside
en memoria externa, tal como un disco. Los rboles B se denominan tambin rboles 2-3 y son
una clase de rboles no binarios sino ternarios, que obligan a que todas las hojas se encuentren al
mismo nivel.
Un rbol 2-3 permite que el nmero de hijos de un nodo interno varen entre dos y tres. Un
rbol2-3 es un rbol en el que cada nodo interno (no hoja) tiene dos o tres hijos y todas las hojas
estn al mismo nivel. Una definicin recursiva de un rbol 2-3 es: T es un rbol 2-3 de altura h si:
l. T est vaco (un rbol 2-3 de altura O).
o alternativamente:
2. T es de la forma
r
donde r es un nodo y TI Y T o son los dos rboles 2-3, cada uno de altura h-l. En este
caso, TI se llama subrbol izquierdo y Tose llama subrbol derecho.
O bien,
3. T es de la forma
donde r es un nodo y T" Te, T D son rboles 2-3, cada uno de altura h-l. En este caso, TI
se llama subrbol izquierdo, Te se llama subrbol central y Tose llama subrbol derecho.
50 90
120 150
En un rbol 2-3, los nodos internos pueden tener dos o tres hijos, permitiendo que el nmero
de hijos vare; los algoritmos de insercin y supresin pueden mantener fcilmente el equilibrio
del rbol.
rboles B 415
EJERCICIOS
12.1. Dada la secuencia de claves enteras: 190,57,89,90,121,170,35,48,91,22,126,132
Y 80, dibuja el rbol B de orden 5 cuya raz es R, que se corresponde con dichas claves.
12.2. En el rbol R del problema 1, elimina la clave 91 y dibuja el rbol resultante. Vuelve a
eliminar, ahora, la clave 48. Dibuja el rbol resultante, ha habido reduccin en el nme-
ro de nodos?
12.3. Modifique la rutina de insercin de un rbol B de orden m para que si se intenta aadir
una clave a un nodo que ya est lleno, se efecte una bsqueda de un hermano no lleno
antes de partir el nodo.
12.4. En un rbol B de orden 5 se insertan las claves 1, 2, 3, ... n. Qu claves originan la
divisin de un nodo? Qu claves hacen que la altura del rbol crezca?
12.5. En el rbol B de orden 5 del ejercicio 12.4, las claves se eliminan en el mismo orden de
creacin. Qu claves hacen que los nodos se queden con un nmero de claves menor
que el mnimo y den lugar a la unin de dos nodos? Qu claves hacen que la altura del
rbol disminuya?
12.6. Prevemos tener un archivo de un milln de registros, cada registro ocupar 50 bytes de
memoria. Los bloques de memoria son de 1.000 bytes de longitud y adems hay un pun-
tero por cada bloque que ocupa 4 bytes de memoria. Disear una organizacin con rbo-
les B para este archivo.
12.7. El procedimiento de bsqueda de una clave se ha realizado con una llamada recursiva al
final del procedimiento. Volver a escribir el procedimiento eliminando la llamada recursiva.
12.8. Un rbol B* es un rbol B en el que cada nodo est, al menos, lleno en las dos terceras
partes (en vez de la mitad), menos quizs el nodo raz. La insercin de nuevas claves en
el rbol B* supone que si el nodo que le corresponde est lleno mueve las claves a los
nodos hermanos (de manera similar a como se mueven en la eliminacin cuando hay que
restaurar el nmero de claves de un nodo). Con 10 cual se pospone la divisin del nodo
hasta que los dos nodos hermanos estn completamente llenos. Entonces, stos pueden
dividirse en tres nodos, cada uno de los cuales estar lleno en sus dos terceras partes.
Especifique los cambios que necesita el algoritmo de insercin de una clave en un rbol
B para aplicarlo a un rbol B*.
12.9. Dado un rbol B* segn est definido en 12.8, especificar los cambios necesarios que
necesita el algoritmo de eliminacin de una clave en un rbol B para aplicarlo a un
rbol B*.
12.10. Dada la secuencia de claves enteras del ejercicio 12.1: 190,57,89,90,121,170,35,48,
91, 22 , 126, 132 Y 80, dibuja el rbol B* de orden 5 cuya raz es R, que se corresponde
con dichas claves.
12.11. Con las claves del rbol B de orden 5 del ejercicio 12.4 dibuja un rbol B* de orden 5.
12.12. En el rbol B * de orden 5 del ejercicio 12.11, las claves se eliminan en el mismo orden
de creacin: 1, 2, 3, 4 ... n. Qu claves hacen que los nodos se queden con un nmero
de claves menor que el mnimo y den lugar a la unin de dos nodos? Qu claves hacen
!
,f PROBLEMAS I
12.1. Dada la secuencia de claves enteras: 190, 57, 89, 90, 121, 170, 35, 48, 91, 22, 126, 132 Y
80, dibuja el rbol B de orden 5 cuya raz es R, que se corresponde con dichas claves. ,
,
416 Estructura de datos
12.2. En el rbol R del problema 12.1 elimina la clave 01 y dibuja el rbol resultante. Vuelve a
eliminar ahora la clave 48. Dibuja el rbol resultante, ha habido reduccin en el nmero
de nodos?
12.3. Cada uno de los centros de enseanza del Estado consta de una biblioteca escolar. Cada
centro de enseanza est asociado con nmero de orden (valor entero), los centros de cada
provincia tienen nmeros consecutivos y en el rango de las unidades de 1.000. (As, a
Madrid le corresponde del 1 al 1.000; a Toledo, del 1.00 l al 2.000 ... )
Escribir un programa que permita gestionar la infolluacin indicada, formando una estruc-
tura en memoria de rbol B con un mximo de 6 claves por pgina. La clave de bsqueda
del rbol B es el nmero de orden del centro> adems tiene asociado el nombre del centro.
El programa debe permitir aadir centros, eliminar, buscar la existencia de un centro por la
clave y listar los centros existentes.
12.4. En el problema 12.3 cuando se termina la ejecucin se pierde toda la informacin. Pues
bien, modificar el programa 1 para que al terminar la informacin se grabe la estructura en
un archivo de nombre centros.txt.
Escribir un programa que pellllita leer el archivo centros.txt para generar a partir de l la
estructura de rbol B. La estructura puede experimentar modificaciones nuevos centros,
eliminacin de alguno existente , por lo que al terminar la ejecucin debe de escribirse
de nuevo el rbol en el archivo.
12.5. Se quiere dar ms contenido a la informacin tratada en el problema 12.3. Ya se ha especi-
ficado que la clave de bsqueda del rbol 8 es el nmero de orden del centro de ensean-
za. Adems, cada clave tiene que llevar asociada la raz de un rbol binario de bsqueda
que representa a los ttulos de la biblioteca del centro. El rbol de bsqueda biblioteca
tiene como campo clave el ttulo del libro (tiene ms campos como autor. .. ). Escribir un
programa que partiendo de la informacin guardada en el archivo centros.txt cree un nue-
vo rbol 8 con los centros y el rbol binario de ttulos de la biblioteca de cada centro.
12.6. A la estructura ya creada del problema 12.3, aadir las operaciones que responden a estos
requerimientos:
Dada una provincia cuyo rango de centros es conocido, por ejemplo de 3.001 a 3.780,
eliminar en todos sus centros escolares los libros que estn repetidos en cada centro, y
que informe del total de libros liberados.
Dado un centro n, en su biblioteca se desea que de ciertos libros haya m ejemplares
(por ejemplo, 5.)
,
CAPITULO
.,
resentaclOn
O eraCIOneS
......., .1" , . , '
.... ,'
,' ,'. ' ," . " . ."
'.",~'I:,."
, .'" "', .
',. . , "
CONTE
Con los rboles binarios se han representado relaciones entre objetos en las que existe
una jerarqua. Con frecuencia, es necesario representar relaciones arbitrarias entre obje-
417
418 Estructura de datos
tos de datos. Los grafos se clasifican en dirigidos y no dirigidos y son modelos naturales
de tales relaciones. As, los grafos se usan para representar redes de alcantarillado, redes
de comunicaciones, circuitos elctricos, etc. Una vez modelado el problema mediante
un grafo se pueden hacer estudios sobre diversas propiedades. Para ello se utilizan algo-
ritmos concretos que resuelvan ciertos problemas.
La teora de grafos ha sido aplicada en el estudio de problemas que surgen en reas
diversas de las ciencias, como la qumica, la ingeniera elctrica o la investigacin ope-
rativa. El primer paso siempre ser representar el problema como un grafo. En esta re-
presentacin cada elemento, cada objeto del problema, forma un nodo. La relacin, co-
municacin o conexin entre los nodos da lugar a una arista, que puede ser dirigida o
bidireccional (no dirigida). En la Figura 13.1 aparece una red de comunicaciones.
Impresora
PC1
Servidor
PC2
EJEMPLO 13.1
EJEMPLO 13.2
15
5
6
12 Centenera - - - - - - - - - - - Atanzn
Valfermoso
13.2.2. Camino
tal que (v, V+I) E A(arcos) para O $; i $; n. La longitud del camino es el nmero de arcos
que lo forma.
EJE LO 13.3
EJE LO 13.4
o E
EJEMPLO 13.5 i
,
13.3. REPRESENTACION DE LOS GRAFOS
Al pensar en los tipos de datos para representar un grafo en memoria, se debe tener en
cuenta que se debe representar un nmero (finito) de vrtices y de arcos que unen dos
vrtices. Se puede elegir una representacin secuencial, mediante arrays; o bien una re-
presentacin dinmica, mediante una estructura multienlazada. La representacin me-
diante arrays se conoce como matriz de adyacencia, la representacin dinmica se deno-
mina lista de adyacencia. La eleccin de una manera u otra depender de las operaciones
que se apliquen sobre los vrtices y arcos.
EJEMPLO 13.6
Sea el grafo dirigido de la figura siguiente
\.
Supongamos que el orden de los vrtices es el siguiente: {D, F, K, L, R}, Y por tanto
la matriz de adyacencia:
O 1 l o o
1 O O O O
A= O O O O O
O 1 l O O
1 O O O O
,,
EJEMPLO 13.7
Ahora el grafo de la figura es no dirigido.
,
,
La matriz de adyacencia:
I,
O 1 O 1 1
,
1 O 1 O O
A= O 1 O l l
1 O 1 O O
1 O 1 O O
Los grafos con factor de peso, grafos valorados, pueden representarse de tal forma
que si existe arco, el elemento aj es el factor de peso; la no existencia de arco supone
que aij es O o (esto slo si el factor de peso no puede ser O). A esta matriz se la deno-
00
EJEMPLO 13.8
4
Alicante Barcelona
1
3
5 3 6 2
Reus
Cartagena Murcia
." O 4 5 5 O
O O 3 6 3
,
P= 3 O O O O
O 2 O O O
O 1 O O O
Representacin en Pascal
Al ser una representacin esttica debe de estar previsto el mximo de nodos al que
puede llegar el grafo. Los nodos o vrtices tienen un identificador, los cuales se guardan
en un vector de cadenas. El tipo arco podramos representarlo con un registro con un
campo de tipo boolean, tomar el valor verdadero (true) si (v, v) es una arista, y en caso
necesario, falso (fa/se) otro campo de tipo numrico, que represente el factor de peso. La .
matriz de adyacencia que se representa es de tipo entero, tomando los valores de O al,
segn haya arco o no entre un par de vrtices.
const
Maxvert=20;
type
Indicevert = 1 .. Maxvert;
424 Estructura de datos
Ve r ti ce = s tr in g ;
Ve rti ces =array[In d i c evert , Indi ce vert ) of 0 .. 1
Gr a fo = record
N : In d i c e ve r t ;
V : Ve r tices ;
A : Ma t Ad cia
end;
var
G : Gr afo
type
Ar co - record
Ad t e : b oo le a n;
Pes o : re a l
end;
Mat Adcia = array [I ndicever t, I n diceve r t ) o f Ar co ;
1 3
5 1 2 4
Representacin en Pascal
Cada nodo de la lista directorio tiene que guardar el vrtice que representa, la direccin
de acceso a la lista de adyacencia (arcos que salen de dicho vrtice) y adems la direc-
cin del nodo siguiente de la lista directorio. Grficamente:
Cada nodo de la lista de adyacencia de un vrtice del grafo almacena la direccin del
vrtice (en la lista directorio) con el que forma un arco, en caso de ser un grafo valorado
tambin el factor de peso, y como en todas las listas la direccin del nodo siguiente.
Grficamente:
type
PtrDir ~ ANodoDir;
PtrAdy ~ ANodoLy;
NodoDir ~ record
Vert : string; {identificador del vrtice}
Lady: PtrAdy;
Sgte : PtrDir
end;
426 Estructura de datos
Nodo Ly = record
Pt r V: Pt rDi r ;
Pe s o : r e a l; {ca mp o fa c tor d e pe s o , e s o p cio n a l }
Sgte : Pt rAd y
end;
var
G : Ptr Di r;
Los grafos, al igual que las pilas, colas ... son tipos abstractos de datos. Ya hemos esta-
blecido los datos y su representacin, ahora definimos las operaciones bsicas sobre
esos datos y su realizacin que ser dependiente de la representacin de los datos.
La operacin unin (X, Y) aade el arco (X, Y) al grafo. En caso de ser un grafo
valorado se define la operacin unin-peso (X, Y, W) que aade el arco (X, Y) cuyo
factor de peso es W.
Estas operaciones son el ncleo a partir del cual se construye el grafo. En la repre-
sentacin con listas encadenadas se hace uso de las operaciones propias de una lista
enlazada.
En esta realizacin los vrtices estn representados por el ordinal (1..n) dentro del con-
junto de vrtices.
Operacin unin
for C := P to N-1 do
for 1 := 1 to N do
A[I,C] := A[I,C+1];
{Desplaza filas}
for 1 := P to N-1 do
for C := 1 to N do
A[I,C] := A[I+1,C]
{Se reduce el nmero de vrtices}
N := N-1
end
el se {Vrtice no existe en el grafo}
end
end;
end;
Operacin unin.
Dado el grafo y dos vrtices que forman un arco se aade el arco en la correspon-
diente lista de adyacencia. La realizacin de unin_peso slo presenta la diferencia de
asignar el factor de peso al crear el nodo de la lista de adyacencia.
Grafos. Representacin y operaciones 429
begin
if W = nil then
PA.Lady := RA.Sgte
elBe
WA.Sgte := RA.Sgte;
dispose (R) ;
Sw := true
end
elBe begin
W : = R;
R := RA.Sgte
end
end;
end;
Operacin Adyacente.
function Adyacente(G: PtrDir; Vl,V2: string) :boolean;
var
P,Q: PtrDir;
R,W: Ptradv;
Sw: boolean;
begin
P := Direccion(G,Vl),
Q := Direccion(G,V2);
if(P<>nil)and(Q<>nil) then
begin
{Proceso de bsqueda}
R := PA.Lady; Sw := false;
while(R<>nil) and not Sw do
begin
Sw := RA.PtrV = Q;
if not Sw then R := RA.Sgte
end;
Adyacente := Sw
end
elBe Adyacente := false
end;
Aade un vrtice X del grafo a la lista directorio. Siempre se aade como ltimo
nodo.
procedure Nuevo_vertice(var G: PtrDir; x: string);
begin
if G<>nil then
Ultimo(G)A.Sgte := CrearVt(X)
el Be
G := CrearVt(X)
end;
La operacin de eliminar un vrtice del grafo supone eliminar los arcos que van a l
y despus suprimirlo de la lista directorio. Se utilizan operaciones auxiliares nuevas:
.'
,:;,
432 Estructura de datos
, Frente Final
{D, B, el Final
/
14 l'
H R
{D, B, e, H, Rl Final
/
14 l'
A T
{D, B, e, H, R, A} Frente
. '>.. /
Final
y
...... T
CODIFICACiN
procedure Recorrido _ Anchu r a(G,W : PtrDir) ;
var
Lv,Av : Ptr I v ;
Qe : Cola ;
N : PtrD ir;
L : P t rAdy;
procedure Lis t a_Visitados (var Lv : Pt r_Lv ; G : PtrDir);
var P : Pt rDi r;
function Cre aV( Q : PtrDir ): Ptr _ Lv ;
var A : Ptr Lv;
begin
n ew (A) ;
AA . V : = Q; AA . Vsdo : = fa ls e;
CrearV : = A
end;
begin
if G<>n i l then
begin
Lv : = CreaV(G); P : = Lv; G : = GA . Sgte;
Grafos. Representacin y operaciones 435
la direccin de visitar es hacia adelante mientras que sea posible; al contrario que la
bsqueda en anchura, que primero visita todos los vrtices posibles en amplitud.
La definicin recursiva del recorrido en profundidad ya nos indica que tenemos que
utilizar una pila como estructura para guardar los vrtices adyacentes no visitados a uno
dado. De igual forma que en el recorrido en anchura, hacemos uso de una lista de vrti-
ces para controlar los ya visitados.
En la siguiente figura desarrollamos el recorrido en profundidad para el mismo grafo
y mismo vrtice de partida (D) que en el recorrido en anchura.
D D ~ Cima
{D} B C ~ Cima
{D, C} B R ~ Cima
{D, C, R} B H ~ Cima
{D, C, R, H} B A T ~ Cima
{D, C, H, R, T} B A ~ Cima
{D, C, R, H, T, A} B ~ Cima
I
o
Grafos. Representacin y operaciones 437
end
end
l. Realizar un recorrido del grafo a partir de cualquier vrtice w. Los vrtices visi-
tados son guardados en el conjunto W. .
2. Si el conjunto W es el conjunto de todos los vrtices del grafo, entonces el grafo
es conexo.
3. Si el grafo no es conexo, W es una componente conexa.
4. Se toma un vrtice no visitado, z, y se realiza de nuevo el recorrido del grafo a
CODIFICACiN
Se parte de un grafo G representado mediante listas de adyacencia, los vrtices segn
son visitados son almacenados en un vector para as comparar los vrtices visitados con
el total de vrtices y determinar si el grafo es conexo. Es necesario seguir utilizando la
lista de vrtices visitados.
Los tipos de datos que se incorporan a los ya definidos para el recorrido:
const
M = 100; {Mx imo d e vr ti ces}
type
Co nj u n t o = record
Vc : array[ l .. M} of Vert i ce ;
N: O .. M
end;
Estructura de datos
with W do
begin
N := N+l;
Vc[N] := ZA.Vert
end;
L := ZA.Lady;
while L<> nil do
begin
N := LA.V; Av := Direccion(Lv,N);
if not Av A. Vsdo then
begin
Meter(N,Pila) ;
AvA.Vsdo := true
end;
L := LA.Sgte
I end
until Esvacia (Pila)
,, II end;
,
Grafos. Representacin y operaciones 439
N : =O ; Z := G;
while z < >ni l do
begin
N : = N+l ;
Vc [ N] := ZA. Ve r t
Z : = ZA. Sg t e
end;
end;
Lista_V i sitados I Lv , G) ; {Todos los v rt i c es s e pone n a fa l se su
camp o v is ita do }
(Com i e n za a part i r de pr i mer vrtice n o vis it ado}
Z := Dir _N ov is(Lv);
while Z<>ni l do
begin
W.N := O;
Co n exaIG , Z , Lv , W) ;
if W. N = T .N then
wr i t e ln( 'Te nemos un gra f o no dirigido Cone x o')
elee begin
wri t e ( ' Co mp on en te Con e xa:' ) ;
for J := 1 to W. N do
wr i t e ( W. Vc [J ] , ' , ) ;
wr i teln
end;
Z : = Dir_No vi s(L v )
end
end;
EJEMPLO
La figura siguiente muestra un grafo dirigido con sus componentes fuertes.
,
440 Estructura de datos
, conexo.
,, 4. Si no es un grafo fuertemente conexo se selecciona un vrtice cualquiera w que
I no est en ninguna componente fuerte de las encontradas [w E: D( v) n A( v)] y se
procede de la misma manera, es decir, se repite a partir de 1 hasta obtener todas
I
I,
las componentes fuertes del grafo.
Para el paso 1 se realiza un recorrido en profundidad del grafo G a partir del vrti-
ce v. Los vrtices que son visitados se guardan en el conjunto D.
, Para el paso 2 hay que proceder en primer lugar a construir otro grafo dirigido G que
!
! sea el resultante de invertir las direcciones de todos los arcos de G. Y a continuacin
proceder como en el paso l.
En cuanto a los tipos de datos, el tipo vrtice se supone entero de tal forma que el
ordinal del vrtice coincide con el vrtice. Adems se supone que el mximo de vrtices
es 100. El grafo est representado mediante listas de adyacencia. Se define el vector
boolean visitado cada elemento del vector tiene verdadero (true) si en el recorrido el
vrtice con el que se corresponde ha sido visitado. El recorrido est codificado segn su
definicin, de manera recursiva, de tal fOlma que los vrtices alcanzados desde un vrti-
ce de partida se guardan como sus descendientes; la lista de vrtices visitados se imple-
, menta con un vector global. Repitiendo el recorrido a partir del mismo vrtice, pero con
!
el grafo inverso (cambiando el sentido de los arcos), los vrtices alcanzados a partir del
vrtice de partida son sus ascendientes.
CODIFICACiN
El programa que se presenta tiene dos partes diferenciadas. La primera lee los arcos del
grafo, crea las listas de adyacencia del grafo G y a la vez las listas de adyacencia del
grafo inverso InvG . La segunda encuentra las componentes conexas y las escribe.
Esconex o : = S
end;
procedure In terse cc ion(D ,A: Visit ad os ; Nv: vertic e;
var F : Visitados);
var J : Ve rt ice ;
begin
for J : = 1 to Nv do
F[J] := F [J] or (D[J] and A[J] )
end;
Camino entre par de vrtices
lores de ambos operandos lo son, lo cual implica que hay un arco desde el vrtice i al
vrtice k y otro desde el vrtice k al). Tambin podemos decir que la expresin sea cierta
implica la existencia de un camino de longitud 2 desde el vrtice i al j.
Ahora consideremos la expresin:
(A[i, l] and A[ l,j]) or (A[ i , 2] and A[2,j] ) or '" or (A[i,NurnVerts ] and A [NurnVer ts ,j ] )
Si esta expresin es cierta implica que hayal menos un camino de longitud 2 desde el
vrtice i al vrtice) que pase a travs del vrtice 1, o a travs del 2, o a travs del vrtice
NumVerts.
Recordando el producto matricial A x A observamos que la expresin anterior si cam-
biamos and por producto y or por suma representa el elemento Aij de la matriz A2.
2
Segn esto los elementos (Aij) de la matriz A son verdaderos si existe un camino de
longitud 2 desde el vrtice i al vrtice) "di,) = 1..n.
De igual forma el producto matricial A2 x A = A3 nos permite determinar si existe un
camino de longitud 3 entre cualquier par de vrtices del grafo. En general, para determi-
nar la existencia de camino de longitud m entre cualquier par de vrtices se forma el
producto boolean de los caminos de la matriz A m - 1 con la matriz adyacente A.
En la figura siguiente tenemos un grafo dirigido.
La matriz de adyacencia
F T F F F
F F T F T
A= T F F F F
T T F F T
F F F F F
El producto boolean A x A
F F T F T
T F F F F AS, Al5 es verdadero (true) ya que hay un cami-
2
A = F T F F F no de longitud 2 desde A-E (A~B~).
F T T F T
F F F F F
il:.
444 Estructura de datos
El producto boolean N x A
T F F F F
F T F F F
3
As, A 4 es verdadero (true) ya que hay un ca-
A = F F T F T
mino de longitud 3 desde D-A (D~B~C~A).
T F T F T
F F F F F
nos da todos los posibles caminos de longitud 2 desde el vrtice i al j, adems, recor-
2
dando el producto matricial A x A, representa el elemento Aij de la matriz A Podemos
generalizar, la forma de obtener el nmero de caminos de longitud k entre cualquier
par de vrtices del grafo es obtener el producto matricial Al, A3 ... Ak, entonces el
elemento Ali,j) nos da el nmero de caminos de longitud k desde el vrtice i hasta
el vrtice j.
EJEMPLO 13.9
Consideremos el grafo anterior cuya matriz de adyacencia es
o 1 O O O
O O 1 O 1
A= 1 O O O O
1 1 O O 1
O O O O O
El producto A x A
.
O O l O 1
1 O O O O
A2= O 1 O O O
O 1 1 O 1
O O O O O
El producto N x A
1 O O O O
O 1 O O O
A3 = O O 1 O 1
1 O 1 O 1
O O O O O
end
end;
Matriz de caminos
,
Sea G un grafo con n vrtices. La matriz de caminos de G es la matriz n x n P definida:
,"
.
!-
,
,
446 Estructura de datos
El camino de Vi a Vj ser simple si Vi :;:. Vj, o bien un ciclo cuando los extremos sean
el mismo vrtice Vi = Vj. Al ser el grafo G de n vrtices, un camino simple ha de tener
longitud n-l o menor, y un ciclo ha de tener longitud n o menor. Segn esto podemos
encontrar la siguiente relacin entre la matriz de caminos P, la matriz de adyacencia A y
las sucesivas potencias de A.
Dada la matriz Bn = A + A 2+ A) + ... +A n, la matriz de caminos P = (Pij) es tal que un
elemento Pij= 1 si y slo si EnU,}) 2! l yen otro caso Pij= O.
Una vez que tenemos la matriz de camino de un grafo G dirigido podemos determi-
nar de manera ms fcil si el grafo es fuertemente conexo. Recordar que para que G sea
fuertemente conexo se ha de cumplir que para todo par de vrtices Vi, Vj ha de existir un
camino de Vi a Vj y un camino de Vj a Vi. Por tanto, para que G sea fuertemente conexo
la matriz de caminos P ha de tener todos los elementos a 1.
Cierre transitivo
El cierre o contorno transitivo de un grafo G es otro grafo G' que consta de los mismos
vrtices que G y que tiene como matriz de adyacencia la matriz de caminos P del grafo
.
,.. G. Segn esta definicin, un grafo es fuertemente conexo si y slo si su cierre transitivo
es un grafo completo.
EJEMPLO 13.10
de k-l vrtices cualesquiera del grafo no lo divide en componentes conexas (no lo des-
conecta). Cuanto mayor sea la conectividad de un grafo (una red, por ejemplo) tanto
mayor probabilidad tendr de mantener la estructura ante el fallo (eliminacin) de algu-
no de sus vrtices.
,
, ,
,
,, ,
,,
B--- ,,
,,
,,
Grafo ,,
,,
,
rbol de expansin
a) Num(v).
b) El menor valor de Num(w) para los vrtices w de las aristas hacia atrs (v,w)
del rbol.
e) El menor valor de Bajo(w) para los vrtices w de las aristas (v,w) del rbol.
En la figura del ejemplo 13.11 se encuentran los valores Num(v), Bajo(v) de
todos los vrtices.
3. Una vez que tenemos los valores Num(v), Bajo(v), se determinan los puntos de
articulacin .
3.1. La raz del rbol (vrtice de partida) es punto de articulacin si y slo si
tiene dos o ms hijos.
3.2. Cualquier otro vrtice w es punto de articulacin si y slo si w tiene al
menos un hijo u tal que Bajo(u) ;;:: Num(w).
13.11
En la figura siguiente mostramos un grafo conectado (conexo) y el rbol de expansin.
3,3
---
---
, , --
, rbol; con cada nodo se escribe
,, ,
,, NumO y BajoO.
5,3
,
,
B 6,3
Grafos. Representacin y operaciones 449
begin
Vs t dos [V] := t r ue ;
C : = C + 1 ; Num [ V] : = C ;
L := GA. Lady; {G ti ene l a di re cci o n del ve rtic e V}
while L <> n i l do
begin
W := L A. Ptr V ;
if not Vs t do s [W A. Ve r t ] then
begin
Ari sta[ WA. Ver t] . -- V,
Va l_Num( W, WA. Vert , Vstdos , C,Nu m , Ar ista)
end;
L : = LA . S gt e
end
end;
El procedimiento para calcular los valores llamados Baja(v) se realiza con un reco-
rrido en postorden de los vrtices. Son necesarios los valores calculados en el procedi-
miento anterior de Num y Arista. Adems se puede determinar los puntos de articulacin
de vrtices que no son la raz (vrtice de partida) al conocerse el valor de BajaO.
RESUMEN
,
l.
Grafos. Representacin y operaciones 451
El recorrido de un grafo puede ser en analoga con los rboles, recorrido en profundidad y
recorrido en anchura. El recorrido en profundidad es aplicable a los grafos dirigidos y a los no
dirigidos y es una generalizacin del recorrido preorden de un rbol. El recorrido en anchura es
tambin aplicable a grafos dirigidos y no dirigidos, que generaliza el concepto de recorrido por
niveles de un rbol.
EJERCICIOS
13.1. Sea el grafo no dirigido G de la figura
H
F L
R T
,
I
o 1 1 1 O
1 O 1 O 1
M= 1 1 O l l
O l 1 O 1
O 1 l O O
a) Dibujar el grafo correspondiente.
b) Representar el grafo mediante listas de adyacencia.
13.6. Dado el grafo G del ejercicio 13.5 realice el recorrido del grafo en profundidad partiendo
del nodo C.
13.7. Dado el grafo G del ejercicio 13.5 realice el recorrido del grafo en anchura partiendo del
nodo C.
13.8. Un grafo dirigido acclico (gda) es un grafo dirigido sin ciclos. Dados los siguientes
grafos:
Grafos. Representacin y operaciones 453
13.11. Dibujar un grafo dirigido cuyos vrtices son nmeros enteros desde 3 hasta 15 para cada
una de las siguientes rela~es:
a) ves adyacente de w si v + 2w es divisible entre 3.
b) v es adyacente de w si I Ov + w < v*w.
PROBLEMAS
13.1. Escribir un programa para dar de entrada los vrtices y las aristas de un grafo dirigido. La
representacin del grafo ser mediante matriz de adyacencia. El programa pedir un vrti-
ce para realizar el recorrido en profundidad del grafo a partir de dicho vrtice.
13.2. Un grafo valorado est formado por los vrtices 4,7, 14, 19,21,25. Las aristas siempre
van de un vrtice de mayor valor numrico a otro de menor valor, y el peso es el mdulo
del vrtice origen y el vrtice destino. Escribir un programa que represente el grafo en
listas de adyacencia. Adems, realizar un recorrido en anchura desde un vrtice dado.
13.3. Queremos formar un grafo de manera aleatoria con los siguientes requisitos: consta de
10 vrtices que son nmeros enteros de 11 a 99. Dos vrtices X.y estn relacionados si
x+ y es mltiplo de 3. Escribir un programa para representar el grafo descrito mediante
una matriz de adyacencia Determinar la matriz de caminos utilizando las potencias de la
matriz de adyacencia.
13.4. Una regin est formada por 12 comunidades. Se establece la relacin de desplazamiento
de personas en las primeras horas del da. As, la comunidad A est relacionada con la
comunidad B si desde A se desplazan n personas a B, de igual forma puede haber relacin
entre B y A si se desplazan m personas de B hasta A. Escribir un programa que represente
el grafo descrito mediante listas de adyacencia. Tiene fuentes y sumideros?
13.5. Dado el grafo descrito en el problema 13.4, escribir un programa para representarlo me-
diante listas enlazadas de tal fOI ma que cada nodo de la lista directorio contenga dos listas:
una que contiene los arcos que salen del nodo, y la otra que contiene los arcos que termi-
nan en el nodo.
13.6. Dado un grafo dirigido en el que los vrtices son nmeros enteros positivos y el par (x,y)
es un arco si x-y es mltiplo de 3, escribir un programa para representar el grafo mediante
listas de adyacencia de tal forma que cada lista sea circular. Una vez el grafo en memoria I
determinar el grado de entrada y el grado de salida de cada nodo.
13.7. Un grafo no dirigido est representado en memoria mediante listas de adyacencia y se
desea saber si el grafo es cclico o acclico. Escribir un programa que represente el grafo y
las funciones o procedimientos necesarios que determinen si el grafo es cclico o acclico.
Adems, escribir un procedimiento para listar los nodos que forman un ciclo (en caso de
que lo haya).
!
!
13.8. Un algoritmo para detectar ciclos en un grafo dirigido consta de los siguientes pasos:
l. Obtener los sucesores de cada uno de los vrtices.
2. Buscar un vrtice sin sucesores y eliminarlo de los conjuntos de sucesores.
3. Repetir paso 2 siempre que haya algn vrtice sin sucesores.
4. Si todos los vrtices del grafo han sido eliminados, el grafo no tiene ciclos.
Realizar un programa en el que se represente un grafo dirigido mediante listas de adya-
cencia y detecte si el grafo dirigido tiene ciclos siguiendo el algoritmo descrito.
13.9. Se tiene un grafo representado mediante una matriz de adyacencia, escribir los procedi-
mientos necesarios para representar dicho grafo mediante listas de adyacencia.
13.10. Un grafo en el que los vrtices son regiones y los arcos tienen factor de peso est repre-
sentado mediante una lista directorio que contiene a cada uno de los vrtices y de las que
sale una lista circular con los vrtices adyacentes. Ahora se quiere representar el grafo
mediante una matriz de pesos, de tal forma que si entre dos vrtices no hay arco su
posicin en la matriz tiene O, y si entre dos vrtices hay arco su posicin contiene el
factor de peso que le corresponde. Escribir los procedimientos necesarios para que par-
tiendo de la representacin mediante listas se obtenga la representacin mediante la ma-
triz de pesos.
,
/
,
,
,
CAPITULO
un amenta es con
,', ,
"
',"", i' i', ' ... .. ... . . ,
... . .. ' ' ' ' ' , ' ,
,
," ,', ""
.
, ,,l',e~'
"
].
" "', , .
t ~ ",',." '" e,' '~", "
, ' , ,1 '
'. " :" ;
CONTENIDO
455
l.
456 Estructura de datos
EJEMPLO 14.1
,
i
,,.
,,
,
Est claro que una ordenacin topolgica no es posible en un grafo con ciclos. Qu
implica el que haya un ciclo? Pues que si v, w pertenecen al ciclo, entonces v precede
a w, y que w precede a v lo cual es evidentemente imposible.
Para que resulte ms familiar la exposicin del algoritmo, los vrtices del grafo van a
representar tareas. En primer lugar hay que buscar alguna tarea que no tenga predeceso-
res, que no tenga prerrequisitos, esto es, que no tenga arcos de entrada. Este vrtice v
pasa a formar parte de la ordenacin T; a continuacin, todos los arcos que salen de v
son eliminados (el prerrequisito v ya se ha satisfecho). La estrategia se repite, se coge
otro vrtice w sin arcos incidentes, y as sucesivamente.
Precisando un poco ms la estrategia, el que un vrtice v no tenga arcos incidentes lo
expresamos como que el gradoentrada (v) = O. Eliminar los arcos que salen de v implica
ro.
r que el gradoentrada (w) de todos los vrtices w adyacentes de v disminuyen en l.
"
,.l ,
En una estructura de tipo cola se guardan los vrtices con gradoentrada O, el ele-
,
mento frente de la cola v pasa a formar parte de la ordenacin T. Se disminuye el grado-
entrada de los adyacentes de v, y aquellos vrtices cuyo gradoentrada se haga O se me-
ten en la cola; as sucesivamente hasta que la cola est vaca.
CODIFICACiN
La codificacin se hace pensando en que el grafo tiene relativamente pocos arcos, lo que
da origen a una matriz de adyacencia sparce (muchos ceros); por lo que la representa-
cin es con listas de adyacencia. Se utilizan las operaciones del TAD grafo.
const
N = {nme r o de vrt i ce s }
type
{t i pos para re p r ese n tar u n gra f o por l i s tas d e adyacenc i a}
Ve rt i c e =1 .. N;
Ptrnod oq = ~ N o doq;
Nodo q = record
I n f o: Vert i ce ;
Sgte: p trn o d o q
end;
Co l a = record
Fren te ,
Final: Pt rn odoq
end;
begin
W:=GAVer;
if Adyacente(G,W,V) then { hay arco W ~ V }
K:=K+l;
G:=GA.Sgte
end;
GradoEntrada:=K
end;
procedure OrdenTopologica(G:PtrDir);
type
Vector = array[l . . N] of integer;
var
Grd: Vector;
V: Vertice;
Pv,Pw:PtrDir;
Lad:Ptrady;
Q: Cola;
begin
{Determina grado de entrada de cada vrtice}
for V:= 1 to N do
Grd[V]:= GradoEntrada(V,G);
Qcrear( Q); write( 'Ordenacin topolgica: ');
{Mete en cola vrtices con grado de entrada O}
for V:= 1 to N do
if Grd[V] = O then
I
Qponer(V,Q) ;
whi1e not Qvacia(Q) do
1-
begin
Qsacar(V,Q) ;
wr i t e (V: 2 " ');
Pv:= Direccion(G,V); Lad:=PvA.Lady;
{Decrementa grado entrada de V. adytes y si se pone a O es llevado
a cola}
Algoritmos fundamentales con grafos 459
begin
Grd[W] : = Grd[W]-l;
if Gr d[W ] = O then
Qp o ner(W, Q)
end
end;
O en otro caso.
Observamos que en cada paso se incorpora un nuevo vrtice, el que coincide con el
,
ndice de P, a los anteriores para poder formar camino.
l. Ya existe un camino simple de Vi a vj del que pueden formar parte los vrtices de
ndice l a k - 1(VI a Vk _ ); por tanto, el elemento de la matriz P k _ I [i,j] = l.
2. Hay un camino simple de Vi a Vk Y otro camino simple de Vk a vj de los que pueden
formar parte los vrtices de ndice 1 a k-I; por tanto, esto equivale a cumplirse
(P k - I [i,k] = 1) Y (P k - I [k,j] = 1)
,, , vk '' ,, ''
v'J '
, .
'
,, /
'
,
vJ'
,
.
,
,-
, .,
,,
v'I ~, vi
,, , ,. .
'
,, , , ,
...... .... , ,
........... .. .. .,' '. .... ........ ," '
{ Ini cializ ar P}
desde i <- 1 hasta n hacer
desde j <- 1 hasta n hacer
P [ i,j] <- A [ i , j )
fin desde
fin desde
,,,
Algoritmos fundamentales con grafos 461
,
{A con ti n u ac i n se ob t iene n las suces i vas mat ri ces Po, P" P" P, ... , Pn q ue
es la mat r iz de cami n os del gra f o}
desde k - 1 hasta n hacer
desde i <- 1 hasta n hacer
desde j<- 1 hasta n hacer
P[i,j] < - Minimo(l , P [ i,j]+(p[i,k ] *P[ k ,j ]))
fin desde
fin d es de
fin des d e
fin algor it mo
3
Se puede observar que la eficiencia del algoritmo es O (n ).
CODIFICACiN
El tipo de datos para representar la matriz de adyacencia es el ya utilizado
const
Maxv e r t= 20;
type
Indiceve r t = 1 .. Maxvert ; .,
MatAdcia = array [Indi ce vert , I n d i cevert ] of 0 . . 1
procedure Wars h all(A : MatAdc ia ;n: I ndicevert ; var P: Ma t Adc i a);
var i,j ,k: in d i cevert;
function Mi nimo (x, y: i n teger) : in t ege r ;
begin
if y < x then
Min imo := y
else
Mi nimo:= x
end;
begin
for i:= 1 to n do
for j := 1 to n do
P [ i ,j] : = A[i,j ] ;
{ }
, for k = 1 to n do
f
I for i := 1 to n do
,
j
for j := 1 to n do
P[i , j] : = Minimo(l , P[i,j ] + (p [i , k) *P[k , j)))
end;
,
14.3. PROBLEMA DE LOS CAMINOS MAS CORTOS
CON UN SOLO ORIGEN: ALGORITMO DE DIJKSTRA
Otro problema que se plantea con relativa frecuencia es determinar el camino ms corto
entre un par de vrtices. Se parte de un grafo dirigido y valorado (jactor de peso), por lo
I
que cada arco (v ,v) tiene asociado un coste cij ;::: O. De tal forma que el coste de un
k- I
!,
cammo V I ,V2 ... Vk es ,
1=
LI C + 1
'
Y lo que se pretende es encontrar el camino de VI a Vk de
coste mmlmo .
- -----
~
---------------------------------------------...
Inicialmente los valores de estos tres campos estarn a falso, 00 (excepto vrtice de
partida, que estar a cero) y O.
Tambin se hace uso de una cola. Como primer paso, la cola contiene el vrtice de
partida (VI), que es el vrtice de longitud de camino O. A continuacin se saca el elemen-
to frente y aaden los vrtices adyacentes a l, que son los de longitud de camino l, y as
sucesivamente. La cola (primero en entrar primero en salir) nos garantiza que no se pro-
cesan vrtices de longitud de camino m + 1 hasta que no han sido procesados todos que
tienen longitud m.
CODIFICACiN
,
type
{tipos para r ep r ese n ta r l os vrt i ces y la matri z de adyace n cia}
Est ad o = record
Alcanz ad o: bo o lean;
Di s ta n c ia: integer ;
Ult im o : Ve rtice;
end;
Ta bla = array[l . . NumV ertl of Estado;
,
Algoritmos fundamentales con grafos 465
En la figura del ejemplo 14.2 tenemos un grafo dirigido valorado y queremos calcu-
lar el coste mnimo desde el vrtice 1 al resto de los vrtices siguiendo el algoritmo de
Dijkstra . .
EJEMPLO 14.2
La matriz de adyacencia con los pesos de los arcos y considerando el peso como 00
00 3 4 00 8 00
00 00 00 00 5 00
00 00 00 00 3 00
C= 00 00 00 00 00 00
00 00 00 7 00 3
00 00 00 2 00 00
Los valores que se van obteniendo en los sucesivos pasos estn representados en
forma tabular:
Inicial I 3 4 00 8 00
1 1,2 2 3 4 00 8 00
2 1,2,3 3 3 4 00 7 00
3 1,2,3,5 5 3 4 14 7 10
4 1,2,3 ,5,6 6 3 4 12 7 10
5 1,2,3,5 ,6,4 4 3 4 12 7 10
CODIFICACiN
En la codificacin se supone que el vrtice origen es el de ndice l. Adems se tiene
como entrada la matriz de pesos la cual contiene el coste de cada arco, de no haber arco
i
contiene max i n t; {representa el oo}.
const
N = 15; { nmero de vrtices}
type
{tipos para representar los vrtices y matriz de adyacencia matriz de=
pe sos}
MatAdcia= array [ Indicevert, Indicevert] of integer ;
Estado=record
Distancia: integer;{Suponemos que el factor de peso es entero}
Ultimo : Verti ce;
end;
Tabla= array[l . . N ] of Estado;
,
Do[i,j] = e ij coste (peso) del arco de i a j.
00 si no hay arco.
'.
l.
-'
-
,
468 Estructura de datos
DI [i,j] = mnimo (Do[i,j], Do[i, 1] + D o[1,j]). Es decir, el menor de los costes entre
el anterior camino de i -? j Y la suma de los costes de caminos de i -? 1,
l-?j.
D 2 [i,j] = mnimo (DI[i,j], D I[i ,2]+ DI[2J]). Es decir, el menor de los costes entre el
,
,
anterior camino de i -? j Y la suma de los costes de caminos de i -? 2,
2 -? j.
Dk[i,j] =
entre el anterior camino de i -? j Y la suma de los costes de caminos de
,
i i -? k, k -? j.
De esta forma hasta llegar a la matriz Dn que ser la matriz de caminos mnimos del
grafo.
EJEMPLO 14.3
En la figura siguiente se tiene un grafo dirigido con factor de peso; aplicando los sucesi-
vos pasos del algoritmo de Floyd se llega a la matriz de caminos mnimos.
La matriz de pesos:
4
o 1 00 00 00
00 O 00 4 7
DI = 3 2 O 00 4 Al incorporar el vrtice 1 ha cambiado D I (4,2) ya que
6 O 2 C(4,1) + C(1,2) < C(4,2).
7 00
00 00 00 3 O
O 1 00 5 8
00 O 00 4 7 Al incorporar el vrtice 2 ha habido varios cambios.
D2 = 3 2 O 6 4 As ha ocurrido con DI(1,4):
6 7 00 O 2
00 00 00 3 O D I(1,2) + D I(2,4) < DI (1 ,4).
Algoritmos fundamentales con grafos 469
o 1 00 5 8
00 O 00 4 7
03 = 3 2 O 6 4 Al incorporar el vrtice 3 no ha habido cambios; al
6 7 00 O 2 vrtice 3 no llega ningn arco.
00 00 00 3 O
CODIFICACiN
, ..
const
N ~ 15 ; {nmero de vrtices}
type
{tipos para representar l o s vrtices y matr i z de a dy ace n cia matr iz de=
pesos}
Ma t Adcia ~ array [Indicevert,I ndi c e ve rt] of intege r;
MatCmo~ array[In d ic evert, rn d ic eve r t ] of O .. N;
procedure Floyd(C: Ma tadcia ; var D: Matadcia ; var Tr : MatCmo) ;
var
i,j,k: integer;
begin
for i :~ 1 to n do
for j: ~ 1 to n do
begin
D[ i, j ] := C [i ,j ];
Tr [ i , j] : = O
end;
{El camino mnimo de un ve r tice a s mismo se consi d era cero}
for j:= 1 to n do
D[ j,j ] : = O;
for k = 1 to n do
for i = 1 to n do
for j:= 1 to n do
if (D[i,k]+D[ k, j])<D[ i, j ] then
begin
D [i ,j] :~ D [i, k ] + D [k, jl;
Tr [ i , j ] : = k
end
end;
i
470 Estructura de datos
La primera idea de flujo se obtiene del significado popular: forma de enviar objetos de
un lugar a otro.
Ejemplos de la vida diaria: entre los centros de produccin y los centros de distribu-
cin hay un flujo de mercancas. Entre los lugares de residencia y los centros de trabajo
se produce un flujo de personas. Un sistema de tuberas para transporte de agua, cada
arco es un tubo y el peso representa la capacidad de la tubera en Litros/Minuto y los
nodos son puntos de unin de los diversos tubos.
Esta es la idea intuitiva de flujo, ahora exponemos la formulacin matemtica de flujo:
Se llama flujo a una funcin Fij definida en A (arcos) que verifica las propiedades:
I. D >
rlj_ O V'(i, j) E A
2. I:,Fij-I,F'ji = O i E V, i :t:. S, i :t:. T
JEa. JE PI
_ - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - -
......
EJEMPLO 14.4
Supngase un punto de origen con fuerte trfico, por ejemplo una ciudad dOllnitorio,
y otro punto que representa el centro, zona comercial, de la gran ciudad. Entre ambos
puntos se pueden establecer diversas rutas de entrada, cada una de ellas con una capaci-
dad de trfico mxima, dato que es conocido y expresado en miles de vehculos por
10 6
2
5
5 4 B
6
6
hora. Un problema que se puede plantear es encontrar cul es el flujo mximo de vehcu-
los que pueden desplazarse desde el punto origen al destino en la hora punta, y conocer
cul ser el ndice de utilizacin de cada una de las rutas de entrada. Esto nos conduce a
un problema de optimizacin.
EJEMPLO 14.5
j
,
,
,
j
1
,
1
s 3 e Red de flujos j
5
5 6 ,1
4
B D
3
arco.
,
,
1
,
F(S, X)
~E V
= VI = F(X,
'6V
T)
I
!
,
I la cantidad de agua, trfico ... que sale del vrtice S es igual a la cantidad que entra
i, en el sumidero T, y esta cantidad es Vr.
, El problema del flujo mximo consiste en enviar la mayor cantidad posible de flujo
desde el vrtice fuente S al vrtice sumidero T.
sujeto a las condiciones (flujo que entra = flujo que sale): I/ij - LJ). =
. .
O; i..=S,i..=T
J J
O _ <
lO'"
rlJ _ T T"
vI) < (i, j) E A
La funcin objetivo es la suma de los flujos que llegan al vrtice sumidero. Es preci-
samente la cantidad que se desea hacer mxima. Esta funcin de flujo se denomina el
ptimo.
La idea bsica de algoritmo es partir de una funcin de flujo , flujo cero, e iterativa-
mente ir mejorando el flujo. La mejora se da en la medida que el flujo de S hasta T
aumenta, teniendo en cuenta las condiciones que ha de cumplir la funcin de flujo en
lenguaje natural:
Con estas categoras podemos establecer las siguientes mejoras de la funcin de flu-
jo desde S a T:
l." Forma de mejora: encontrar un camino P del vrtice fuente S al sumidero T tal
que el flujo a travs de cada arco del camino (todos los arcos incrementables) no
supera a la capacidad:
2." Forma de mejora: encontrar un camino P' del sumidero T a la fuente S formado
por arcos reducibles, entonces es posible reducir el flujo de T a S y por tanto
aumentar en las mismas unidades de flujo de S a T en la cantidad:
3." Forma de mejora: existe un camino PI desde S hasta algn nodo V con los arcos
incrementables, un camino P2 desde un nodo W hasta el sumidero T con arcos
incrementables, y un camino P3 desde W a V con flujo reducible. Entonces el
flujo a lo largo del camino W - V puede ser reducido y el flujo desde S a T
puede ser incrementado en las unidades de flujo igual al mnimo de estas dos
cantidades:
Una cadena que une los vrtices Vi, Vj es una sucesin de arcos con origen
en el vrtice i y final en el vrtice j, tal que dos arcos sucesivos tienen un vrtice
comn, aunque no necesariamente el vrtice final de un arco es el inicial del
siguiente.
De manera ms escueta, una cadena, tambin llamada semicamino, desde
V a W es la secuencia de nodos V = Xl ' X2 , , Xn = W tal que para todo i,
l < =i < =nsecumpleque (X i - I ,X ;l o (Xi'X i - l ) es un arco.
De inmediato podemos afirmar que todo camino P de V a W es una cadena,
aunque no toda cadena es un camino. En el grafo de la figura siguiente encontra-
mos que una cadena de S a Tes:
S- A- B- D- T
A cualquier cadena de la red de S a T a la que se le pueda aplicar una de las
formas de mejora de flujo ser una cadena de aumento de flujo. El objetivo que
persigue el algoritmo de aumento de flujo es encontrar cadenas de aumento de
flujo en la red y aumentar el flujo en la cantidad determinada en los tres modos
expuestos. La solucin ptima se encuentra cuando ya no hay ms cadenas de
aumento de flujo.
5
4
2 3
,3
5,0 6,
4,2
3,2
2,2
Algoritmos fundamentales con grafos 475
33
5,4
e
s
5,0
4,2 T
----~ 3,3
2,2
Como se observa de la fuente S salen 6 unidades de flujo que son las que llegan al
sumidero T.
Para que sirva de ejemplo de mejora de flujo por aumento de cadena, sea el siguiente
grafo en el que representamos la capacidad de cada arco:
x
4
3
5
T
4 4
La funcin de flujo queda con la mejora por caminos con arcos incrementables:
5,4
4,4
5,1
4,4
EJEMPLO 14.6
Dada la siguiente red, en la que los pesos de los arcos representan la capacidad y el
flujo actual, se aplican los pasos que propone el algoritmo de Ford-Fulckenson para
encontrar el flujo mximo.
3,0
4,
6,0 6,0
4,0
jo= Min{ (Cij- Fij) para todo arco de la cadena}, en esta cadena
es 4. Ahora se actualizan los flujos de cada arco con el valor 4.
3,0
4 5,0
6
6,0
4,0
En una segunda pasada se marcan los vrtices S, Z, Y, T; todos los arcos son incre-
mentables, se tiene una segunda cadena de aumento de flujo. El incremento de flu-
jO=Min{(Cij- Fij) para todo arco de la cadena},enestacadena
es 2. Se actualiza los flujos:
3,0
w
5,0
T
6,6
6,2
y
4,2
3,2
5,2
6,
6,4
4,4
inicio
I nicializar la funcin de flujo a cero en cada arco
Nocadena f- false
repetir
<En contrar una cad ena de S a T que incremente flujo hacia T en x>
si <No se puede encontrar cadena> entonces
Nocadena f- true
sino
<Aumentar flujo a cada n o do en la cadena en x>
fin_si
hasta Nocadena
fin
Los tipos de datos son aquellos necesarios para representar las acciones indicadas en
el algoritmo.
Para marcar un nodo, una vez que ste ha sido colocado en una cadena, utilizamos
el vector boolean Encadena, de tal forma que Encadena [nodo] indica si el nodo
est en la cadena que se est fOllllando o no. En el vector boolean Fin v i a un elemento
Fin v i a [nodo] indica si el nodo est al final de la cadena que se est formando.
Para obtener correctamente la secuencia de nodos que forman la cadena, el vector
Precede es tal que Precede [nodo] referencia al nodo precedente del nodo ndice
en la cadena de la que forma parte. El vector boolean Adelante es tal que Adelan-
te [nodo] es true si el arco es hacia adelante, hacia T; en definitiva, el arco (prece-
de [nodo] I nodo).
Las unidades de flujo acumuladas hasta un nodo se guardan en la posicin corres-
pondiente del vector Fl uj os.
La capacidad de un arco y su flujo actual se almacenan respectivamente en las posi-
ciones correspondientes de las matrices e, F: e [i j] Y F [i j ] .
I I
F l uj o s [i l ~ F[i,ndl
fin - si
fin mientras
fin mientras {te r min a bucle de bsq ueda d e cade na}
si En cadena [ Tl entonces
<Aumentar e l flujo en l os arco s de l a cade na >
sino
<El flujo ya es mximo >
fin_si
fin
unit UnitFlux;
interface
const
Ma xnodos = 10;
type
Indexnodo = 1 .. Ma xnodos ;
Vn odos = array[I ndexnodol of Indexnodo;
Matr i z = array [Indexnodo , I ndexnod o l of integer;
Ve c t o r 10 gic o =array [ I nd e xn odo l of boo1ean;
procedure Impr i me ( F j: ma t riz ) ;
procedure Maxfluj o (Cap:Ma triz ; S , T :l ndex nod o ;
var Fj: Matriz; var Fj ototal:integer);
implementation
i. uses p rinter;
procedure Cadena (var Pred: Vnodos ; S,A: Indexnodo);
1
'J
o
o
var ,
Nd: Indexnodo;
begin
if A= S then
write(lst,' Cadena de aumento de flujo: ':40, S)
elee begin ,
o
Cadena(Pred, S, Pred[A]); o
,
wr i t e ( 1 s t , ' - - " A) ,
o
end ,o
,
'1
,
end; ,
1
procedure Imprime (Fj: Matriz); ,
,
var ,
;
Vi,Vj: Indexnodo; ,i,
begin ,~
,,
,
writeln (1st, 'Flujo de cada arco de la red':50);
'j
)
writeln (1st, 'Origen Arco, Final Arco, Flujo':55); ,1
for vi:= 1 to Maxnodos do
for Vj:= 1 to Maxnodos do 11
if Fj [Vi,Vj] <>0 then 00
procedure Maxflujo;
var
pred,nd,i: Indexnodo;
x: integer;
Precede: Vnodos;
Flujo: array[Indexnodo] of integer;
Finvia,Adelante,Encadena: Vectorlogico;
.,- .
,
Algoritmos fundamentales con grafos 481
begin
Finvia [nd] : =false;
Encadena [nd] : =false
end;
Finvia[S]:= true;
Encadena[S]:= true;
Flujo[S]:= maxint ; {mximo valor posible}
while (not Encadena[T]) and (Alguno(Finvia)) do
begin
nd:=l;
while not Finvia[nd] do {bsqueda del ltimo nodo en la
semicadena actual}
nd:=nd+l;
Finvia [nd] : = false;
for i:=l to Maxnodos do
begin
{La condicin de adyacentes es cierta en cuanto
Cap[nd,i]>O}
{Inspecciona si es arco incrementable}
if (Fj [nd,i]<Cap[nd,i]) and (not Encadena[i]) then
begin
Encadena[i] :=true;
Finvia[i] :=true;
Precede[i] :=nd;
Adelante[nd] :=true;
x:=Cap[nd,i]-Fj [nd,i];
if Flujo[nd]<x then
Flujo[i] :=Flujo[nd]
elee
Flujo[i] :=x
end;
{Ahora se trata la posibilidad de que sea un arco
hacia S, en vez de hacia T. En cuyo caso el arco
podra ser reducible}
{La condicin de adyacentes es cierta en cuanto
Fj[i,nd]>O}
if (Fj [i,nd]>O)and (not Encadena[i]) then
begin
Encadena [i] : =true;
Finvia[i] :=true;
Precede[i] :=nd;
Adelante [nd] : =false;
if Flujo[nd] <Fj [i,nd] then
,
Flujo[i] :=Flujo[nd]
, elee
,
,, Flujo[i] :=Fj [i,nd)
?
end
end {ltima sentencia del bucle for}
,,, end ; {ltima sentencia del bucle while}
,
if Encadena[T) then
{Ha sido encon~ada una cadena, puede aumentar el flujo en la
semiva(cadena) al sumidero T}
,
begin
x:= Flujo[T);
Fjototal:= Fjototal+x;
Algoritmos fundamentales con grafos 483
14.6.1. Definiciones
Red conectada: es una red tal, que cualquier par de vrtices pueden ser unidos me-
diante
,
un camino.
Arbol: en una red es un subconjunto G' del grafo G que es conectado y sin ciclos.
Los rboles tienen dos propiedades importantes:
b d
pueblos, un arco, viene dado por la distancia en kilmetros. Se quiere construir una red
de carriles-bicicleta de coste mnimo de tal forma que cada par de pueblos est comuni-
cado a un coste mnimo.
El planteamiento, dado un grafo no dirigido ponderado y conexo, encontrar el sub-
conjunto del grafo compuesto por todos los vrtices, con conexin entre cada par de
vrtices y sin ciclos, cuya suma de los costes de los arcos sea mnima. Hay que encontrar
el rbol de expansin de coste mnimo.
w= { 1 }
A partir del vrtice inicial el rbol de expansin crece, aadiendo en cada iteracin otro
vrtice z de V - W tal que si u es un vrtice de W, el arco (u, z) es el ms corto. El
proceso termina cuando v = w.
Observamos que en todo momento el conjunto de nodos que forma w forman una
componente conexa sin ciclos.
Otra forma de expresar el algoritmo de Prim es que, partiendo de un vrtice inicial u,
2
2 2 2 2
3 4 4
1 4 1
3 3
3 5 3
4 4
2
8 7
5 6 11 9 4
8 6
12
8 12
3
3
15
procedimiento Prim( G, T)
{ G : grafo
T : co nj u n to de arcos del rbo l de cos t e mnimo}
var
W: c onjunt o de vertlces;
u,w: vrti c es;
Inicio
T <- {}
V <- {lo .n }
u <- 1
W <- {u}
mientras W<> V hacer
<Encontrar v de V- W " (u ,v ) sea InlnlmO, siendo u E W>
W <- W+ {v}
T< - T+ {(u ,v )}
fin_mientras
fin_procedimiento
Para encontrar el arco de menor coste entre W y V-W en cada iteracin se utilizan
dos arrays:
En cada paso se revisa Cos t e para encontrar algn vrtice z de V -w que sea el ms
cercano a W. A continuacin se actualizan los arrays Mas_Cerca y Coste, teniendo
en cuenta que z ha sido aadido a W.
La implementacin del algoritmo en Pascal:
Algoritmos fundamentales con grafos 487
El algoritmo comienza con un grafo T con los mismos vrtices V pero sin arcos. Se
puede decir que cada vrtice es una componente conexa en s mismo.
Para construir componente conexas cada vez mayores, se examinan los arcos de A,
en orden creciente del coste. Si el arco conecta dos vrtices que se encuentran en dos
componentes conexas distintos, entonces se aade el arco a T. Se descartarn los arcos
si conectan dos vrtices contenidos en el mismo componente, ya que pueden provocar
un ciclo si se le aadiera al rbol de expansin para ese componente conexo. Cuando
todos los vrtices estn en un solo componente, T es un rbol de expansin de coste
mnimo del grafo G.
En el algoritmo siguiente se definen estos tipos de datos:
IndexNo d o= 1 . . n ;
!
end;
ListArco s= array[ l . . n*n] of Arco ;
Li stCo n js= array[ l . . n] of Co n jVe rt;
var
Ar c os : Li stA r cos;
Co mpConx : Li s t Conjs ;
U , v ,
e_u , e_ v ,
Co mp_n : In dexNodo ;
Kn , Ka , K : in teger ;
Mi n _ Ar : Arco;
begin
Kn : = O ; {Nmer o de arcos e n T}
Ka : = O; {Nmer o de arcos de la matriz de costes C}
Ct := O ; { Coste del rbo l de expansin}
Inicia l (C , Arcos,Ka) ; {obtie n e l os Ka arcos en orde n crec i ente de costes }
for V : = 1 to n do
CompCo n x [v ]: = [ v ];
{Obtiene los n compone n tes conexos i ni ciales,
con cada v rti ce}
Comp _ n: = n; {Nmero de c o mponentes conexos}
K: = O;
while Co mp_n > 1 do
begin
K : = K+l;
Mi n Ar: = Arc os [ K] ; { Arco m nimo actu a l }
C_ u : = NumCompon(M i n _ Ar . u , Comp Conx); {Componente do nde se
encuentra el vrtice u de l arco mni mo}
C_ v : = NumCompon(Min_ Ar . v, CompCo nx ) ;
if C u<>C v then {Co n ecta dos compone n tes dist in tos}
begin
Ct := Ct + Mi n_ Ar. Cdste ;
wri te l n( ' Arco ', Mi n _ Ar .u,' - > ', Mi n_Ar . v) ;
Co mbina(C _ u , C_ v , CompConx) ; {Une co mponentes u y v . Nueva componente
qu e da en u }
488 Estructura de datos
Comp_n: = Co mp_n-1;
Kn:= Kn +1;
T [Kn ] := Mi n _ Ar
end
end
end;
14.8. CODIFICACiN.
, RBOL DE EXPANSiN
DE COSTE MINIMO
En la siguiente unidad encapsulamos los tipos de datos necesarios para realizar los algo-
ritmos que determinan el rbol de expansin mnimo. En esta unidad tambin quedan
incorporados los tipos para representar la matriz de adyacencia.
implementation
procedure Ordena_ Rapid o ( var Lars: ListArcos; K: i n teger);
procedure Sort (iz,de : in t eger);
var
i, p: integer;
X, W: Arco;
begin
1: = 12;
p:=de ;
X:=Lars[ ( iz+de ) div 2 ];
repeat
while Lars[i].Coste < X .Coste do
i:=i+l;
while x.C o ste < Lars[p] .Coste do
p:=p-l;
if i < = p then
Algoritmos fundamentales con grafos 489
begin
W:= Lars[i];
Lars [i]: = Lars [p];
Lars [p] : = W;
i:= i+l
p: = p-1
end
until i > p;
if iz < p then Sort (iz,p);
if i < de then Sort (i,de);
end;
begin
Sort (1, K)
end;
begin
; Coste[i] := C [ l ,i ] ; {Inicialmente coste de cad a vrtic e de V- el]
es el arco (l,i)}
Mas_Cerca [i] : = 1 {deb i do a que W= [1]}
end;
for i:= 2 to n do
begin
(Encuentra el vrtice z de V-W ms cercano(menor arco a a l gn
vrtice de W)}
Min:= Coste[2];
z:= 2;
for j := 3 to n do
if Coste [ j] < Min then
begin
Min:= Coste[j ] ;
z:= J
end;
Ct : = Ct+ Min;
{Escri be arco del rbol de expa nsi n}
writeln(z, ' -- ',Mas _ ce rca[z]);
{ El vrtice z es aadido a W }
Coste [z): = Infin ito ;
W:= W+[z ) ;
{Ajus ta l os costes de l resto de vrtices }
I
i, for j:=2 to n do
if (C [ z,j)< Coste [ j ] ) and not (j in W) then
begin
Coste[j]:= C[z,j];
Mas_Cerca [ j ] : = Z
492 Estructura de datos
Coso Matriz;
T: ListArcos;
NI, N2: Indexnod o ;
CosteTot: real;
begin
{Los costes son inicializados a infinito}
for Nl:= 1 to Maxnodos do
for N2:= 1 to Maxnodos do
Cos[Nl,N2) :=Infinito;
writeln(CosteTot:12:1} ;
repeat until keypressed;
writeln;
write ('rbol de expansin de coste ffilnl.ffiO,
I ) ;
RESUMEN
Si G es un grafo dirigido sin ciclos, entonces un orden topolgico de G es un listado secuencial
de todos los vrtices de G, tales que todos los vrtices V, W E G; si existe una arista desde Va W,
entonces V precede a Wen el listado secuencial. El tImino acclico se utiliza con frecuencia para
representar que un grafo no tiene ciclos.
La ordenacin topolgica es un recorrido solamente aplicable a grafos dirigidos acclicos,
que cumple con la propiedad de que un vrtice slo se visita si han sido visitados todos sin prede-
cesores dentro del grafo. En un orden topolgico, cada vrtice debe aparecer antes que todos los
vrtices que son sus sucesores en el grafo dirigido.
Dado un grafo G, una de las operaciones clave es la bsqueda de caminos mnimos que sean
lo ms cortos posible, donde la longitud de un camino, tambin conocida como coste, se define
como la suma de las etiquetas de las aristas que lo componen. Una caracterstica fundamental en
un algoritmo es encontrar la distancia mnima de un vrtice al resto y otro para encontrar la dis-
tancia mnima posible entre todo par de vrtices.
Uno de los problemas ms importantes es calcular el coste del camino mnimo desde un vrtice
al resto. Una de las soluciones ms eficiente a este problema es el denominado algoritmo de
Dijkstra. Asimismo, se trata de deteIlninar el coste del camino ms corto entre todo par de vrtices
de un grafo etiquetado y de esta manera se puede generalizar la situacin estudiada. Adems de
Dijkstra, se dispone del llamado algoritmo de Floyd, que proporciona una solucin ms compacta
y elegante.
Un rbol de expansin es un rbol que contiene a todos los vrtices de una red y es una forma
de averiguar si la red es conectada. Los algoritmos que resuelvan los rboles de expansin mnima
ms usuales son: algoritmo de Prim y algoritmo de Kruskal.
EJERCICIOS
14.1. Dada la siguiente red:
3
2
A D
4 1
9
494 Estructura de datos
5
H K L
, 2 2
12
6
8
6 5
10 9
,
6
E
3
5
11
encontrar el camino ms corto desde el vrtice A a todos los dems vrtices del grafo.
,
,
i
Algoritmos fundamentales con grafos 495
14.8. En el grafo del ejercicio 14.7 encontrar el camino ms corto desde el vrtice D a todos
los dems vrtices del grafo siguiendo el algoritmo de Dijkstra. Incluir la ruta que for-
man los caminos.
14.9. En el grafo del ejercicio 14.7 encontrar los caminos ms cortos entre todos los pares de
vrtices. Para ello, seguir paso a paso el algoritmo de Floyd.
14.10. Dibujar un grafo dirigido con factor de peso en el que algn arco tenga factor de peso
negativo, de tal forma que al aplicar el algoritmo de Dijkstra para determinar los caminos
ms cortos desde un origen se obtenga un resultado errneo.
14.11. Con el algoritmo de Dijkstra se calculan los caminos mnimos desde un vrtice inicial a
los dems vertices del grafo. Escribe las modificaciones necesarias para que teniendo
como base el algoritmo de Dijkstra se calculen los caminos mnimos entre todos los
pares de vrtices. Cul es la eficiencia de este algoritmo?
14.12. El algoritmo de Prim o el algoritmo de Kruskal resuelven el problema de encontrar el
rbol de expansin de coste mnimo. La cuestin es: funcionan correctamente dichos
algoritmos si el factor de peso es negativo?
14.13. El algoritmo de Dijkstra no se puede aplicar a un grafo valorado en el que alguna arista
tiene un factor de peso negativo. El algoritmo de Bellman-Ford resuelve el problema
cuando hay aristas negativas, aunque no lo resuelve cuando hay ciclos en el grafo con
peso negativo. En caso de haber un ciclo con peso negativo el algoritmo lo indica y
telmina.
Sea G = (V,A) un grafo valorado de n vrtices, consideramos el vrtice origen el I y P la
matriz de pesos, el algoritmo de Bellman-Ford para hallar los caminos mnimos desde un
origen lo expresamos en seudocdigo:
I n icio
d es d e v r 2 h ast a n { n e s e l n mero de nodos } h a c er
d(v) r 00
f in_d esd e
s r 1
d (s ) r O { ma rc a el o rigen d e l c a mi n o }
d esd e i r 1 h as ta n - 1 { n es el n me ro d e n odos } hac e r
pa r a c ada ar is ta (u , v) E A h a ce r
si d(v) > d( u) + P(u,v ) entonces
d (v) r d(u) + P( u , v)
f in _ si
fin _ de s de
{ Prue ba de c i clos c o n p es o neg a t i vo }
,
par a ca da arista (u , v) E A ha cer
si d( v d ( u) + P (u, v) , en t on c e s
Error r t rue
fin s i
{ en e l array d estn l o s caminos m n i mos desde s a l os d e m s
vrtices si Error e s f a l s e }
Fi n
14.14. Determinar los vrtices que son puntos de articulacin en el grafo de la figura:
B J L
A E
14.15. Un circuito de Euler en un grafo dirigido es un ciclo en el cual toda arista es visitada
exactamente una vez. Se puede demostrar que un grafo dirigido tiene un circuito de Euler
si y solo si es fuertemente conexo y todo vrtice tiene iguales su grado de entrada y de
salida.
Dibujar un grafo dirigido en el que se pueda encontrar un circuito de Euler.
PROBLEMAS
14.1. Escribe un programa en el cual sea representado en memoria una red (un Pert: grafo dirigi-
do sin ciclos y factor de peso) mediante la matriz de adyacencia (matriz de pesos) y calcule:
El tiempo tn(v).
El tiempo tl(v).
Adems encuentre las rutas crticas de la red.
(Nota: vanse los ejercicios 14.2-14.4.)
14.2. Escribir un programa en el que dada una red (un Pert), representada en memoria mediante
listas de adyacencia, encuentre las rutas crticas.
14.3. Tenemos una red (un Pert) representada con su matriz de adyacencia. Escribir un programa
que calcule el mnimo tiempo en el que todo trabajo se puede terminar si tantas actividades
como sea posible son realizadas en paralelo. El programa debe de escribir el tiempo en el
que se inicia y se termina toda actividad en la red.
14.4. Escribir un programa para que dada una red (Pert) representada por su matriz de adyacen-
cia, determine el tiempo mnimo de realizacin del trabajo si como mximo se pueden
realizar n actividades (de las posibles) en paralelo. El programa debe mostrar el tiempo de
inicio y el de finalizacin de cada actividad.
14.5. Escribir un procedimiento para implementar el algoritmo de Dijkstra con esta modifica-
cin: en la bsqueda del camino mnimo desde el origen a cualquier vrtice puede haber
ms de un camino del mismo camino mnimo, entonces seleccionar aquel con el menor
nmero de arcos.
Algoritmos fundamentales con grafos 497
14.6. El algoritmo de Dijkstra resuelve el problema de hallar los caminos mnimos desde un
nico vrtice origen a los dems vrtices. Escribir un procedimiento para resolver el
problema de que dado un grafo G representado por su matriz de pesos encuentre los
caminos mnimos desde todo vrtice Va un mismo vrtice destino D.
14.7. Escribir un programa en el que dado un grafo valorado, teniendo ciertos factores de peso
negativos, representado en memoria mediante la matriz de pesos, determine los caminos
ms cortos desde el vrtice origen a los dems vrtices. Utilizar el algoritmo de Bellman-
Ford del ejercicio 14.13.
14.8. Dado un grafo no dirigido con factor de peso escribir un programa que tenga como entra-
da dicho grafo, lo represente en memoria y determine el rbol de expansin de coste
, .
maxlmo.
14.9. Un circuito de Euler en un grafo dirigido es un ciclo en el cual toda arista es visitada
exactamente una vez. Se puede demostrar que un grafo dirigido tiene un circuito de
Euler si y slo si es fuertemente conexo y todo vrtice tiene iguales sus grados
de entrada y de salida. Escribir un programa en el que se represente mediante listas de
adyacencia un grafo dirigido. Implemente un algoritmo para encontrar, si existe, un
circuito de Euler.
14.10. Un grafo est representado en memoria mediante listas de adyacencia. Escribir las ruti-
nas necesarias para determinar la matriz de caminos.
(Nota: Seguir la estrategia expuesta en el algoritmo de Warshall pero sin utilizar la ma-
triz de adyacencia.)
14.11. Se quiere escolarizar una zona rural compuesta de 4 poblaciones: Lupiana, Centenera,
Atanzn y Pinilla. Para ello se va a construir un centro escolar en la poblacin que mejor
coste de desplazamiento educativo tenga (mnimo de la funcin Z J
PARTE
i
--
"
CAPTULO
., ,
aCIOn, US mezca
- ."',{-'- ( "-:- . - ,'-.' '- ,
,' "
.. -
- - ., r,
!
. ,,' , ,-. -" "",- :-:c::,-:,.-.
-,,-~---,- --- - >
.
",,, . "',",", " ' ,"
~
"
,
. .'
,,
'- --
CONTENIDO
15.1. Introduccin.
15.2. Ordenacin.
15.3. Ordenacin por burbuja.
15.4. Ordenacin por seleccin.
15.5. Ordenacin por insercin.
15.6. Ordenacin Shell.
15.7. Ordenacin rpida (quicksort).
15.8. Ordenacin por mezcla (mergesort).
15.9. Ordenacin Heapsort.
15.10. Ordenacin Binsort.
15.11. Ordenacin Radix Sort.
15.12. Bsqueda lineal.
15.13. Bsqueda binaria.
15.14. Bsqueda binaria recursiva.
15.15. Mezcla.
RESUMEN.
,
EJERCICIOS.
PROBLEMAS. ,
501
,
,
15.1. INTRODUCCION
Tres operaciones muy importantes en programacin de computadoras son: ordenacin,
bsqueda y mezcla; son esenciales para un gran nmero de programas de proceso de
datos y se estima que en estas operaciones las computadoras por trmino medio gastan
gran parte de su tiempo. La bsqueda, ordenacin y mezcla son tambin procesos que
las personas se encuentran normalmente en sus vidas diarias. Considrese, por ejemplo,
el proceso de encontrar una palabra en un diccionario o un nombre en una gua o listado
de telfonos. La bsqueda de un elemento especfico se simplifica considerablemente
por el hecho de que las palabras en el diccionario y los nombres en la gua telefnica
i estn ordenados o clasificados en orden alfabtico. Asimismo, la operacin de mezclar
datos de dos listas o conjuntos de datos en una sola lista suele ser una operacin frecuente.
En este captulo se estudian los mtodos ms usuales de ordenacin, bsqueda y
mezcla, relativos a listas o vectores (arrays), ya que si bien estas operaciones se aplican
sobre otras estructuras de datos como registros o archivos, su mayor aplicacin est casi
siempre asociada a los vectores, y, por otra parte, la comprensin de los algoritmos en
vectores extrapolables a otras estructuras' es ms fcil.
15.2. ORDENACION
La ordenacin o clasificacin de datos (sort en ingls) es una operacin consistente en
disponer un conjunto estructura de datos en algn determinado orden con respecto
a uno de los campos de elementos del conjunto. Por ejemplo, cada elemento del conjun-
to de datos de una gua telefnica tiene un campo nombre, un campo direccin y un
campo nmero de telfono; la gua telefnica est dispuesta en orden alfabtico de nom-
bres. Los elementos numricos se pueden ordenar en orden creciente o decreciente de
acuerdo al valor numrico del elemento. En terminologa de ordenacin, el elemento por
el cual est ordenado un conjunto de datos (o se est buscando) se denomina clave.
Una coleccin de datos (estructura) puede ser almacenada en un archivo , un array
(vector atabla), un array de registros, una lista enlazada o un rbol. Cuando los datos
estn almacenados en un array, una lista enlazada o un rbol, se denomina ordenacin
interna. Si los datos estn almacenados en un archivo, el proceso de ordenacin se llama
ordenacin externa.
Una lista dice que est ordenada por la clave k si la lista est en orden ascendente o
descendente con respecto a esta clave. La lista se dice que est en orden ascendente si:
i < j implica que K[i] < = K[j]
y se dice que est en orden descendente si:
i > j implica que K[i] > = K(j]
, para todos los elementos de la lista. Por ejemplo, para una gua telefnica, la lista est
clasificada en orden ascendente por el campo clave k, donde k[i] es el nombre del abona-
do (apellidos, nombre).
Ordenacin, bsqueda y mezcla 503
4 5 14 21 32 45 orden ascendente
75 70 35 16 14 12 orden descendente
Zacar ias Ro drigue z Ma rt i ne z Lopez Ga rcia orden descendente
Los mtodos (algoritmos) de ordenacin son numerosos; por ello se debe prestar es-
pecial atencin en su eleccin. Cmo se sabe cul es el mejor algoritmo? La eficiencia
es el factor que mide la calidad y rendimiento de un algoritmo. En el caso de la operacin
de ordenacin, dos criterios se suelen seguir a la hora de decidir qu algoritmo de entre
los que resuelven la ordenacin es el ms eficiente: 1) tiempo menor de ejecucin en
computadora; 2) menor nmero de instrucciones. Sin embargo, no siempre es fcil efec-
tuar estas medidas: puede no disponerse de instrucciones para medida de tiempo aun-
que no sea ste el caso de Turbo Pascal ,y las instrucciones pueden variar, dependien-
do del lenguaje y del propio estilo del programador. Por esta razn, el mejor criterio para
medir la eficiencia de un algoritmo es aislar una operacin especfica clave en la ordena-
cin y contar el nmero de veces que se realiza. As, en el caso de los algoritmos de
ordenacin, se utilizar como medida de su eficiencia el nmero de comparaciones entre
elementos efectuados. El algoritmo de ordenacin A ser ms eficiente que el B, si re-
quiere menor nmero de comparaciones. As, en el caso de ordenar los elementos de un
. vector, el nmero de comparaciones ser funcin del nmero de elementos (n) del vector
(array). Por consiguiente, se puede expresar el nmero de comparaciones en trminos de
n (por ejemplo, n + 4), o bien n en lugar de nmeros enteros (por ejemplo, 325).
2
En todos los mtodos de este captulo, normalmente para comodidad del lector'-
se utiliza el orden ascendente sobre vectores o listas (arrays unidimensionales).
Los mtodos de ordenacin se suelen dividir en dos grandes grupos:
.
, 15.3.1. Anlisis
..
,
. ..
,
Supongamos un vector A[!], A[2], .oo, A[n]. Se comienza el seguimiento del vector de
,
'-
,,
,,
A(1) 23 15
A(2) 19 19
, A(3) 45 23
I
A(4) 31 31
A(5) 15 44
,
En la lista A, i ser el nmero de la pasada y j indica el orden del elemento de la lista.
Se comenzar en el elemento j-simo y el (j + l)-simo.
!,
,
;
I
Pasada 1: i = 1
A[1) 23 19 19 19 19
A[2) 23 1.--, 23 23 23
A[3) 45 45 45 31 31
A[4] 31 31 31 45 15
Elemento
A(5) 15 15 15 15 45 ordenado
j= 1 j=2 j= 3 j=4
Comparacin 1 Comparacin 2 Comparacin 3 Comparacin 4
Ordenacin, bsqueda y mezcla 505
A[1] 19 19 19 19 19
A[2] 23 I.h 23 23 23
A[3] 31 31 31 15 15
A[4] 15 15 15 31 31
Elemento
A[5] 45 45 45 45 45 ordenado
j= 1 j = 2 j=3 j=4
Comparacin 1 Comparacin 2 Comparacin 3 Comparacin 4
Pasada 3: i = 3
19 19 19 19 19
23 23 15 15 15
15 15 23 23 23
31 31 31 31 31
45 45 45 45 45
Pasada 4: i = 4
19 15 15 15 15
15 19 19 19 19
23 23 23 23 23
31 31 31 31 31
45 45 45 45 45
Se observa que se necesitan cuatro pasadas para ordenar una lista de nmeros de
cinco elementos, por lo que una lista de n elementos necesitar n-l pasadas. El proceso
se describe as:
506 Estructura de datos
for j = 1 to 5 -i
I
Algoritmo (pseudocdigo)
desde i r-1 hasta n - 1 hacer
desde j r- 1 hasta n - i hacer
si A[j ] > A[j+1 ]
entonces Inter ca mbio (A[j] , A[ j+1])
fin-si
fin_desde {bu cle j }
fin_desde {bucl e i }
Aux r- A [ j]
A [j ] r- A [ j+1 ]
A [ j+1] Aux
1
Ordenacin, bsqueda y mezcla 507
Mtodo 1
procedure burbu ja 1 (var A : List a ; N : int eger);
{o rden ar A[l] , ... ,A[N] e n orden ascen dent e
Lista en un array u ni d i mensio n a l d e fin i do en e l programa p rin cipal d e N
eleme n tos d e tipo e n te r o}
var
r, J, Aux : inte ger;
begin
for I : = 1 to N -1 do
for J := 1 to N - I do
if A[J ] > A [J+ 1] then
begin { i n te rcambio de n t ro de l programa }
Aux : = A [ J ];
A [J ] : = A [ J +l]
A[J+1] : = Au x
end; {f in de los buc le s for }
end; {Bu r bu j a l}
Mtodo 2
procedure Burbuja1 (var A : Li sta ; N : int eger) ;
var
r , J : intege r;
procedure Inter c ambio (var X, Y : i n teger);
var
Aux : integer;
begin
Aux - X;
X - Y;
-
y Au x
end;
begin
for I := 1 to N-l do
for J : = 1 to N-I do
if A [ J ] > A [J+l ] then
Intercamb i o (A [ J ] , A [ J+l ] )
end; {Bu r bu j a l }
Pseudocdigo BurbujaMejorado
i f- 1
repetir
NoIntercambio f- true
desde j f- 1 hasta n-i hacer
si A[jl > A [j+1l
1 entonces Intercambio (A[j], A[j+ll)
!
I NoIntercambio f- false
fin si
fin desde
, i f- i+1
,
hasta_que Nolntercambio = true
,
,
1
15.3.4. Programacin completa de ordenacin por burbuja
Se genera aleatoriamente una lista de 100 nmeros enteros (o bien se leen de un archivo de
entrada: teclado o disco) y se desea escribir un programa que realice las siguientes tareas:
l. Leer lista de nmeros aleatorios.
2. Visualizar lista.
3. Ordenar lista por burbuja.
4. Visualizar lista ordenada.
1
El procedimiento Leer sirve para introducir la lista de 100 nmeros; el procedi-
miento visualizar permite imprimir cualquier lista, en este caso tanto la lista orde-
nada como desordenada; y el procedimiento Ordenar clasifica la lista A.
i
program OrdenarBurbuja;
{Ordenacin ascendente por el mtodo de la burbuja}
const
Limite = 100;
type
Item = integer;
rango - O.. Limite;
Lista = array [Rangol of Item;
var
ListaItem : Lista;
Numitems : integer;
procedure Leer (var A: Lista; N: integer);
var
1 : integer;
begin
for 1 := 1 to N do
A [1] : = Random (10 OO)
end;
,,
.,
Ordenacin, bsqueda y mezcla 509
n- l 1
510 Estructura de datos
15.4. ORDENACION POR SELECCION
El algoritmo de ordenacin por seleccin de una lista (vector) de n elementos tiene los
siguientes pasos:
Algoritmo
e l emen t o ma y or co n e l d e s ub nd i ce i .
program Or d e narSe l e cc i o n ;
{ l eer 1 00 e nt er os . Ord e nar . Vis u al i zar}
const
Li mi t e ~ 1 00;
type
Lis t a = array [1 . . Li mit e ) of i n te g er ;
Ordenacin, bsqueda y mezcla 511
var
1 , Num : 1 .. Lim ite ;
A : List a ;
function Pos Ma y o r (Ul timo :i nt e g er; var Tab la: Li s ta ) : in t eger ;
{encuen t r a el i ndi ce de l e l e me n t o mayo r e n la Tab l a [l .. Ul ti mo]}
var
I ndic e_Max , Ind i c e : 1 .. Limit e;
begin
I nd i ce _ max := 1;
for Indi ce := 2 to Ul timo do
if Tabla [I n d i ce ] > Tab l a [Indice _ Max]
then Ind i c e_Max := I ndice ;
Po s Ma yor : = Indic e_Max
end;
procedure Seleccion (Limi : i nteger ; var Tab l a : Li sta) ;
var
Aux, J , Mayo r : integer ;
begin
for J := Limi downto 2 do
begin
{enc o ntr a r e l Ele men t o mayor de 1 .. J}
Ma yo r : = Pos May or (J , Tab la);
{i n tercambio con el Eleme nt o Ta bl a [J ] }
Au x : = Tab l a [ Mayo r ] ;
Ta b la [Mayor] : = ta bl a [J ];
Ta b la [J] : = Aux
end
end;
{p r ogra ma pri nci pal}
begin
for 1 : = 1 to Li mi t e do
begin
A [1] : = Random (10 O) ;
Wr i t e (A [ I] : 4)
end;
WriteLn ;
Se l eccion (Limi te , A);
for I := 1 to Li mit e do
Write (A[I] : 4) ;
WriteLn
end.
n- 1 1
, ,
15.5. ORDENACION POR INSERCION
Este mtodo est basado en la tcnica utilizada por los jugadores de cartas para cla-
sificar sus cartas. El jugador va colocando (insertando) cada carta en su posicin co-
rrecta.
tres cartas 2 6 10
cuatro cartas 2 6 10
cinco cartas 2 6 9 10
El mtodo se basa en considerar una parte de la lista ya ordenada y situar cada uno
de los elementos restantes insertndolo en el lugar que le corresponde por su valor, todos
los valores a la derecha se desplazan una posicin para dejar espacio.
Algoritmo
{para cada el emento de l a lista despu s del prim ero}
desde k f-- 2 hasta n hacer
Ordenacin, bsqueda y mezcla 513
Algoritmo de desplazamiento
begin
for K := 2 to N do
begin
Au x : = Tab l a [ K] ; {obtener s i gu i e n t e e l emento a in sert ar}
[(k - 1) +1] /2 = k/ 2
El nmero de comparaciones ( C) es
n
n2 - n -_
C mx = L (i - 1) = 1 + 2 + ... + (n - 1) =
;~2 2
n
Cmin = L (l) = 1 + 1 + ... + 1 = (n - 1)
;=2
Lista original
504 88 513 62 908 171 898 277 654 427 150 510 612 675 750 704
l. Se divide la lista original (16 elementos, en este ejemplo) en ocho grupos de dos
(considerando un incremento o intervalo de 16/2 = 8).
Ordenacin, bsqueda y mezcla 515
2. Se clasifica cada grupo por separado (se comparan las parejas de elementos y si
no estn ordenados se intercambian entre s de posiciones).
3. Se divide ahora la lista en cuatro grupos de cuatro (intervalo o salto de 8/2 = 4)
Y nuevamente se clasifica cada grupo por separado.
4. Un tercer paso clasifica dos grupos de ocho registros y luego un cuarto paso
completa el trabajo clasificando los 16 registros.
516 Estructura de datos
504 88 150 62 612 171 513 277 654 427 750 510 908 675 898 704
"-- "- A A /--... .--A-.. A /'-.. ./'-..... ~
=---=><::A~_A~><::./'-.....~><:::../'-.....----=::.</~__/
150 62 , 504 88 513 171 612 277 654 427 750 510 898 675 908 704
62 88 154 171 277 427 504 510 513 612 654 675 704 760 898 908
El algoritmo de Shell tiene diferentes modelos; recogemos en este libro uno de los
ms populares y citados en numerosas obras de programacin.
Algoritmo
i n terv al o ~ n d i v 2
mientras (i n tervalo> O) hacer
desde i ~ ( in te r v a l o + 1 ) hasta n hacer
j ~ i -i n te r va l o
mientras ( j >O) hacer
k ~ j + i nt e rv alo
si a [ j J < = a[ k J
entonces
j ~ O
sino
I n tercamb i o (a [ j]. a[ kJ ) ;
fin si
j ~ j - i nt e r v al o
fin _ mientras
fin_desde
interva l o ~ i n t erv a l o div 2
program Orden a r S h e ll ;
{mo del o d e or de n aci n d e 500 e nteros a l eato r io s}
const
Nu mE l e me n tos = 5 0 0 ;
type
Rango - l . . Nume l e men tos ;
List a - array [ Ra ng oJ of i n te g er;
var
L : Li sta ; "
begin
{programa principal}
WriteLn ('Comienza la ordenacin');
GenerarAleatorios (L, NumElementos);
Shell (L, NumElementos);
visualizar (L, NumElementos)
end.
Las sublistas deben ser ordenadas, independientemente, del mismo modo, lo que ,
La eleccin del pivote es arbitraria, aunque por comodidad es usual utilizar el tnni- ,
no central de la lista original, o bien el primero o ltimo elemento de la misma. ,,
,
Como ejemplo ilustrativo de la divisin de una lista en dos sublistas, consideremos ,
,
.",
,
la siguiente lnea de enteros: .
i'
~
;;
,
9 23 31 17 21 19 13 15 26 ,
j
;
i
9 23 31 17 21 19 13 15 26 ,
,
!
j
1= 1 J=9
9 23 31 17 21 19 13 15 26
.. ..
1 J
Ordenacin, bsqueda y mezcla 519
9 15 31 17 21 19 13 23 26
1 J
5. El proceso se repite
9 15 13 17 21 19 31 23 26
1 J
9 15 13 17 21 19 31 23 26
1 J
9 15 13 17 19 21 31 23 26
J 1
9 13 15 17 19
t t
J 1
Ordenacin, bsqueda y mezcla 521
begin { Partir}
1 : = P ri mero;
J : = Ulti mo ;
{encontrar Elemento pivote (central) }
Central := A [(Prim ero + Ultimo) div 2];
repeat
while A[I] < Centr al do
1:=1+1 ;
while A[J] > Ce n tral do
J :=J- l ;
if 1 < = J then
begin
I n ter camb i ar (A [I ], A [ J]);
1 -- 1 + 1;
J -
- J - 1
end { if }
until 1 > J;
if Pr imero < J
then Partir (Prime ro , JI;
if 1 < Ultimo
then Partir (1, Ult i mo)
end; {Part ir }
begin { Rpido }
Part i r (1, N)
end; {R pido }
(pr og ram a principal)
begin
{ le ct ura de 100 ele ment os al e atorios}
for K : = 1 to 100 do
522 Estructura de datos
begin
Lista [ K] : = Random (1000);
Write (Lista [K] : 8)
endl
WriteLn;
{llama da al procedimiento Rapido}
Rapido (Lista. 100);
{escri tura de la lista ordenada}
for K := 1 to 100 do
Write (Lista [K] : 8);
WriteLn ,
end. ,
,
15.7.1. Anlisis de la ordenacin rpida ,
:!
Algoritmo
l. Dividir la lista en dos mitades.
2. Ordenar la sublista izquierda.
3. Ordenar la sublista derecha.
4. Mezclar las dos sublistas juntas.
EJEMPLO 15.1
9 1 3 5 10 4 6
El proceso consiste en dividir la lista en dos mitades y cada una de las mitades en otras
mitades. Este proceso se repite hasta que cada sublista contiene, cada una, una entrada,
segn se aprecia en el grfico.
l
~
;
~
1
Ordenacin, bsqueda y mezcla 523
L1 L2
9 1 3 5 10 4 6
9 1 3 5 10 4 6
9 1 3 5 10 4 6
9 1 3 5 10 4
La mezcla comienza con las sublistas de un solo elemento, que se mezclan en sublis-
tas ms grandes cuyos elementos estn ya ordenados, y el proceso contina hasta que se
construye una nica lista ordenada.
L2 L1
9 1 3 5 10 4 6
1 9 3 5 4 10
1 3 5 9 4 6 10
, 1 3 4 5 6 9 10
,
Primero Ultimo
Algoritmo OrdMezcla
1. si Primero < Ultimo, entonces {ndices de la lista original}
1.1. Central f- ( Primero +Ultimo) div 2 {punto de divisi n para la
particin}
1.2. Llamar a OrdMezcla a [ Primer o .. Central )
1.3. Llamar a OrdMezcla a [Central+1 .. Ultimo]
1.4. Mezclar a [Primero .. Centr al] con a [C en tral+l. .Ultimo]
begin
if Li st a [X l . C lav e < = L is ta [Yl .Cl ave
then
begin
Aux [ Z 1 : = Li s ta [ X l ;
X := X + 1
end
elee
begin
Aux [ Z 1 : = Lista [ Y l ;
y := Y + 1
end;
Z .. -- Z + 1
end;
y -
-
y + 1;
Z -- Z + 1
end;
( copiar Aux e n Li s ta)
for X : = Ida to Dc ha do
Lista [ Xl : = Aux [ X l
end; (Me z c la)
Este algoritmo de ordenacin est basado en la estructura de montculo. Por lo que vamos
a estudiar en primer lugar el concepto de montculo y despus describimos el algoritmo.
15.9.1. Montculo
Se define un montculo de tamao n como un rbol binario completo de n nodos, tal que
el contenido de cada nodo es mayor o igual al contenido de su padre.
526 Estructura de datos
33 41 18 31
Utilizamos un array para representar el rbol binario, de tal forma que si el ndice i
hace referencia a un nodo, entonces el nodo hijo izquierdo est referenciado por el ndi-
ce 2*i, el nodo hijo derecho por el ndice 2*i + 1, Y el nodo padre por i div 2.
As el nodo raz ocupar la posicin 1 en el array, y en la posicin 2 y 3 estarn sus
nodos hijo izquierdo y derecho, respectivamente.
, La representacin del rbol del ejemplo en un array
7 12 15 19 22 17 16 26 33 29 41 18 31 50
Utilizando esta representacin tendremos que para que se cumpla que todo nodo del
rbol ha de ser mayor o igual que el nodo padre, ha de cumplirse:
V[iJ ~ V[2*iJ
tri = 1 .. nI2
V[iJ ~ V[2*i+ 1J
Es claro que a partir de esta definicin de montculo la raz del rbol (o primer ele-
mento del array) es el elemento ms pequeo; en definitiva, V[l] siempre tendr el ele-
,
mento mas pequeno. -
Segn esto podemos descomponer el mtodo de ordenacin heapsort en los siguien-
tes pasos:
l. Construir un montculo inicial con todos los elementos del vector: V[lJ, V[2J,
I,
... V[nJ
I
I
2. Intercambiar los valores de . V[lJ y V[nJ (siempre se queda el mximo en el ex-
tremo).
3. Reconstruir el montculo con los elementos V[lJ, V[2J, ... V[n - 1].
4. Intercambiar los valores de V[lJ y V[n - 1J.
5. Reconstruir el montculo con los elementos V[l], V[2J, '" V[n - 2].
Ordenacin, bsqueda y mezcla 527
Est claro que estamos en un proceso iterativo que partiendo de un montculo inicial,
repite intercambiar los extremos, decrementar en 1 la posicin del extremo superior y
reconstruir el montculo del nuevo vector. Lo expresamos en forma algortmica:
,.
sltuaClOn .
,"
64
66
23
528 Estructura de datos
V[l] es menor o igual que los valores de sus hijos, entonces la propiedad del
montculo no se ha roto.
En otro caso, el elemento mnimo que necesitamos poner en V[ 1] es o su hijo
izquierdo o su hijo derecho (V[2], V[3], respectivamente). Por lo que se detenni-
na el menor de sus hijos y ste se intercambia con V[l). El proceso contina repi-
tiendo las mismas comparaciones entre el nodo intercambiado y sus nodos hijos;
as hasta llegar a un nodo en el que no se viole la propiedad de montculo, o
estemos en un nodo hoja.
42 42
,
<
<
40
<
<
.-
;
<
<
<
:
,
!
<
---.
Ordenacin, bsqueda y mezcla 529
begin
Inter ca mbi a (V[ Prim e rol, V [Hi jo l);
Pr i mero : = Hijo {p a r a co n t in ua r p or la rama d e c l aves mnima s}
end
elee Es Mtc l o := tru e
end
end;
for j : = n d iv 2 downto 1 do
C r i ba (V , j , n) ;
Codificacin de Heapsort
Antes de escribir la codificacin cabe hacer una observacin. El mtodo ordena descen-
dentemente ya que siempre intercambia el elemento menor, V[1], con el ltimo del mon-
tculo actual. Para que la ordenacin sea en orden ascendente simplemente debemos de
invertir el vector. Pero si se desea que directamente termine en orden ascendente, se
cambia la condicin de montculo de modo que un nodo tenga la clave mayor (en vez de
menor) que las claves de sus hijos.
La codificacin del procedimiento de ordenacin Heapsort:
for i : = 1 to n do
T [ V[i ] .Cl ave ]: = V[i ];
i
Urnas
1 A1 A1 ... -
2 A2 ... - A2
A3 ... -
I
1
I
m Rm ... -
R1 R1
R2 R2 R2
R3 R3
R3
Rm Rm
Rm
const
Li mi te - 1000;
M = 1 00 ; {Mx i mo va l or de l a c l ave}
type
TipoClave = 1 .. M;
Registro = record
Clave: T ipoClave;
end;
Vector = array [ l . . Limite] of Reg istro ;
begin
V[J]:=LA.R;
.. J:= J+l;
L: = LA.Sgte
end
end;
,
I Una urna se considera una lista enlazada en la que se almacenan los elementos ledos con un detelllli-
nado criterio, el valor del dgito en la secuencia creciente de pesos (unidades, decenas, etc.).
534 Estructura de datos
Esta secuencia de fichas ya la tenemos ordenada respecto a los dos ltimos dgitos,
es decir, respecto a las decenas. Por ltimo se distribuye de nuevo las fichas respecto al
tercer dgito:
194 216 236 247 345 365 389 425 431 467 529 572 672 721 746 834 836 891
La idea clave de la ordenacin radix-sort (tambin llamada por residuos) es clasifi-
car por urnas primero respecto al dgito de menor peso (menos significativo) d", despus
,.
concatenar las urnas, clasificar de nuevo respecto al siguiente dgito dk _ l , y as sucesiva-
! mente se sigue con el siguiente dgito hasta alcanzar el dgito ms significativo di' En ese
,
momento la secuencia estar ordenada.
Tipos de datos
Al igual que en el mtodo de binsort las urnas estarn representadas por un vector de
listas. En el caso de que la clave respecto a la que se ordena sea un entero, tendremos 10
urnas numeradas de O a 9. Las listas tienen una realizacin dinmica, cada lista se man-
tiene con dos punteros, uno al frente y otro al final de la lista, as el aadir un nuevo
"-
registro es inmediato ya que se enlaza por el final, de igual forma, concatenar las urnas
consistir en enlazar al final de una con el frente de la siguiente. Estas acciones ya estn
hechas en el mtodo binsort.
A continuacin se presentan los tipos de datos:
const
M = 9; . {numeracin de las urnas 0,1,2,- - -9}
Limite - 1000;
type
TipoClave = O.. maxint;
Registro = record
Clave: TipoClave;
end;
Vector = array[1, .Limite) of Registro;
{tipos para definir las urnas}
,
Puntero =~Nodo;
,
Nodo = record
R: Registro;
, Sgte: Puntero
,
, end;
, Lista = record
,
Frente, Final: puntero
end;
TUrnas = array[O .. M) of Lista;
,
,
I
Ordenacin, bsqueda y mezcla 535
CODIFICACiN
La codificacin supone que se est ordenando respecto a una clave entera y positiva. En
primer lugar se determina el nmero de dgitos que tiene el campo clave, mediante divisio-
nes sucesivas por 10; para ello, se toma el entero mximo que admite la computadora (en
nuestro caso, 32.767). A continuacin, se introducen de modo sucesivo cada elemento
en su correspondiente urna mediante la unidad? y se realizan iteraciones del bucle for 1,
hasta que I es el nmero mximo de dgitos del entero ms grande de la lista a ordenar.
A continuacin se presenta la codificacin del procedimiento de ordenacin Radix Sort.
Peso := 1; {Nos perm ite obte ner los dgi tos de menor a mayo r pe so}
for l : = 1 to Ndig do
begin
CrearUrnas(Urnas); {Crea las urnas con un bucle de O a M}
for J :=1 to N do
begin
D :=(V[J] . c l ave div Peso) mod 1 0 ;
Anadir EnU rna(Urnas [ D], V [J ]) ;
end;
J := O; {bsqueda de pr im era ur na no va c a}
while EstaVacia(Urnas [ J]) do
J := J+1;
for R : = J+ 1 to M do
Enl aza rUr na(Ur nas [J] , Urn as[R ]);
(S e r eco rre l a lista - u rn a re sultante d e la concatenacin)
R : = 1;
L := Urnas[J] .Fren te ;
while L < > nil do
begin
V [R] := LA .r;
R : = R + 1;
A : = L;
L : = LA.Sgte;
dispose(A)
end;
Pe so : = Pe so * 10;
end
end,
!
.~
,
,
536 Estructura de datos "
,
,
15.12. BUSQUEDA LINEAL ,
,,
,
Otro problema importante en proceso de datos, como ya se ha comentado, es la bsque- ,
1
"
da en un conjunto de datos de un elemento especfico y la recuperacin de alguna infor-
.~
Las dos primeras se pueden aplicar a listas implementadas con arrays, y la tercera es
ms propia de estructuras tipo registros o archivos. En esta seccin y en la siguiente
trataremos de la bsqueda lineal y de la bsqueda binaria dejando para el captulo de
archivos el tercer mtodo.
I ,
,
15.12.1. Anlisis
La bsqueda lineal o secuencial es la tcnica ms simple para buscar un elemento en un
,
,
array (vector). Consiste el mtodo en el recorrido de todo el vector, desde el primer
,
elemento hasta el ltimo, y de uno en uno. Si el vector contiene el elemento, el proceso
,
,
devolver la posicin del elemento buscado dentro del vector y, en caso contrario, un
:j
;, ;
mensaje que indique la falta de xito en la bsqueda.
,I
I ;
,
Mediante un bucle desde se compara el elemento t buscado con a[i]. ,En caso de
I
,,
encontrarlo, se almacena la posicin (el ndice del array) del mismo y finalmente se
,
EJEMPLO
Supongamos una /ista de nmeros de la Seguridad Social incluidos en un array a y se
desea buscar a ver si existe el nmero 453714.
Pseudocdigo 1
posi c i on f-- o
{lista = vect or a [il de n e l e men tos}
desde i f-- 1 hasta n hacer
si a [ i 1 = t
entonces posici o n f-- i
fin_si
fin_desde
Este algoritmo tiene un grave inconveniente: sea cual sea el resultado (existe/no existe
el elemento) se recorre el vector completo. El algoritmo tiene una mejora: detectar el
momento de localizar el elemento y terminar el bucle. As, el algoritmo mejorado se
.j
,
Ordenacin, bsqueda y mezcla 537
a[1] 451871
a[2] 120467
a[3] 401321
a[4] 25761
Elemento a buscar: t
~---- 453714
a[98]
339412
a(99)
81467
a(100) 924116
puede realizar con un bucle while o repeat, y utilizando unas banderas (interruptor) que
detecten cundo se encuentra el elemento. El bucle se terminar por dos causas:
La bandera o indicador (En co nt rado , por ejemplo) toma el valor esperado (por
ejemplo, true verdadero ) si la bsqueda ha tenido xito.
El valor del ndice i es mayor que el nmero de trminos de la lista, lo que signifi-
ca que se ha terminado de recorrer la misma y el elemento buscado no ha aparecido.
Pseudocdigo 2
Encontrado f - fals o
Posic i on f- O
i f- 1
mientras (i < = n ) y (No En con trado) hacer
si a [ i 1 = t
entonces Pos i c i o n f - i
En c ontr ad o f - verd a de ro
1 ~ l +l
fin_mientras
,,
Funcin bsqueda lineal ,
1
,
function BusquedaLineal (A:Lista; (entrada, vector bsqueda}
N : integer; {entrada, nmero de elementos}
T : integer; (elemento a buscar}) : integer;
var
Encontrado : boolean;
I : integer;
begin
BusquedaLineal := O; {posicin del elemento caso de no existir}
Encontrado := false;
I : = 1;
while (I <= N) and not Encontrado do
if A[I] = T then
begin
BusquedaLineal .. - I',
Encontrado := true;
end (fin del if )
else I : = I + 1
end; (posicion del elemento en la lista)
-
,
program LinealBusqueda;
const
Total = 100;
type
Li s ta = array [1 .. To tal] of int e ger;
var
L : List a ;
P, J, Num : intege r;
function Bu s q ued a Linea l (t: i n t eg er ; A: L i s ta;Maximo : int e ger): integ er ;
var
1 : in te g er;
En co ntrad o : boo l ean;
begin
En co ntra do := fal se ;
1 .. -- O',
while (1 < Maxim o) and not Encontr a d o do
begin
1 := 1 + 1:
En c o ntr a d o : = A[I ) - t
end;
if En c on t r ad o
then Bu s qued a Linea l -- 1
elBe Bu squ eda Line a l -- O
end;
t = O [f(n)]
o simplificando
t = O(n)
540 Estructura de datos
,
15.13. BUSQUEDA BINARIA
La bsqueda lineal, por su simplicidad, es buena para listas de datos pequeas, para
listas grandes es ineficiente; la bsqueda binaria es el mtodo idneo. Se basa en el
conocido mtodo de divide y vencers.
Este mtodo tiene una clara expresin en la bsqueda de una palabra en un dicciona-
rio. Cuando se busca una palabra no se comienza la bsqueda por la pgina 1 y se sigue
secuencialmente, sino que se abre el diccionario por una pgina donde aproximadamen-
te se piensa puede estar la palabra, es decir, se divide el diccionario en dos partes; al
abrir la pgina se ve si se ha acertado o en qu parte (la primera o la segunda) se encuen-
tra la palabra buscada. Se repite este proceso hasta que por divisiones o aproximaciones
sucesivas se encuentra la palabra.
Supongamos que la lista donde se busca es
1331
1373
1555
1850
1892
1898 ....f - - - - elemento central
elemento buscado ----~ 1989
2002
2400
2670
3200
, El elemento central en esta sublista es 2400, y como 1989 es menor, la nueva sublista
donde buscar es
I,
1989 ....f - - - - elemento considerado central
2002
Algoritmo
l. Esta bl ecer Prime ro ~l y Ult im o ~n (n , nm ero d e e leme n to s). Es ta s
var i ab l es rep r ese n ta n l a pr i mera y lt i ma p o sic i n de la l i sta o
sublista donde se est bus c ando y permi te e l clcu l o de l a pos ic i n
d el el eme nto cen tr al .
2. E ncontrado ~ falso (var i able lgica) .
3. mientras Pri mero < = Ult imo y no Encon t rado hacer
{En c o n t r a r pos ic in ce ntra l}
Ce ntral~(Pr i mero+Ult i mo) div 2
{Compara r e l e me n to buscado t co n a (Ce n tral] )
si t = a[ Centra l ]
entonces E ncont r ado ~ v er dade r o
sino si t > a [Centra l ]
entonces Primero~Centra l + 1
sino U l timo ~ Centr al - 1
4. si Encontrado
entonces P osic io n ~ Ce nt ral {exi st e el el eme nt o}
sino posic i on ~ O {no se ha encontrado}
fin_si
Programa
La bsqueda binaria requiere una ordenacin previa del vector o lista en el que se va a
efectuar la bsqueda. Por consiguiente, las acciones tpicas (mdulos) en un algoritmo
de bsqueda binaria son:
n n n
2' 4' 8 'oo.
,
,
!
Ordenacin, bsqueda y mezcla 543
El proceso terminar cuando el tamao se hace igualo menor que l. Por consiguiente, si
k es el nmero mayor de comparaciones
o bien
.
Si se toman logaritmos en base 2, en ambos lados, se tiene
log2n :5 k. log22 = k
log2n :5 k
que es bastante ms rpido que la bsqueda lineal, como se puede ver en la Figura 15.3,
que representa las dos funciones O.
El tiempo que se ahorra utilizando el algoritmo de bsqueda binaria es muy conside-
rable. Para una lista de 50.000 elementos, la bsqueda lineal en el peor de los casos
requiere 50.000 comparaciones y 25.000 por trmino medio, mientras que la bsqueda
binaria nunca requerir ms de log2 50.000. A fin de ser sinceros, al tiempo de la bs-
queda binaria habra que sumarle el tiempo empleado en ordenar la lista.
y=x
Recuerde
". La bsqueda binaria sl() funciQna~ C.o rrectamente si la lista est ordena.da. Sin
embargo, la bsqueda line;llfuncjona.tantQ;si la lista est ordenadac()mosjno~st
'. ordenada. .. .' " .
. _. ..
Ji _-
Programa
function Busqueda (var A:Lista; Max, Min:integer; Clave: i nteger) :boolean;
var
Central : integer; {elemento cen tr al del array }
begin
if Min > Max
then Busqueda := false
el Be
begin
Central := (Ma x + Min) div 2;
if A[Central] = Clave
then
Busqueda := true
elBe
begin
if Clave> A [Central]
then
Min := Cen tr al + 1
elBe
Max := Central - 1;
Busqueda := Busqueda (A, Max, Min, Clave)
end
end
{bsqueda}
end;
Ordenacin, bsqueda y mezcla 545
type
Info Emp - record
Nombre : string [30] ;
Nu mSS : i nteger ; {nme ro de la Segur idad Soc ial}
Salario: real ;
Edad : integer;
end
Arr ay _ Emp = array [1 .. 1 00 ] of In f o Emp;
var
L i s ta : Array_Emp;
Parmetros de entrada
Lista
Clave (nmero de la Seguridad Social buscado)
Primero, Ult imo (lmite del array ndices )
Parmetros de salida
Indi ce (posicin que ocupa el nmero de la SS buscado, NumSS)
Programa
procedure BusquedaBin (var Lis ta :Array_Emp; var Indice:integer;
15.15. MEZCLA
El proceso de mezcla, fusin o intercalacin (merge en ingls) consiste en tomar dos
vectores ordenados (a, b) y obtener un nuevo vector (e) tambin ordenado.
El algoritmo ms sencillo para resolver el problema es:
EJEMPLO 15.2
2 4 78 97 Lista A
-15 O l3 15 78 90 96 Lista B
..
Ordenacin, bsqueda y mezcla 547
2 4 78 97 Lista A
I Comparar A[i} y BUJ.
Poner el ms pe queo en C[k}.
<
'- ./ Incrementar los ndices apropiados
-15 O 13 15 78 90 94 96 Lista B
2 4 78 97 Lista A
7
j se ha incrementado,
< junto con k
:;:::.
-15 O Lista B
. ....
-.
-15 O Lista e
B[] < AlI], de modo que C[k] se obtiene de B[]
begin
e [ K] - A [1 ] ;
1 - 1 + 1
end
elee
begin
e [K] -- B [J] ;
J . -- J + 1
end;
K .. -- K + 1
end;
{copi ar el resto del vector no ago tado }
if 1 > M
then
for P := J to N do
begin
e [K] := B [Pl;
K := K + 1
end
elee {J > N}
for P := 1 to M do
begin
e [K] := A[P];
K : = K + 1
end
end;
548 Estructura de datos
RESUMEN
Los procesos de programacin ms usuales son: bsqueda y ordenacin. Son partes esenciales de un
gran nmero de programas de procesamiento de datos. La bsqueda y la ordenacin son tambin
procesos que se encuentran nOllnalmente en la vida diaria. Es necesario constatar el hecho de que en
muchas ocasiones se consigue una eficiencia considerable cuando se trata de buscar palabras en un
diccionario o un nombre en una direccin telefnica, que vienen dispuestas en orden alfabtico.
Los procedimientos de bsqueda bsicos son: lineal y binaria. Una bsqueda lineal es slo
adecuada para listas de datos pequeas, mientras que para una lista de datos larga es muy inefi-
ciente. Uno de los mtodos de bsqueda ms eficiente es la bsqueda binaria. '
Los mtodos de ordenacin simple presentan muy poca diferencia en la eficiencia y as, para
listas o vectores pequeos, se pueden considerar los algoritmos de ordenacin, ordenacin mix-
tos, etc" mientras que para listas o vectores ms grandes, los algoritmos ms eficientes son las
ordenaciones de seleccin y de Shell. Segn un estudio de Hale y Easton I de 1987, los tiempos de
ordenacin requeridos para ordenar arrays de 512 y 2.500 elementos son:
Para el caso de arrays grandes, se consideran los mtodos de ordenacin avanzados, que son
mucho ms rpidos y eficientes que los mtodos de ordenacin elementales ya citados. Sin em-
bargo, excepto en el caso de ordenacin rpida (quicksort), los mtodos avanzados son mucho
ms grandes en cdigo que las ordenaciones simples.
Los tiempos requeridos para los mtodos de ordenacin avanzados en el caso de arrays de
512 y 2.500 elementos se resumen en la siguiente tabla (Hale y Easton, 1987):
EJERCICIOS
15.1. Escribir un programa que lea una serie de nmeros enteros, los ordene en orden descen-
dente y a continuacin visualice la lista ordenada,
1 Hale, Guy J., y Easton, Richard J.: Applied Dala Struclures Using Pascal, Lexington, Massachusetts,
Heat and Company, 1987, pgs. 158 y 419.
Ordenacin, bsqueda y mezcla 549
15.2. Un mtodo de ordenacin muy simple, pero no muy eficiente, de elementos Xl' X2' X3, ... X n
en orden ascendente es el siguiente:
Paso 1: Localizar el elemento ms pequeo de la lista Xl a X n ; intercambiarlo con Xl.
Paso 2: Localizar el elemento ms pequeo de la lista X2 a X., intercambiarlo con X2 .
Paso 3: Localizar el elemento ms pequeo de la lista X3 a X., intercambiarlo con X3'
En el ltimo paso, los dos ltimos elementos se comparan e intercambian, si es necesario,
y la ordenacin se termina. Escribir un programa para ordenar una lista de elementos,
siguiendo este mtodo.
15.3. Escribir un programa que lea 42 nmeros enteros en un array 7 x 6 y realizar las siguientes
operacIOnes:
a) Imprimir el array.
b) Encontrar el elemento mayor del array.
e) Indicar dnde se encuentra el elemento mayor del array.
d) Si el elemento mayor est repetido, indicar cuntas veces y la posicin de cada ele-
mento repetido.
15.4. Igual que el ejercicio 15.1, pero con el mtodo Shell.
15.5. Se lee una lista de nmeros desde teclado y se desea saber si entre dichos nmeros se
encuentra el 333. En caso afirmativo, visualizar su posicin en la lista. Resolver el proble-
ma por:
a) Bsqueda secuencial.
b) Bsqueda binaria.
PROBLEMAS
15.1. Dado un vector x de n elementos reales, donde n es impar, disear una funcin que calcule
y devuelva la mediana de ese vector. La mediana es el valor tal que la mitad de los nme-
ros son mayores que el valor y la otra mitad son menores. Escribir un programa que com-
pruebe la funcin.
15.2. Se trata de resolver el siguiente problema escolar. Dadas las notas de los alumnos de un
colegio en el primer curso de bachillerato, en las diferentes asignaturas (5, por comodidad)
se trata de calcular la media de cada alumno, la media de cada asignatura, la media total de
la clase y ordenar los alumnos por orden decreciente de notas medias individuales.
15.3. Se dispone de dos vectores, Maestro y Esclavo, del mismo tipo y nmero de elementos. Se
deben imprimir en dos columnas adyacentes. Se ordena el vector Maestro, pero siempre
que un elemento de Maestro se mueva, el elemento correspondiente de Esclavo debe mo-
verse tambin; es decir, cualquier cosa que se haga a Maestro[i] debe hacerse a Esclavo[i].
Despus de realizar la ordenacin se imprimen de nuevo los vectores. Escribir un progra-
ma que realice esta tarea.
15.4. Cada lnea de un archivo de datos contiene informacin sobre una compaa de informti-
ca. La lnea contiene el nombre del empleado, las ventas efectuadas por el mismo y el
nmero de aos de antigedad del empleado en la compaa. Escribir un programa que lea
la informacin del archivo de datos y a continuacin la visualice. La informacin debe ser
ordenada por ventas de mayor a menor y visualizada de nuevo.
550 Estructura de datos
15.5. Se desea realizar un programa principal que realice las siguientes tareas con procedi-
mientos o funciones:
a) Leer una lista de nmeros desde el teclado.
b) Visualizar dichos nmeros.
e) Ordenar en modo creciente.
d) Visualizar lista ordenada.
e) Buscar si existe el nmero 444 en la lista.
15.7. Escribir un programa que genere un vector de 10.000 nmeros aleatorios de l a 500.
Realice la ordenacin del vector por dos mtodos:
Binsort
Radixsort
Escriba el tiempo empleado en la ordenacin de cada mtodo.
15.8. Escribir un programa que lea una serie de nmeros enteros, los ordene en orden descen-
dente y a continuacin visualice la lista ordenada.
15.9. Un mtodo de insercin muy simple, pero no muy eficiente, de elementos X" X 2, . , X.
en orden ascendente es el siguiente:
Paso 1: Localizar el elemento ms pequeo entre XI y X. y cambiarlo con XI'
Paso 2: Localizar el elemento ms pequeo entre X 2 y X. y cambiarlo con X 2
Ice
abierto-cerrado, 93 bsqueda secuencial, 536
Abstraccin, 3, 4, 5, 24, 84, 97, 107 de ordenacin, 565
Ada, 24 eficiencia, 553
Ada 95, 115 notacin O-grande, 556
Algoritmo, 4 ordenaciones cuadrticas, 514
anlisis, 553-571 orden de magnitud, 554
rbol de expansin de coste mnimo, 483, ordenacin por burbuja, 507, 566
851
,
852 In dice
Errores, 32 Funcin, 32
compilacin, 44 hash, 623
localizacin, 39 Fusin, 546
lgicos, 45 .
reparacin de, 39
sintaxis, 44 gda,456
tiempo de ejecucin, 45 Genericidad, 110
tratamiento, 323 getmem, 145, 146
Estructura de datos, 5 goto, 31
dinmica, 125 grafo, 417
, .
estattca, 126 rbol de expansin mnimo , 48
de salida, 419
I
Fibonacci, 264 flujo , 470
Ficheros, 581 fuertemente conexo , 421
I bases de datos, 584 lista de adyacencia, 424
I, bloque, 585 matriz de adyacencia, 424
i campo, 582 matriz de caminos, 442, 459
I
,! clave, 585 no dirigidos, 418, 419
iI concepto, 581, 583 realizacin con listas de adyacencia,
,.
i
,
854 In dice
bsqueda, 162
especificacin formal, 153, 155
l
r
,
856 Indice
obsoleto, 15 Requisitos, 11
reglas para pruebas, 17 especificacin, 11
verificacin, 16 Reutilizacin, 110
Programacin, 5
a gran escala, 9
a pequea escala, 9
Simula, 98
equipos, 41
Smalltalk, 114
estilo, 28
Software, 15
estructurada, 11 6
ciclo de vida, 3, 9, 15
facilidad de uso, 27
construccin, 106
imperativa, 98
evolucin, 15
orientada a objetos, 9
le, 110
paradigma, 88
iteracin, 15
segura contra fallos, 26
sistemas de, 23
Programacin orientada a objetos, 5, 7, 9,
Solapamiento, 75
683
sort, 500
PROLOG,89
Subprograma, 29
I
declaracin, 127 Tecnologas Orientadas a Objetos, 118
,
I iniciacin, 135 beneficios, 119
, lista enlazada, 160 testing, 3, 42
I,,
problema del laberinto, 293 tratamiento, 793
problema de la mochila, 290 gua de referencia, 807
, problema de la seleccin ptima, 297 mens, 769
problema de los matrimonios estables, Compile, 773
300-306 Debug,774
procedimiento recursivo, 263 Edi t ,770
Redundancia, 24 Help,778
release, 146 Opt ions, 775
ndice 857
Run,774 Graph,740 ,
,
.
I
f
,,
,
,
,,
-r'" _ ,