Sie sind auf Seite 1von 88

ALGORITMOS Y LENGUAJES

NDICE

1. INTRODUCCIN AL DISEO Y TEORA DE ALGORITMOS


1.1 INTRODUCCIN: CONCEPTO DE PROBLEMA ............................................................... 1
1.2 DATOS E INFORMACIN ............................................................................................ 3
1.3 DEL PROBLEMA AL PROGRAMA ................................................................................. 3
1.4 SIGNIFICADO DEL TRMINO ALGORITMO.................................................................... 6
1.5 ALGORITMOS, PROGRAMAS Y LENGUAJES DE PROGRAMACIN ............................... 12
1.6 SINTAXIS Y SEMNTICA .......................................................................................... 16
1.7 PROCEDIMIENTO DE REFINAMIENTO DE ALGORITMOS POR PASOS SUCESIVOS .......... 20
1.8 SECUENCIA ............................................................................................................. 25
1.9 SELECCIN ............................................................................................................. 26
1.10 ITERACIN ............................................................................................................ 30
1.11 REVISIN DE LAS ESTRUCTURAS DE SECUENCIA, SELECCIN E ITERACIN ............ 38
1.12 ACTIVIDADES ....................................................................................................... 42

2. CONCEPTOS DE MODULARIDAD, RECURSIN Y PARALELISMO


2.1 MODULARIDAD....................................................................................................... 43
2.2 RECURSIN ............................................................................................................. 49
2.3 PARALELISMO ......................................................................................................... 58
2.4 ACTIVIDADES ......................................................................................................... 64

3. INTRODUCCIN A LAS ESTRUCTURAS DE DATOS


3.1 INTRODUCCIN ....................................................................................................... 65
3.2 ESTRUCTURAS DE DATOS MS USUALES ................................................................. 67
3.3 REPRESENTACIN INTERNA DE LAS ESTRUCTURAS DE DATOS ................................. 71
3.3.1 Asignacin secuencial .................................................................................... 71
3.3.2 Listas enlazadas .............................................................................................. 72
3.4 EJEMPLO DE APLICACIN: ALGORITMO DE ORDENACIN UTILIZANDO UN
RBOL BINARIO .....................................................................................................77
3.5 ACTIVIDADES ......................................................................................................... 81

APNDICE I. CDIGO ASCII.......................................................................... 83

DPTO. INFORMTICA Y AUTOMTICA.UNED.

ALGORITMOS Y LENGUAJES

DPTO. DE INFORMTICA Y AUTOMTICA. UNED

ALGORITMOS Y LENGUAJES

1. INTRODUCCIN AL DISEO Y TEORA DE ALGORITMOS

1.1 INTRODUCCIN: CONCEPTO DE PROBLEMA


Sin gnero de dudas, podemos catalogar esta poca como la "era de la informtica",
dado el impacto que los computadores estn teniendo tanto a nivel de la sociedad como
personal. Pocas cosas hay en nuestro mundo cotidiano que de alguna forma no lleven
detrs de s un computador. Un computador controla el trfico en las grandes ciudades,
hace posible todo el sistema bancario, prepara el pago de nuestras nminas, permite que
Hacienda controle el pago de nuestros impuestos, hace posible el sistema de reserva de
billetes, resulta indispensable en las unidades de vigilancia intensiva, no hubiese sido
posible la llegada del hombre a la luna sin su concurso y mil ejemplos ms que al hilo de
estas referencias se le estarn ocurriendo seguramente al lector. Piense por un momento
el caos que se ocasionara si todos los computadores dejasen de funcionar!
Lo que resulta verdaderamente sorprendente es que todo esto haya ocurrido en apenas
50 aos, que hace que todava vivan personas de la primera poca de los computadores
que hicieron posible que la informtica sea lo que hoy da es.
La importancia econmica del mundo de los computadores es incuestionable. En la
actualidad por el volumen de recursos econmicos que manejan se sita inmediatamente
detrs de las industrias del petrleo y del automvil y se espera que antes de que finalice
este siglo, habr superado a ambas.
Quizs la gran aceptacin que a nivel de gran publico ha tenido la Informtica deriva de
su carcter instrumental como herramienta para resolver problemas
independientemente del valor intrnseco que como disciplina posee
Es bajo sta ptica, desde la que se aborda este tema. Aunque parezca una trivialidad, lo
que al ser humano se le presentan son problemas a los que una vez planteados de forma
correcta, trata de encontrar soluciones. En el paso del problema a la solucin veremos
que un computador aparece como un elemento muchas veces indispensable y es aqu
donde reside su verdadera importancia.

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

INTRODUCCIN AL DISEO Y TEORA DE ALGORITMOS

El concepto de problema, desde un punto de vista general, es fundamental y al mismo


tiempo tiene un cierto carcter de punto de origen en el sentido de que resulta imposible
definirlo en funcin de otros conceptos. De alguna manera todos tenemos una idea ms o
menos intuitiva del significado semntico que asociamos al trmino problema
Sin embargo aqu vamos a dar un enunciado operacional del mismo Un problema ser un
enunciado tal que, partiendo de los datos que se nos proporcionen, existe un tratamiento
que, en tiempo finito, nos da unos resultados que llamaremos solucin del problema.

TRATAMIENTO
Datos

Resultados
Figura 1.1

El hombre puede pensar de forma precisa sobre problemas simples: por el contrario, en
el esfuerzo que realiza para entender problemas complicados, necesita concentrarse en
un pequeo nmero de propiedades que cree esenciales para su propsito e ignora todos
los dems aspectos. En cierto sentido, su eficacia para resolver problemas, reside en la
mxima "divide y vencers".
Una vez que entiende un problema en trminos de un nmero limitado de aspectos,
procede a analizar cada uno de ellos separadamente, con ms detalle. Es normal que sea
necesario repetir este proceso, con lo que el problema original aparece como una
jerarqua de abstracciones relacionadas a diferentes niveles de detalles. El conjunto de
conexiones entre componentes, a un nivel dado de detalle, define la estructura del
problema a ese nivel.
Los mecanismos de abstraccin y de reconocimiento de la estructura subyacente se usan
en todas las disciplinas intelectuales, para presentar los conocimientos en una forma fcil
de entender y de recordar. Se aplica pues un mecanismo de anlisis descendente del
problema (top-down) o de refinamiento por pasos sucesivos que ser objeto de nuestra
atencin posteriormente.

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

ALGORITMOS Y LENGUAJES

1.2 DATOS E INFORMACIN


El intercambio de ideas y hechos entre los hombres, en forma hablada, est basado en un
acuerdo mutuo sobre el significado que asignamos a ciertos sonidos y combinaciones de
los mismos. Otros convenios nos capacitan para expresar las mismas ideas mediante
textos, dibujos, etc. o sea, nos comunicamos mediante fenmenos fsicos que escogemos
para representar ciertos aspectos de nuestro mundo.
Estas representaciones fsicas de nuestras abstracciones se llaman datos y el significado
que le asignamos representa su informacin asociada.
Los datos se usan para transmitir informacin entre los hombres, para almacenarla con
vistas a su uso futuro y para obtener nuevas informaciones mediante la manipulacin de
los mismos, de acuerdo con ciertas reglas. Podemos pues decir, que la informacin es el
concepto y el dato su materializacin manipulable. Las computadoras procesan datos y
no conceptos (informaciones).

1.3 DEL PROBLEMA AL PROGRAMA


Como punto de partida analicemos de forma muy sucinta que condiciones parece que
son necesarias para que tengamos que utilizar un computador. En principio surgen
claramente tres condiciones, que aunque resulten obvias muchas veces no se explicitan
suficientemente:
1) Para utilizar un computador resulta evidente que en cierta medida necesitamos
conocer su modo de funcionamiento y la forma de manejarlo (a nadie se le
ocurrira utilizar un automvil si realmente no sabe conducir). Esto se traduce
en que el usuario de un computador deber conocer un cierto lenguaje de
programacin, que lo que hace en definitiva es establecer las reglas de juego
que permiten la comunicacin hombre-mquina.
2) Si vamos a utilizar un computador es porque tenemos un problema que resolver
con su ayuda. Esta reflexin que a muchos puede parecer una nimiedad tiene un
significado mucho ms profundo que el que aparentemente se manifiesta en una
primera lectura. El motor que desde siempre ha movido al hombre a mejorar su
condicin ha sido la necesidad imperiosa de resolver los distintos problemas que

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

INTRODUCCIN AL DISEO Y TEORA DE ALGORITMOS

a lo largo de toda su historia se le han ido presentando. Sin problemas el resto


carece de sentido y por supuesto no iba a ser una excepcin el mundo de los
computadores.
3) Finalmente no basta con tener un problema, hay que saber cmo resolverlo
desde un punto de vista formal, es decir, aunque no conozcamos la solucin, se
trata de especificar de forma precisa y sin ambigedades, los pasos que
hay que dar para a partir de unos datos obtener una solucin.
Observe el lector que de las tres condiciones anteriores, en las dos ltimas no interviene
en ningn sentido el computador cuya utilidad aparece en la obtencin de soluciones
concretas. Es pues importante advertir desde el comienzo que un computador no nos
indica como tenemos que resolver un problema, cuestin esta que requiere de la
intervencin directa del ser humano. Aunque esto puede parecer una desgracia, en ltimo
trmino no es ms que un fiel reflejo de la supeditacin de la mquina al hombre.
Suponiendo cumplida la 1 condicin (conocer un lenguaje de programacin, cuestin
esta que abordaremos a lo largo del curso), hay que pasar del problema concreto a un
programa escrito de acuerdo con la reglas de un lenguaje de programacin. Esto se
denomina programacin. El paso problema-programa no se hace en general, de forma
inmediata, salvo en casos triviales. La dificultad del paso depende a la vez de la
complejidad del problema y de la estructura del lenguaje de programacin.
De forma sinttica las etapas comunes a seguir son las siguientes:
a) En primer lugar debemos concretar el problema. Para ello se utiliza,
fundamentalmente, el lenguaje natural. El resultado de esta etapa, que tiene por
objeto la eliminacin de ambigedades, es la obtencin de un enunciado del
problema. El enunciado expresa la descripcin de aquel en un lenguaje no
ambiguo pero que no dice nada acerca de su resolucin.
b) Para resolver un problema es necesario encontrar un algoritmo. Aunque a la
nocin de algoritmos nos referiremos ya en la prxima seccin podemos
considerarlo, en este momento, como la expresin en forma dinmica de los
pasos necesarios para la resolucin del problema.

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

ALGORITMOS Y LENGUAJES

c) Finalmente hay que expresar el algoritmo en un lenguaje comprensible para el


computador, es decir, en un lenguaje de programacin. El algoritmo expresado
as recibe el nombre de programa.
Vemos pues que los pasos a seguir son:
PROBLEMA ENUNCIADO ALGORITMO PROGRAMA

A ttulo ilustrativo planteamos el siguiente problema.


Problema:
Supongamos que queremos realizar el clculo de una nmina. Ya tenemos el
problema.
Enunciado:
Hay que calcular la nmina de un empleado.
1) Los datos ( nombre, apellido, salario bruto) estn en el fichero X.
2) Queremos recibir una hoja impresa con la identificacin del empleado y el
detalle de salario bruto, neto y descuento
Algoritmo:
Paso 1.

Leer nombre, apellidos y salario bruto del fichero X.

Paso 2.

Calcular descuentos (impuesto a cuenta, seguridad social,


derechos pasivos)

Paso 3.

Imprimir nombre y apellidos, salario bruto, salario neto y


descuentos.

Programa:
La expresin de ese algoritmo en un lenguaje de programacin. De esta forma
queda perfectamente comprensible para el computador.

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

INTRODUCCIN AL DISEO Y TEORA DE ALGORITMOS

1.4 SIGNIFICADO DEL TRMINO ALGORITMO


Un computador puede realizar nicamente aquellas tareas que se especifican en funcin
de las operaciones que puede ejecutar. Para hacer que una computadora ejecute una
tarea debemos decir que operaciones tiene que efectuar, en otros trminos, hay que
describir cmo se realiza dicha tarea. A esta descripcin la denominamos un algoritmo.
El algoritmo consiste en una secuencia de pasos que si se ejecutan exactamente en la
forma en que se especifica, da como resultado el que la tarea o proceso se lleve a cabo.
El trmino algoritmo procede del nombre de un matemtico rabe Alkhorizmi, que a
principios del siglo IX dio las reglas para efectuar las cuatro operaciones aritmticas con
nmeros escritos en forma decimal.
El concepto de algoritmo no es solamente caracterstico de las ciencias de la
computacin, ya que existen algoritmos que describen toda clase de procesos de nuestra
vida cotidiana. En la Figura 1.2 presentamos algunos ejemplos ilustrativos de esta
afirmacin. En estos ejemplos, los procesos los ejecuta el hombre. De forma genrica el
elemento activo que realiza un proceso se denomina procesador. As pues, un
procesador puede ser una persona, un computador o cualquier dispositivo que
materializa un algoritmo, es decir, un procesador realiza un proceso ejecutando el
algoritmo que lo describe. La ejecucin de un algoritmo implica la ejecucin de cada uno
de los pasos que lo constituye.

Proceso
Hacer un postre

Algoritmo
Receta

Pasos tpicos del algoritmo


Tomar 3 huevos, batir las claras
a punto de nieve, etc.

Hacer un vestido

Patrn del vestido

Tocar una sonata de Bach

Partitura musical

Construir un modelo de avin

Instrucciones de

Zurcir la costura lateral

Pegar el alern B al panel A

ensamblaje
Figura 1.2 Ejemplos de algoritmos prcticos en nuestra vida cotidiana

En particular un algoritmo viene caracterizado por las siguientes propiedades:

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

ALGORITMOS Y LENGUAJES

a) Naturaleza determinstica. Un algoritmo debe formularse como una lista


finita de pasos que dan el procedimiento exacto que ha de seguirse para, a
partir de una entrada determinada obtener la correspondiente salida,
independientemente de quien lo ejecuta. Se trata pues de un procedimiento "no
ambiguo". Realmente el termino no ambiguo a veces resulta muy ambiguo.
Ambiguo a quin o a qu? Como no existe nada que de forma universal sea
totalmente claro o vago, al menos debe de especificarse, implcitamente, el
ejecutor de dicho algoritmo. As, un algoritmo para calcular una integral es
perfectamente comprensible a alguien que tiene conocimientos de anlisis
matemtico, pero resultara incomprensible a quien no los posee.
b) Finitud. Todo algoritmo necesariamente ha de concluir en un nmero finito de
pasos. La condicin de terminacin o no terminacin de un proceso es una de
sus caractersticas bsicas. Una gran fuente de error en el diseo de un
algoritmo es que, bajo determinadas circunstancias, el proceso que describe
puede no terminar nunca, mientras que se supone, que un algoritmo siempre
tiene un final.
Los ejemplos siguientes ilustran de algn modo los dos puntos anteriores de no
ambigedad y finitud de los algoritmos.

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

INTRODUCCIN AL DISEO Y TEORA DE ALGORITMOS

Problema 1. Es 7321 un Algoritmo. Dividir 7321 por Comentario.


nmero primo?

este

cada uno de los ns 2, 3, 4, algoritmo es una solucin de


...., 7320. Si alguna divisin fuerza

(Un nmero es primo si


nicamente es divisible por s
mismo y por la unidad)

Realmente

bruta

resulta exacta la respuesta es problema,

para

nuestro

que

existen

ya

afirmativa en caso contrario algoritmos mucho ms eficaces


ser negativa.

para resolver el mismo problema.


Pero de lo que s estamos seguros
es de que con este algoritmo
resolveremos el problema.

Problema 2. Cmo hacer Procedimiento. Tome 10.000 Comentario. Observe que hemos
10.000.000 de pts.?

pts. y vyase por ejemplo a un puesto


Bingo. Juegue hasta que:

procedimiento

algoritmo

pts.
b) pierda todo el dinero.

no

porque

(!desgraciadamente
a) rena los 10.000.000 de

para

nosotros!) puede no resolver el


problema (lo ms probable) y en
general un algoritmo lo resuelve.
Adems este procedimiento no
cumple la condicin de finitud
pues puede no terminar nunca,
basta para ello que no ganemos los
10.000.000 de pts. ni perdamos
todo nuestro dinero

Problema 3. Rellenar una Algoritmo. Tome una pala y Comentario. Este algoritmo es
zanja de tierra.

comience a tirar tierra en la muy

simple

no

tiene

zanja. Cuando la zanja est ambigedad. Estamos seguros de


llena pare.

que finalmente la zanja se llenar


aunque no tenemos idea de cuanto
tiempo se tardar en ello (depende
del tamao de la zanja y de la
pala).

Figura 1.3 Ejemplos de algoritmos

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

ALGORITMOS Y LENGUAJES

c) Generalidad. Un algoritmo es una nica lista de instrucciones definiendo un


clculo que puede ser llevado a cabo sobre cualquier conjunto de datos
iniciales y que en cada caso da el resultado correcto. En otras palabras, un
algoritmo dice cmo resolver no slo un problema particular sino toda una
clase de problemas similares.
Por ejemplo, si tenemos un algoritmo que nos permite ordenar los nmeros de menor a
mayor, la descripcin del mismo ser independiente de cules son los nmeros que en
concreto queremos ordenar en cada caso particular.
Ilustremos estas ideas con un ejemplo: "Encontrar la raz cuadrada del nmero
real x". Como sabemos, este problema es, algortmicamente o trivial o no soluble,
debido al carcter irracional de la mayora de las races cuadradas. Si se acepta 2 como
la raz cuadrada de dos, la solucin es trivial; la respuesta es el signo raz cuadrada ( )
concatenado con la entrada. Sin embargo, si se necesita una expresin decimal, entonces
la raz cuadrada de 2 no puede calcularse nunca. Por tanto, el requisito de un nmero
finito de pasos (condicin de finitud) se viola en este caso.
Una modificacin en el enunciado del problema, ms acorde con nuestros objetivos sera
la siguiente: "Encontrar con precisin de cuatro dgitos decimales la raz
cuadrada positiva del nmero real x". Esta formulacin tiene tres propiedades
tiles:
1) Se dice explcitamente que se desea obtener la raz cuadrada positiva en
oposicin al enunciado previo que lo dejaba en forma ambigua.
2) Se elimina

2 como una solucin del problema

3) Dando la precisin con la que se quiere obtener el resultado, se est


suministrando un test para la terminacin del algoritmo (condicin de finitud).
Un posible mtodo de solucin es el siguiente:
Paso a:

Escoger un nmero z y calcular z2.

Paso b:

Si (z2-x) < 0.00005, entonces la solucin es z si no ir al


paso (a).

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

INTRODUCCIN AL DISEO Y TEORA DE ALGORITMOS

Este mtodo no puede ser considerado como un verdadero algoritmo, ya que no


especifica ni el valor inicial de z, ni cmo escoger los valores subsiguientes. An ms, si
hay solucin no existe garanta de que podamos encontrarla utilizando este
procedimiento. Consideremos pues, otro mtodo:
Paso a:

Hacer z = 1

Paso b:

Calcular z2

Paso c:

Si (z2-x) < 0.00005 entonces la solucin es z si no ir al


paso (d).

Paso d:

Reemplazar z por 0.5(z + x/z), ir al paso (b).

este procedimiento es un caso especial del mtodo de Newton-Raphson (ver Figura 1.4).
De esta forma se obtendr una secuencia de puntos z0, zl, z2, .... que, finalmente
converger a la solucin z con la precisin que se desee.
E1 procedimiento anterior tiene en cada paso la definicin precisa requerida por un
algoritmo. Mas an, siempre que se aplica a un nmero real no negativo x, se obtendr
la solucin correcta en un numero finito de pasos. Sin embargo, siempre que se aplica a
un nmero negativo, se estar recalculando indefinidamente z sin que por ello se
reconozca lo intil de esta tarea. Esto es tpico de una clase de mtodos llamados semialgoritmos: pararn en un nmero finito de pasos si el problema planteado tiene
solucin, pero no terminar necesariamente en caso contrario.
Para transformar el mtodo dado en un algoritmo, se debe hacer una cosa: aadir un
paso 0;
Paso 0:

si x < 0 no existe solucin.

Aunque el concepto de algoritmo es til para cristalizar la nocin informal de mtodo


de solucin para un problema, tiene no obstante una significacin mucho ms
profunda, cuyo anlisis riguroso se sale fuera del marco de las ideas que aqu estamos
exponiendo. Durante mucho tiempo se advirti implcitamente que todo problema
matemtico enunciado correctamente tena solucin. Hacia 1920 los matemticos
empezaron a cuestionrselo, preguntndose precisamente qu significa decir que
podemos resolver un problema.

10

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

ALGORITMOS Y LENGUAJES

f(z)

f(z)

z
(z , f(z ))
0

valor buscado

parbola
f(z) = z2 - x

a) Representacin grfica de la solucin

b) A partir de una condicin inicial (z , f(z ))


0

se traza una recta que pasando por dicho punto


sea tangente a la parbola
f(z) - f(z0 )) = f' (z0 ) (z - z0 ) = 2z0 (z - 0z )
f(z)

f(z)

z0

z1

c) Determinacin del punto 1z interseccin


de dicha recta con el eje de abcisa

z1 z

d) Repetir el procedimiento de las Figuras b) y c)


tomando como punto de partida el obtenido
en el paso anterior

Figura 1.4 Ilustracin del mtodo de Newton -Raphson para el clculo de la raz
cuadrada positiva de un nmero x > 0. En trminos matemticos se trata de determinar
el nmero real z > 0 tal que: f(z) = z 2 - x = 0

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

11

INTRODUCCIN AL DISEO Y TEORA DE ALGORITMOS

Es ilustrativo el hecho de que ha habido problemas que no encontraban solucin y


despus se pudo establecer que era imposible resolverlos con los medios empleados para
ello. As, en el problema de la triseccin de un ngulo (dividir un ngulo en tres partes
iguales con regla y comps), la demostracin de imposibilidad era rigurosa debido al
hecho de que se tena una definicin precisa ''divisin de un ngulo con regla y comps".
Algunas reas importantes en la matemticas se han originado en los intentos de
responder a esta pregunta. El punto realmente importante es que todos los conceptos
que se han propuesto han resultado equivalentes, es decir, cualquier problema que es
resoluble de acuerdo con uno de ellos, tambin lo ser respecto a los otros. As pues,
aunque el concepto de algoritmo adecuadamente formalizado puede no ser el nico
medio de resolver problemas, parece ser al menos, en el estado actual de desarrollo el
mejor camino que el ser humano puede entender. Sobre estas cuestiones volveremos de
forma un poco ms detallada posteriormente.

1.5 ALGORITMOS, PROGRAMAS Y LENGUAJES DE PROGRAMACIN


Los procesos de la Figura 1.2 tienen en comn la caracterstica de que despus de un
tiempo todos terminan, es decir, son finitos, as se hacen el postre y el vestido, se
construye el modelo del avin y se toca la sonata.
Sin embargo existen muchos procesos interesantes que nunca se pueden afirmar que
"terminan" tales como:
Estar triste
Actualizar el catlogo de una biblioteca

Incluso procesos que pueden ser realizados por un computador pueden no terminar
nunca, como por ejemplo:
Controlar las seales de trfico
Control de pacientes en una unidad de cuidados intensivos

12

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

ALGORITMOS Y LENGUAJES

La terminacin o no terminacin de un proceso es una de sus caractersticas bsicas.


Muy a menudo una gran fuente de error en el diseo de algoritmos es que bajo ciertas
circunstancias, el proceso descrito puede no acabar mientras que podemos suponer que
s lo hace.
Como ya hemos mencionado un algoritmo se puede ejecutar nicamente si se expresa en
una forma que el procesador que lo va a ejecutar pueda entender. En todos los ejemplos
de la Figura 1.2, los algoritmos estn expresados de forma que son comprensibles a los
seres humanos. Sera muy conveniente e incluso extraordinario que los computadores
tambin pudiesen entender la descripcin de algoritmos descritos en lenguaje natural.
Desgraciadamente y aunque en los ltimos tiempos se han realizado notables progresos
en este campo, los computadores, al menos en el momento actual, no pueden hacer esto
por las siguientes razones:
a) Los lenguajes naturales poseen reglas gramaticales relativamente complejas y
vocabularios muy extensos. Para que un computador fuese capaz de analizar
sentencias expresadas, por ejemplo en castellano, necesitara que se le
suministrase un algoritmo para poder hacerlo. Sin embargo, el proceso de
anlisis es tan complejo que todava no se han ideado algoritmos que puedan
llevarlo a cabo salvo para subconjuntos restringidos del lenguaje o reas
especializadas en temas concretos (por ejemplo en cardiologa, bsqueda de
yacimientos petrolferos, etc.).
b) La interpretacin de una sentencia en lenguaje natural depende no solamente
del anlisis gramatical apropiado, sino tambin del contexto en que la frase
aparece. Consideremos la frase: "Juan hizo el coche rpido". Esta frase al
menos puede tener los significados siguientes:
Juan construy el coche rpidamente
Juan dise el coche para que fuese veloz
Juan transform un coche lento en rpido

Adems muchas palabras tienen diferentes acepciones o significados que solo se pueden
resolver considerando la situacin del contexto en que se producen. Incluso un anlisis
gramatical correcto depende del significado de las palabras que a veces se emplean en un

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

13

INTRODUCCIN AL DISEO Y TEORA DE ALGORITMOS

sentido metafrico que hace que la interpretacin que da el receptor tome en cuenta la
entonacin con que dicha frase se pronuncia.
A pesar de estas dificultades, se han conseguido algunos avances en la comprensin de
lenguajes naturales mediante computador. Como los lenguajes naturales son demasiados
complejos para que un computador pueda entenderlos, los algoritmos que se van a
ejecutar en estas mquinas deben de escribirse de una forma mucho mas simple.
Recordemos que un algoritmo expresado de esta manera se denomina "un programa" y
que un programa est escrito utilizando un lenguaje de programacin. Desde la aparicin
de los computadores, se han propuesto multitud de lenguajes de programacin pensados
con el fin de resolver categoras de problemas y describir de una manera clara y precisa
los programas. Algunos de los lenguajes de programacin ms conocidos son: Fortran,
Pascal, C, C++, Java, Cobol, Algol, etc. La razn de que existan tantos lenguajes de
programacin es triple:
a) La programacin de computadores es una actividad relativamente reciente, y
las ideas acerca de cmo hacer mejor las cosas estn an en continua
evolucin. As cuando surgen nuevas ideas aparecen a su vez nuevos lenguajes
de programacin.
b) Los computadores se utilizan para una gran variedad de objetivos. Esto implica
que los algoritmos utilizados son de una naturaleza diversa y no pueden
expresarse de una forma cmoda en un nico lenguaje de programacin. Esto
ha llevado consigo el desarrollo de lenguajes de programacin de propsito
especial que permitan expresar algoritmos que surjan en campos de aplicacin
especficos. As, por ejemplo, los algoritmos utilizados en gestin comercial
son completamente diferentes de los requeridos en clculos cientficos o
incluso de los utilizados para controlar una planta industrial.
Consecuentemente, se han desarrollado diferentes lenguajes de programacin
para expresar estas diferentes clases de algoritmos (Cobol, Fortran, C).
c) Existe una tendencia natural e inevitable por parte de los especialistas en
Informtica de estar continuamente "descubriendo Amrica". Es la creencia de
que las "propias ideas" son mejores que las de los dems, an en el supuesto de
que no sean originales.

14

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

ALGORITMOS Y LENGUAJES

Por analoga con los lenguajes naturales, cada lenguaje de programacin tiene su propio
vocabulario y sus propias reglas gramaticales que dictan cmo se debe de utilizar este.
En la mayor parte de los casos, el vocabulario consta de ciertos smbolos matemticos y
de unas pocas palabras en ingls (ya que casi todos los lenguajes de programacin de uso
extendido son de procedencia sajona y principalmente norteamericana), y las reglas
gramaticales son bastante simples para permitir que el computador pueda interpretar los
programas. A causa de la diferencia tanto en su vocabulario como en su gramtica, los
lenguajes de programacin naturalmente difieren en las formas de expresin permitida,
por ejemplo uno de los pasos en un algoritmo de contabilidad se podra expresar en
Cobol como:
MULTIPLY precio BY cantidad GIVING coste

y en Pascal como:
coste := precio * cantidad

Ambas formas de expresin significan la misma cosa; es decir una instruccin para
multiplicar un nmero llamado "precio" por un nmero llamado "cantidad" para dar
como resultado un nmero llamado "coste".
Los diseadores de lenguajes de programacin intentan conseguir algunos objetivos,
entre los cuales los ms importantes son los siguientes:
1) El lenguaje debe permitir la expresin fcil y concisa de algoritmos en el rea
de aplicacin para la cual se disea.
2) El lenguaje debe resultar comprensible al computador.
3) Los programas escritos en el lenguaje deberan ser rpidamente asimilables por
el ser humano, de manera que se puedan modificar y corregir fcilmente
cuando sea necesario.
4) El lenguaje debera minimizar el potencial de error en la transformacin de un
algoritmo en un programa.
5) Debera ser fcil de demostrar mediante el examen de un programa, que su
ejecucin verdaderamente llevar a cabo el proceso que se desea.

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

15

INTRODUCCIN AL DISEO Y TEORA DE ALGORITMOS

Resulta obvio que estos objetivos no son todos mtuamente compatibles. Por ejemplo, la
condicin de las expresiones puede ir contra la comprensin de las mismas (por el uso de
acrnimos), mientras que un lenguaje que se disea de forma que sea fcilmente
comprensible por el hombre puede no resultarlo para el computador (cualquier lenguaje
natural es un ejemplo extremo).
En lo que sigue aparecern algoritmos de muy diversas clases que fundamentalmente
queremos que sean comprensibles al lector no tanto como al computador. Por esta razn
no vamos a utilizar un lenguaje de programacin formal para expresar los algoritmos. Sin
embargo con el soporte de cualquier lenguaje de programacin como herramienta (por
ejemplo, Pascal) podr darse cuenta que la transcripcin a un lenguaje es una tarea
mucho ms sencilla cuando se ha comprendido la estructura del algoritmo.

1.6 SINTAXIS Y SEMNTICA


Hemos dicho ya, que un procesador debe ser capaz de interpretar un algoritmo, si
realmente queremos que ejecute el proceso que este describe. Esto es, el procesador
debe ser capaz de:
1) Comprender la forma en que se expresa el algoritmo
2) Realizar las operaciones correspondientes.
En esta seccin, vamos a examinar un poco ms detenidamente la primera de estas dos
acciones.
Comprender la expresin de un algoritmo tiene dos niveles. En primer lugar, el
procesador debe ser capaz de reconocer y dar significado a los smbolos con los cuales
se expresa el algoritmo, sean estos palabras en castellano, abreviaturas, smbolos
matemticos o notas musicales. Para hacer esto el procesador debe tener un
conocimiento del vocabulario y de la gramtica del lenguaje que se utiliza para
expresar el algoritmo. Siguiendo con los ejemplos anteriores, debe saber que
"pantaln" es un nombre en espaol, que "=" es una relacin entre dos nmeros, y que
"#" es un smbolo musical. La aparicin de cualquiera de estos smbolos fuera de un
adecuado contexto gramatical, como en

16

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

ALGORITMOS Y LENGUAJES

pantaln las camisas


a+ = b

es una violacin de respectivas reglas del lenguaje


El conjunto de reglas gramaticales que gobiernan cmo pueden ser utilizado
legtimamente los smbolos en un lenguaje se denomina la sintaxis del lenguaje. As la
sintaxis del castellano gobierna el uso de la palabra "pantaln" y la de las matemticas
el uso del smbolo "=". Un programa que sigue la sintaxis del lenguaje en el que se
expresa se dice que es sintcticamente correcto, esto es, cada smbolo en el programa
se utiliza de forma legtima. Una desviacin de la sintaxis del lenguaje se llama un error
sintctico. La correccin sintctica es normalmente un prerrequisito necesario para
interpretar un programa de computador; surgen excepciones solamente cuando el
procesador es lo suficientemente sofisticado como para inferir qu forma de expresin se
quera expresar cuando encuentra un error sintctico. Los computadores de hoy da no
suelen estar dotados de esta posibilidad, de manera que un programa que es
sintcticamente incorrecto no se ejecutar.
La segunda etapa para comprender la expresin de un algoritmo es asignar significados a
cada paso, en trmino de las operaciones que se desea que realice el procesador.
Por ejemplo el significado de:
coste := precio * cantidad

es que dos nmeros llamados "precio" y "cantidad" tienen que multiplicarse para dar
un tercer nmero llamado "coste".
El significado de formas particulares de expresiones en un lenguaje se llama la semntica
del lenguaje. Los lenguajes de programacin se disean de forma que tanto su sintaxis
como su semntica sean relativamente simples y de que un programa se pueda analizar
sintcticamente sin hacer referencia a la semntica. Esto est en abierta oposicin con los
lenguajes naturales en los que la sintaxis y la semntica son muy complejas y a menudo
estn muy interrelacionadas.
En lenguajes naturales es posible escribir sentencias que son sintcticamente correctas
pero que carecen de significado. Por ejemplo:

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

17

INTRODUCCIN AL DISEO Y TEORA DE ALGORITMOS

El elefante habl con gran conviccin

Anlogamente, un paso en un algoritmo puede ser tambin sintcticamente correcto,


pero semnticamente puede no tener sentido. Por ejemplo:
escriba el nombre del primer mes del ao

y
escriba el nombre del decimotercer mes del ao

Son ambos pasos algortmicos sintcticamente correctos (expresados en castellano), pero


solamente el primero tiene significado.
La deteccin de las inconsistencias semnticas descansa en el conocimiento de los
objetos a los que se refiere. En particular depende del conocimiento de sus atributos y de
las relaciones entre ellos. Se sigue de este razonamiento el hecho de que un procesador
puede detectar inconsistencias semnticas al intentar comprender la expresin de un
algoritmo, solamente si conoce bastante acerca de los objetos a los que el algoritmo se
refiere; en otro caso las inconsistencias se harn aparentes nicamente cuando el
algoritmo se ejecuta.
Consideremos, por ejemplo, un procesador enfrentado con la orden
escribe el nombre del decimotercer mes del ao

Si el procesador sabe que un ao nicamente tiene 12 meses podr detectar la


inconsistencia semntica de la orden antes de intentar llevarla a cabo. Si, por otra parte,
el procesador no tiene este conocimiento, tomar la orden para ejecutarla, posiblemente
buscando el nombre del mes en un calendario. Es solamente durante la ejecucin, cuando
el procesador encuentra que no existe tal mes, que la inconsistencia sale a la luz.
Algunas inconsistencias son mas sutiles ya que son el resultado de la ejecucin de una
parte anterior del algoritmo. Por ejemplo el algoritmo
piense un nmero del 1 al 13
llame a este nmero N
escriba el nombre del mes N-simo del ao

18

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

ALGORITMOS Y LENGUAJES

contiene una inconsistencia potencial que se pone de manifiesto nicamente si la


ejecucin de la primera lnea resulta que es el nmero 13. Cuando una inconsistencia es
el resultado de ejecutar un algoritmo no existe en general mecanismos de deteccin a
priori.
Todo lo dicho hasta ahora se puede resumir diciendo que para poder interpretar cada
paso en un algoritmo un procesador debe ser capaz de:
1) Conocer los smbolos con los que se expresarn los distintos pasos del
algoritmo.
2) Dar significado a los pasos en termino de las operaciones a realizar.
3) Realizar las operaciones apropiadas.
Los errores sintcticos se pueden detectar en la etapa 1, y ciertos errores semnticos en
la etapa 2. Otros errores semnticos no sern detectados hasta la etapa 3.
Cuando el procesador es un computador, las etapas l y 2 se realizan mediante un
traductor, que transforma cada paso en el programa en las operaciones apropiadas que
el procesador va a realizar. El traductor en s mismo es un programa al que nos
referiremos posteriormente en el curso. Se requiere un traductor independiente para cada
lenguaje de programacin utilizado, y al traductor de un lenguaje de programacin
particular se le dota con un conocimiento completo de la sintaxis del lenguaje. El
traductor puede por lo tanto detectar cualquier error sintctico en los programas. Sin
embargo, hemos visto que es poco razonable que el traductor detecte todos (o incluso
muchos) errores semnticos y aquellos que quedan sin detectar se harn aparentes
nicamente cuando el programa se ejecuta.
Adems de los errores sintcticos y semnticos, hay una tercera clase de errores que
merecen nuestra atencin. Estos son los errores lgicos: un programa puede ser
sintcticamente correcto y no contener inconsistencias semnticas, pero simplemente
puede no describir adecuadamente el proceso deseado. Por ejemplo, consideremos el
siguiente algoritmo (expresado en castellano), para calcular la longitud de una
circunferencia
Calcular la longitud de la circunferencia multiplicando el radio por p

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

19

INTRODUCCIN AL DISEO Y TEORA DE ALGORITMOS

Este algoritmo es sintcticamente correcto (es una sentencia en castellano correcta y que
tiene sentido). No obstante, produce un resultado errneo; hay un error lgico en la
omisin del 2 como factor.
Un procesador no puede detectar errores lgicos ya que no tiene idea de qu proceso
desea describir el algoritmo. Los errores lgicos se pueden detectar nicamente
comparando el proceso deseado con el proceso realmente efectuado. Veamos a
continuacin que pasos se deben tomar para en la medida de lo posible evitar los errores
lgicos.

1.7 PROCEDIMIENTO DE REFINAMIENTO DE ALGORITMOS POR PASOS SUCESIVOS


Las dificultades para disear algoritmos se amplifican cuando el procesador es un
computador puesto que, como hemos visto, a estas mquinas les falta la intuicin o el
sentido comn para darse cuenta que el algoritmo pueden no describir de manera precisa
el proceso. Un fallo comn entre los algoritmos es que el proceso descrito es casi el que
se desee pero no exactamente.
Un ejemplo en la esfera humana es el del amigo que nos explica como llegar a su casa. El
algoritmo que nos da, "gira a la derecha en la tienda, sigue derecho hasta
el prximo cruce, a continuacin toma la tercera calle a la izquierda
..." es posible que omita algn pequeo detalle que resulta crucial (por ejemplo, en

cul tienda giro?) y nos enve a una calle equivocada. Al menos en este caso el
procesador es humano, con sentido comn, probablemente suficiente, para reconocer el
error y actuar en consonancia; los computadores, desgraciadamente, no estn equipados
con tales recursos.
Otro fallo comn de los algoritmos es que su ejecucin normalmente realiza el proceso
deseado, pero bajo ciertas circunstancias (no previstas o pasadas por alto por el
diseador) no lo hace. Como ejemplo, consideremos el siguiente algoritmo que describe
cmo calcular el tiempo de vuelo de un avin a partir del libro de horarios de una
compaa area:

mirar el tiempo de salida

20

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

ALGORITMOS Y LENGUAJES

mirar el tiempo de llegada


restar el tiempo de salida del tiempo de llegada

El algoritmo normalmente dar el resultado correcto, pero fallar si los puntos de partida
y de llegada estn en zonas horarias diferentes.
La moraleja de estos ejemplos es que el diseador de un algoritmo debe tomar gran
cuidado de que este describa de forma precisa al proceso deseado y de que han sido
consideradas todas las circunstancias posibles.
Si el proceso es complicado, entonces la tarea del diseador es realmente difcil, y tendr
muy pocas probabilidades de xito, a menos de que adopte un procedimiento
rigurosamente metdico. A continuacin se describe un enfoque de este tipo conocido
como refinamiento por pasos sucesivos (anlisis descendente).
La idea de base es dividir el proceso en una serie de pasos, donde cada uno de los cuales
se puede describir por un algoritmo que es ms pequeo y ms simple que el proceso
entero. Debido a la mayor simplicidad de estos subalgoritmos, el diseador tiene una idea
ms clara de cmo construirlos y puede por lo tanto precisarlos con ms detalle que si
intenta manejar el algoritmo completo como un todo. Los subalgoritmos pueden a su vez
estructurarse en partes ms pequeas que se expresan con mayor detalle y precisin. El
refinamiento del algoritmo continua de esta manera hasta que cada paso esta
suficientemente detallado y preciso como para permitir su ejecucin por el procesador
que lo va a realizar.
Como ejemplo, supongamos un robot que queremos que acte como nuestro sirviente
domstico y al que hay que especificarle un algoritmo que describa como hacer una taza
de caf instantneo. Una versin inicial del algoritmo podra ser:
1) hervir agua
2) poner caf en la taza
3) aadir agua a la taza

Probablemente los pasos en este algoritmo no estn suficientemente detallados como


para permitir que el robot sea capaz de interpretarlos. En consecuencia, cada paso debe
refinarse en una secuencia de acciones mas simples y especificadas con ms detalle que la
original. As el paso

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

21

INTRODUCCIN AL DISEO Y TEORA DE ALGORITMOS

1) hervir agua

se puede refinar de la forma siguiente:


1.1) llenar de agua la cafetera
1.2) conectar la cafetera (suponemos que es elctrica)
1.3) esperar hasta que el agua hierva
1.4) desconectar la cafetera.

anlogamente
2) poner caf en la taza

se puede refinar a:
2.1) abrir el tarro del caf
2.2) extraer una cucharada de caf
2.3) volcar la cucharada en la taza
2.4) cerrar el tarro del caf

y
3) aadir agua a la taza

en
3.1) verter agua de la cafetera en la taza hasta que se llene

Obsrvese que el ltimo refinamiento no aumenta el numero de pasos en el algoritmo,


sino que simplemente expresa un paso existente con mayor detalle.
En esta etapa el algoritmo original ha sido refinado en tres subalgoritmos que se ejecutan
en secuencia. Si el robot puede interpretar todos los pasos en cada uno de los
subalgoritmos entonces el proceso de refinamiento puede parar y el diseo del algoritmo
est completo. Sin embargo, algunos pasos pueden todava ser demasiado complejos
para que el robot pueda interpretarlos y estos deben de refinarse mas an. As el paso.
1.1) llenar de agua la cafetera

22

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

ALGORITMOS Y LENGUAJES

puede necesitar un refinamiento


1.1.1) poner la cafetera debajo del grifo del agua
1.1.2) abrir el grifo
1.1.3) esperar hasta que la cafetera est llena
1.1.4) cerrar el grifo

Finalmente, despus de una serie de refinamientos, cada paso en el algoritmo ser


interpretable por el robot. En este momento el algoritmo est completo. En la Figura 3.
se muestran los sucesivos refinamientos.
{Algoritmo para hacer una taza de caf}
{primero hervir agua}
1.1.1)

poner la cafetera debajo del grifo del agua

1.1.2)

abrir el grifo

1.1.3)

esperar hasta que la cafetera est llena

1.1.4)

cerrar el grifo

1.2)
1.3.1)
1.4)

conectar la cafetera
esperar hasta que suene el avisador de la cafetera
desconectar la cafetera

{poner caf en la taza}


2.1.1)

tomar el tarro del caf de la estantera

2.1.2)

quitar la tapa del tarro

2.2)

extraer una cucharada de caf

2.3)

volcar la cucharada en la taza

2.4.1)

poner la tapa del tarro

2.4.2)

colocar el tarro del caf en la estantera

{aadir agua a la taza}


3.2)

verter agua de la cafetera en la taza hasta que se llene

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

23

INTRODUCCIN AL DISEO Y TEORA DE ALGORITMOS

Algoritmo original
1) Hervir agua

1er Refinamiento

2 Refinamiento (final)

1.1) Llenar de agua la cafetera

1.1.1) Poner l cafetera debajo del


grifo
1.1.2) Abrir el grifo
1.1.3) Esperar hasta que la
cafetera est llena
1.1.4) Cerrar el grifo
1.1.3) Esperar hasta que suene el
avisador de la cafetera

1.2) Conectar la cafetera


1.3) Esperar hasta que el agua
hierva
1.4) Desconectar la cafetera
2) Poner caf en la taza

2.1) Abrir el tarro del caf

2.1.1) Tomar el tarro del caf de


la estantera
2.1.2) Quitar la tapa del tarro

2.2) Extraer una cucharada de


caf
2.3) Volcar la cucharada en la 2.4.1) Poner la tapa del tarro
taza
2.4.2) Colocar el tarro del caf en
2.4) Cerrar el tarro del caf
la estantera

3) Aadir agua a la taza

3.1) Verter agua de la cafetera en


la taza hasta que se llene

Figura 1.5 Refinamiento del algoritmo para hacer una taza de caf

Las lneas que estn encerradas entre llaves son simplemente comentarios para ayudar al
lector: no son pasos ejecutables en el algoritmo, y por lo tanto el robot los ignora. Cada
comentario describe la funcin de la parte del algoritmo que le sigue.
Cuando se utiliza este procedimiento de refinamiento, el diseador de un algoritmo debe
por supuesto conocer dnde parar; esto es, debe saber cundo un paso particular en el
algoritmo est suficientemente claro como para no necesitar ms refinamiento. Esto por
supuesto significa que debe saber que clase de pasos puede interpretar el procesador. En
nuestro ejemplo hemos supuesto que el robot puede interpretar
conectar la cafetera

y por lo tanto no se necesita ningn refinamiento, sin embargo no interpreta

24

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

ALGORITMOS Y LENGUAJES

llenar de agua la cafetera

El conocimiento de las capacidades de un procesador se necesitan no solamente para


finalizar el refinamiento sino tambin para dirigir el camino en que este progresa. Si el
diseador conoce que el procesador puede interpretar una clase particular de paso,
entonces organizar el refinamiento para que resulten acciones de ese tipo.
El razonamiento anterior, demuestra que el refinamiento por pasos sucesivos de un
algoritmo no puede hacerse sin tener conocimiento de las capacidades interpretativas del
procesador que lo va a ejecutar. Cuando el procesador es una persona, la tarea del
diseador se complica por el hecho de que los conocimientos de stas pueden variar
mucho; lo que es fcilmente comprensible para una persona puede ser la cosa ms
obstrusa del mundo para otra.
Afortunadamente las capacidades interpretativas de un computador estn definidas de
forma mucho ms precisa: un computador puede interpretar cualquier cosa que est
adecuadamente expresada en un lenguaje de programacin. As pues, el diseador de un
algoritmo de computador lo refina de forma tal que los pasos se puedan dar en un
lenguaje de programacin apropiado y termina el refinamiento cuando cada accin del
algoritmo est expresada en dicho lenguaje.

1.8 SECUENCIA
El algoritmo de hacer caf es muy directo, ya que consiste en una serie de pasos simples
que se ejecutan uno despus de otro. Decimos que tal algoritmo es una secuencia de
pasos, que verifica:
1) Los pasos se ejecutan uno cada vez.
2) Cada paso se ejecuta exactamente una sola vez; ninguno se repite y ninguno se
omite.
3) El orden en el que se ejecutan los pasos es el mismo en el que se escriben.
4) La terminacin del ltimo paso implica la terminacin del algoritmo.
En lo que sigue convenimos que los pasos sucesivos en una secuencia se escribirn en
lneas sucesivas.

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

25

INTRODUCCIN AL DISEO Y TEORA DE ALGORITMOS

Un algoritmo que es solamente una secuencia de pasos es extremadamente inflexible


puesto que su curso de ejecucin est fijado, y no se puede modificar dinmicamente en
funcin de circunstancias que ocurran. Qu sucede, por ejemplo, en el algoritmo de
hacer caf si el tarro est vaco?. (E1 robot probablemente se quedar confundido sin
saber que hacer o simplemente servir una taza de agua caliente). Siguiendo con el
mismo ejemplo, cmo puede manejar el robot una peticin de algunas tazas de caf?
De estas consideraciones resulta obvio que una combinacin de pasos en secuencia es
una estructura muy primitiva para un algoritmo. Vamos a examinar algunas estructuras
ms flexibles.

1.9 SELECCIN
Acabamos de ver que cuando un algoritmo es solamente una secuencia no hay
posibilidad de modificar su ejecucin. As en el ejemplo del robot no podamos tratar el
caso de que el tarro de caf estuviese vaco; lo que se necesita es la capacidad para
ejecutar un paso tal como:
obtener un nuevo tarro de la alacena
si el tarro actual est vaco y en otro caso omitir este paso.

Esta capacidad se llama seleccin. La seleccin en el caso anterior se consigue


reescribiendo el paso 2.1 de la forma siguiente:
2.1.1)

tomar el tarro del caf de la estantera

2.1.2)

si el tarro est vaco


entonces tomar un nuevo tarro de la alacena

2.1.3)
quitar la tapa del tarro

El paso crucial es el paso 2.1.2 que expresa tanto la accin a seleccionar (obtener un
nuevo tarro de la alacena) y la condicin (el tarro est vaco) bajo la cul se realiza la
seleccin. El paso 2.1.2 es un caso particular de un paso de la forma general:
si condicin

26

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

ALGORITMOS Y LENGUAJES

entonces accin

Si la condicin es cierta entonces se ejecuta la accin; en cualquier otro caso no se


ejecuta. El procesador debe por supuesto ser capaz de interpretar las condiciones en un
algoritmo de la misma forma que hace con las acciones o pasos. Por lo tanto las
condiciones tambin tienen que refinarse hasta que son suficientemente detalladas y
precisas para que puedan ser interpretadas por el procesador.
En el ejemplo anterior, la seleccin se utiliza para determinar si un paso particular se
ejecuta o no. Una extensin de este tipo de seleccin es una forma que determina cul de
dos pasos alternativos se ejecuta. La forma general de tal relacin es:
si condicin
entonces accin1
si no accin2

donde "condicin" determina qu accin se ejecuta. Si es cierta lo ser "accin 1" y


si no "accin 2". Es claro que la primera forma de seleccin:
si ... entonces ...

es simplemente un caso especial de la forma


si ... entonces ... si no ...

ya que:
si condicin
entonces accin

si condicin
entonces accin

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

27

INTRODUCCIN AL DISEO Y TEORA DE ALGORITMOS

si no no hacer nada

son equivalentes. Sin embargo y siempre que sea posible utilizaremos la forma
simplificada.
Como un ejemplo ms del uso de la seleccin presentamos un algoritmo para
aproximarnos a un conjunto de seales de trfico:

si seal est en rojo o en mbar


entonces parar
si no proseguir

Un algoritmo algo mejor, que permite la posibilidad de que las seales estn fuera de
servicio es:
si no hay seal
entonces proseguir con gran cautela
si no si seal est en rojo o en mbar
entonces parar
si no proseguir

Este algoritmo contiene dos ocurrencias de seleccin, la segunda de las cuales est
anidada dentro de la primera y se ejecuta solamente si el semforo est operativo.
Obsrvese como el uso del sangrado hace bastante claro al lector que pasos en el
algoritmo son parte de cada seleccin. Sin sangrado el algoritmo sera mucho ms difcil
de comprender:
si no hay seal
entonces proseguir con gran cautela
si no si seal est en rojo o en mbar

28

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

ALGORITMOS Y LENGUAJES

entonces parar
si no proseguir

Otro ejemplo de seleccin anidada surge en el siguiente algoritmo, que describe cmo
determinar el mayor de tres nmeros dados con un procesador que en cada instante solo
puede comparar dos de ellos. Si los nmeros se llaman x, y y z, una primera versin del
algoritmo es:
si x > y
entonces escoger entre "x" y "z"
si no escoger entre "y" y "z"

La eleccin entre x y z se puede refinar de la forma siguiente:


si x > z
entonces escoger "x"
si no escoger "z"

anlogamente para la eleccin entre y y z. El algoritmo final es por lo tanto:


si x > y
entonces si x > z
entonces escoger "x"
si no escoger "z"
si no si y > z
entonces escoger "y"
si no escoger "z"

Obsrvese como el sangrado hace otra vez claro qu pasos del algoritmo son partes de
cada una de las tres selecciones. (El lector que todava dude del valor del sangrado
podra escribirlo sin ello y se dar cuenta de la diferencia).
La potencia de la seleccin es que permite al procesador seguir diferentes caminos a
travs de un algoritmo de acuerdo con la circunstancias. Las selecciones anidadas

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

29

INTRODUCCIN AL DISEO Y TEORA DE ALGORITMOS

permiten que el nmero de caminos sea arbitrario. Sin seleccin sera imposible escribir
algoritmos de cualquier significacin prctica.

1.10 ITERACIN
Consideremos el proceso de localizar la direccin de una persona, dado su nombre, a
partir de una lista de nombres y direcciones. Un posible algoritmo es:
Considerar el primer nombre en la lista
S1

si este nombre es el dado


entonces extraer la direccin correspondiente

S1

si no considerar el siguiente nombre en la lista


si este nombre es el dado
entonces extraer la direccin correspondiente

S1

si no considerar el siguiente nombre en la lista


si este nombre es el dado
entonces .....

El problema con este algoritmo (aparte de salirnos del papel por el margen derecho) es
que su autor no sabe cundo parar de escribir.
De forma ms precisa no sabemos cuntas veces escribir el conjunto de acciones Sl para
estar seguros de que se encuentra el nombre. Un problema anlogo surge en el algoritmo
siguiente, que describe cmo calcular el primer numero primo que es mayor que un
nmero dado de comienzo (que se supone que es un entero positivo)

30

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

ALGORITMOS Y LENGUAJES

obtener el nmero de comienzo


S2

sumar 1
comprobar el nmero para ver si es primo
si el nmero es primo
entonces escribirlo

S2

si no sumar 1
comprobar el nmero para ver si es primo
si el nmero es primo
entonces escribirlo
si no sumar 1
................

Otra vez no est claro cuntas veces hay que escribir la secuencia S2 para asegurar que
el procesador produce un nmero primo. Por ejemplo, se necesita escribir S2 solamente
una vez si el nmero de comienzo es el 4, y cuatro veces si es 13, pero cuntas veces si
el nmero inicial es 7.394.485?
Estos ejemplos demuestran que la secuencia y la seleccin no son suficientes por s
mismas para expresar algoritmos cuya longitud vara segn las circunstancias. Lo que se
requiere es un medio de repetir ciertas acciones en un algoritmo un nmero arbitrario de
veces. Para hacer esto introduciremos las palabras, repetir y hasta en los algoritmos. De
esta forma el primer algoritmo de esta seccin se puede reescribir como:
considerar el primer nombre en la lista
repetir
si este nombre es el dado
entonces extraer la direccin correspondiente
si no considerar el siguiente nombre en la lista
hasta que se encuentre el nombre dado o se acabe la lista

Anlogamente el otro algoritmo se puede reescribir como:

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

31

INTRODUCCIN AL DISEO Y TEORA DE ALGORITMOS

obtener el numero de comienzo


repetir
sumar 1
comprobar el nmero para ver si es primo
hasta que el nmero es primo
escribir el nmero

Estos ejemplos ilustran la repeticin o iteracin. La forma general de la misma es:


repetir
cuerpo del algoritmo
hasta que el nmero es primo

que significa que la parte del algoritmo entre las palabras repetir y hasta se ejecuta
repetidamente hasta que la condicin especificada despus de hasta es cierta.
En el primero de los algoritmos lo que se repite es la inspeccin de nombres sucesivos en
la lista; la repeticin cesa cuando se localiza el nombre que se busca o se termina la lista.
En el segundo la repeticin se aplica a la comprobacin de nmeros sucesivos para ver si
son primos y se acaba cuando se encuentra el primero.
La ocurrencia de una iteracin se suele llamar un bucle y la parte del algoritmo que se
repite (la parte entre repetir y hasta) se conoce como el cuerpo del bucle. La condicin
que ocurre despus de hasta se denomina la condicin de terminacin.
La potencialidad de la iteracin es que permite que un proceso de duracin
indeterminada sea descrito por un algoritmo de longitud finita. Esta potencia conlleva un
cierto grado de responsabilidad; ya que hay que asegurar que la iteracin
verdaderamente acaba. En el algoritmo del numero primo, la iteracin finaliza porque
siempre existe un numero primo mayor que uno dado. En el otro algoritmo, la iteracin
tambin alcanza un final porque la condicin de terminacin "que se encuentre el nombre
dado o que se acabe la lista'' finalmente se hace cierta. Obsrvese, sin embargo, que la
omisin de la segunda parte de la condicin de terminacin ("o se acabe la lista") es
potencialmente desastrosa, puesto que si el nombre que se busca no est presente el
procesador no sabr qu hacer al final de la lista. Los fallos de especificar correctamente

32

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

ALGORITMOS Y LENGUAJES

una condicin de terminacin es uno de los errores ms comunes en el diseo de


algoritmos.
Por supuesto algunos procesos, se puede desear que no acaben. Un bucle que describe
esta situacin puede ser:
repetir
cuerpo del bucle
siempre

Como un ejemplo adicional de iteracin consideramos otra vez el algoritmo del nmero
primo. El bucle de este algoritmo contiene el paso:
comprobar el nmero para ver si es primo

Es poco probable que el procesador sea capaz de decirle directamente si o no un nmero


particular es primo, de forma que esta accin particular necesita un mayor refinamiento.
Por definicin un nmero primo es aquel que no tiene ms factores que el 1 y el propio
nmero, as pues comprobar un nmero para ver si es primo es lo mismo que verificar si
tiene factores no triviales. Esto se puede efectuar mediante el siguiente algoritmo, en el
que el nmero que se est comprobando se llama "primo potencial".
dividir primo potencial por cada nmero entre 1 y el nmero
si ninguna divisin es exacta
entonces primo potencial es primo
si no primo potencial no es primo

El primer paso claramente involucra una iteracin, en la que el primo potencial se divide
por los sucesivos posibles factores comenzando por 2. La iteracin puede terminar o
cuando una de las divisiones es exacta (en cuyo caso se demuestra que primo potencial
no es primo), o cuando el probable factor es igual al primo potencial (en cuyo caso el
primo potencial realmente es primo). De hecho no hay necesidad de prolongar la
iteracin hasta el punto en el que el posible factor es igual al primo potencial; razonando
un poco se ve que es suficiente ir nicamente hasta la raz cuadrada del primo potencial.
El algoritmo quedara entonces de la forma siguiente

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

33

INTRODUCCIN AL DISEO Y TEORA DE ALGORITMOS

asignar a posible factor el valor 2


repetir
dividir primo potencial por posible factor
sumar 1 a posible factor
hasta que divisin es exacta o posible factor >

v(primo potencial)

si ninguna divisin es exacta


entonces primo potencial es primo
si no primo potencial no es primo

Con esto el algoritmo inicial de este problema se puede escribir como:


obtener el nmero de comienzo
asignar a primo potencial el nmero de comienzo
repetir
sumar a 1 a primo potencial
fijar posible factor a 2
repetir
dividir primo potencial por posible factor
sumar 1 a posible factor
hasta que divisin es exacta o posible factor > v(primo potencial)
si ninguna divisin es exacta
entonces primo potencial es primo
si no primo potencial no es primo
hasta que primo potencial es primo
escribir primo potencial

Este algoritmo contiene dos bucles, uno anidado dentro del otro. El lazo externo se
ejecuta una vez para cada primo potencial, mientras que el lazo interno se ejecuta una
vez para cada posible factor de un primo potencial. ambos bucles son esenciales en el
algoritmo.

34

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

ALGORITMOS Y LENGUAJES

Es tambin digno de mencin notar cunto tiempo de procesamiento se ahorra mediante


el uso de la raz cuadrada en la condicin de terminacin del lazo interno. Esto es un
ejemplo de un fenmeno comn: "un buen razonamiento en la etapa del diseo puede
conducir a ahorros considerables durante su ejecucin".
La notacin repetir ... hasta ... para la iteracin es sencilla de comprender. Sin
embargo hay situaciones importantes en las que los bucles repetir son inapropiados para
expresar la iteracin requerida, por razones que ahora discutiremos. Un bucle con
repetir tiene su condicin de terminacin al final, despus del hasta que sigue al
cuerpo del bucle esto implica que el cuerpo del bucle se ejecuta al menos una vez,
incluso aunque la condicin de terminacin sea inicialmente cierta, ya que a dicha
condicin se accede solamente despus de haber ejecutado el cuerpo del bucle. La
importancia de esta observacin resultar obvia de la consideracin del siguiente
ejemplo.
Supongamos que se desea un algoritmo para determinar el mayor de una lista de
nmeros. Tal algoritmo puede operar examinando la lista, comparando cada nmero con
el mayor encontrado hasta entonces y modificando ste cada vez que se encuentre uno
ms grande. Sin demasiado esfuerzo podemos escribir el siguiente algoritmo:
asignar a mayor el primer nmero en la lista
repetir
considerar el siguiente nmero en la lista
si nmero > mayor
entonces asignar nmero a mayor
hasta que la lista se acaba
escribir mayor

Este algoritmo parece correcto, pero contiene un error serio que resulta aparente si la
lista solamente tiene un elemento. En este caso el procesador no sabr qu hacer al final
de la lista tan pronto como ejecuta el cuerpo del bucle por primera vez. Por supuesto que
la condicin de terminacin "que la lista se acaba" se coloca para evitar que esto
suceda, pero en este caso es ineficaz ya que el procesador no comprueba la condicin de
terminacin hasta que ha ejecutado el cuerpo al menos una vez. Lo que se requiere es
una forma de colocar la condicin de terminacin al comienzo del bucle en lugar de al

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

35

INTRODUCCIN AL DISEO Y TEORA DE ALGORITMOS

final, de manera que el procesador pueda omitirlo completamente si encuentra que la


condicin de terminacin ya es cierta. Una notacin apropiada para e sto es:
asignar a mayor el primer nmero en la lista
mientras no se acabe la lista hacer
considerar el siguiente nmero en la lista
si nmero > mayor
entonces asignar nmero a mayor
escribir mayor

El cuerpo del bucle comprende todo lo que est sangrado debajo de mientras y la
condicin de terminacin aparece antes del cuerpo entre mientras y hacer. La forma
general de este tipo de bucles es:
mientras condicin hacer
cuerpo del bucle

que indica que el cuerpo del bucle se ejecuta repetidamente mientras la "condicin" es
cierta. Como la condicin se comprueba antes de que se ejecute el cuerpo este tipo de
bucle se llama "pre-comprobado" y el tipo de bucle con repetir se denomina "postcomprobado".
Debido a las diferentes posiciones de la condicin de terminacin el cuerpo de un bucle
"post-comprobado" se ejecuta siempre al menos una vez, mientras que el cuerpo de un
bucle "pre-comprobado" puede no ejecutarse ninguna vez.
Para consolidar las ideas acerca de la iteracin que hemos presentado examinemos
brevemente un algoritmo muy antiguo: el algoritmo de Euclides, desarrollado para
determinar el mximo comn divisor (MCD) de dos enteros positivos.
El algoritmo de Euclides se basa en la siguiente relacin:

36

MCD (x,y) = MCD (y, resto de x/y)

si y > 0

MCD (x,y) = x

si y = 0

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

ALGORITMOS Y LENGUAJES

donde x e y son dos enteros no negativos cualesquiera. Para ilustrar el uso de la relacin
anterior consideremos el problema de determinar el MCD de 24 y 9:
MCD (24, 9) = MCD (9, 6) = MCD (6, 3) = MCD (3, 0) =

Generalizando, para determinar el MCD de dos enteros cualesquiera x e y no negativos


todo lo que necesitamos hacer es repetidamente dividir x por y, entonces reemplazar x
por y e y por el resto.
El proceso contina mientras y es distinto de cero; cuando y se anula la respuesta es x.
Un algoritmo apropiado es por lo tanto:
mientras y # 0 hacer
calcular resto de x/y
reemplazar x por y
reemplazar y por el resto
escribir x (el resultado)

Obsrvese que la utilizacin de un bucle "post-comprobado" en este caso sera errnea,


ya que el algoritmo fallara (divisin por cero) si " y" fuera inicialmente cero.
Existe una forma ms de iteracin, particularmente simple, en la que se conoce antes de
que se ejecute el bucle el nmero de iteraciones. Por ejemplo, un algoritmo para calcular
la potencia N-sima de un nmero x (calcular xN) contendr un bucle en el que x se
multiplica por s mismo, es obvio que dicho bucle debera de ejecutarse exactamente N
veces. Tal algoritmo puede por lo tanto expresarse como:
obtener valores de x y N
asignar a producto el valor 1
repetir N veces
multiplicar producto por x
escribir producto

Este algoritmo ejemplifica un tipo de iteracin que tiene la siguiente forma general:
repetir N veces

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

37

INTRODUCCIN AL DISEO Y TEORA DE ALGORITMOS

cuerpo del bucle

donde N es cualquier entero positivo arbitrario, y el cuerpo del bucle se sangra debajo
de repetir. Como el nmero de repeticiones se define de antemano este tipo de
iteracin se conoce como "iteracin definida" en oposicin a la anterior "iteracin
indefinida" en la que el nmero de repeticiones depende de lo que acontece cuando se
ejecuta el bucle.
La duracin de la iteracin definida est determinada a la entrada del bucle y la
terminacin est garantizada. La iteracin indefinida, por otra parte, depende de que
eventualmente se haga cierta la condicin de terminacin.

1.11 REVISIN DE LAS ESTRUCTURAS DE SECUENCIA, SELECCIN E ITERACIN


Las ltimas tres secciones han descrito tres formas bsicas para la construccin de
algoritmos: "secuencia", "seleccin" e "iteracin". Estas tres formas son de hecho
suficientes para construir cualquier algoritmo. De forma ms precisa, si es posible
construir un algoritmo para describir un proceso particular, entonces tal algoritmo
se puede construir utilizando nicamente las estructuras de secuencia, seleccin e
iteracin.
La afirmacin anterior implica que con lo que ya hemos visto es suficiente para
permitirnos construir algoritmos de cualquier naturaleza. Existen, sin embargo, otras
construcciones que suplementan de forma til a estas tres y que describiremos en los
prximos temas.
Vamos ahora a reforzar las ideas adquiridas hasta aqu desarrollando un algoritmo para
clasificar una lista de nombres por orden alfabtico. La necesidad de clasificar
informaciones ocurre en muchas aplicaciones de computadores y debido a esto hay
muchos algoritmos para hacerlo. Vamos a desarrollar uno particularmente simple
llamado mtodo de la burbuja. Aunque lo desarrollaremos en el contexto de clasificar
nombres en orden alfabtico, se puede utilizar tambin para ordenar cualquier otra clase
de informacin
La idea bsica es examinar la lista de nombres, comparando cada uno con su sucesor e
intercambindolos si estn desordenados. Si al final de una pasada todos los nombres

38

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

ALGORITMOS Y LENGUAJES

estn en el orden correcto no se necesita hacer ya nada, si no se realiza otra pasada a lo


largo de la lista y los nombres adyacentes se intercambian siempre que sea necesario. Las
pasadas sobre la lista deben llevarse a cabo mientras exista algn nombre que no est en
su sitio correcto.

Lista Inicial

1 Pasada

2 Pasada

3 Pasada

(4 cambios)

(3 cambios)

(2 cambios)

Juan

Juan

Felipe

Arturo

Luis

Felipe

Arturo

Felipe

Felipe

Arturo

Juan

Jos

Arturo

Luis

Jos

Juan

Samuel

Jos

Luis

Luis

Jos

Mara

Mara

Mara

Mara

Samuel

Samuel

Samuel

Figura 1.6 Accin del algoritmo de burbuja

En la Figura 1.6 se ilustra el proceso que demuestra como nombres particulares


burbujean hacia arriba o hacia abajo buscando su posicin correcta en la li sta
Un algoritmo que esquematiza el proceso de clasificacin es:
mientras lista no est clasificada hacer
realizar una pasada a travs de la lista, cambiando
nombres adyacentes cuando sea necesario

Observar que se utiliza un bucle pre-comprobado con preferencia a uno postcomprobado, ya que el procesador puede tener la suerte de encontrarse que la lista est
ordenada y no hay nada que hacer. (Esta decisin la revisaremos posteriormente cuando
refinemos el algoritmo).
Podemos refinar el algoritmo como sigue:

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

39

INTRODUCCIN AL DISEO Y TEORA DE ALGORITMOS

comenzar en el primer nombre de la lista


repetir
si nombre debe estar detrs de su sucesor alfabticamente
entonces cambiar el nombre y su sucesor
considerar el siguiente nombre en la lista
hasta que se alcanza el final de la lista

Si antes de entrar en el bucle se sabe el nmero de nombres (por ejemplo N), entonces el
bucle indefinido repetir se puede reemplazar por uno definido ya que hay exactamente
N-l pares de nombres adyacentes a examinar. Por lo tanto el algoritmo completo se
puede escribir:
mientras lista no est clasificada hacer
comenzar en el primer nombre de la lista
repetir N-l veces
si nombre debe estar detrs de su sucesor alfabticamente
entonces cambiar el nombre y su sucesor
considerar el siguiente nombre en la lista

Este algoritmo resulta adecuado a condicin de que el procesador sea capaz de decir (en
la 1 lnea) si la lista est clasificada. Si el procesador es incapaz de esto, la condicin de
terminacin en la lnea 1 necesita un mayor refinamiento. Una forma de decirle si la lista
est ya ordenada es recordar si se necesit cambiar algn nombre durante la ltima
pasada. Si no, todos los nombres deben estar ya en su posicin correcta y la lista est por
lo tanto ordenada. Obsrvese que al menos se requiere una pasada sobre la lista para ver
si est ya ordenada; as pues el bucle pre-comprobado de nuestra ltima versin del
algoritmo no resulta necesario y se puede reemplazar por un bucle post-comprobado.
Con estos refinamientos resulta el siguiente algoritmo:
repetir
comenzar en el primer nombre de la lista
repetir N - 1 veces

40

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

ALGORITMOS Y LENGUAJES

si nombre debe estar detrs de su sucesor alfabticamente


entonces cambiar el nombre y su sucesor
recordar que en esta pasada al menos se ha
hecho un cambio
considerar el siguiente nombre en la lista
hasta que no se ha realizado ningn cambio en esta pasada

El cambio del bucle pre-comprobado a uno post-comprobado ha sido una modificacin


de una decisin inicial. Tales modificaciones no son inusuales en el refinamiento de los
algoritmos. Es demasiado optimista quien espera que el refinamiento de cada parte de un
algoritmo puede realizarse enteramente de forma independiente; cuando se completan
ms detalles, algunas decisiones previas pueden necesitar revisin. Por esta razn es a
menudo una buena idea retardar decisiones mientras sea posible, de manera que se tomen
con un conocimiento ms completo y sea menos probable que necesiten una
reconsideracin. Esta actitud cautelosa se puede resumir en la siguiente mxima un tanto
cnica: "Siempre deje para maana lo que es difcil decidir hoy".
El algoritmo que hemos propuesto es particularmente simple pero no es siempre el ms
rpido. Hay otros algoritmos que requieren menos pasos para conseguir el mismo
resultado y por lo tanto son ms rpidos de ejecutar. El algoritmo propuesto es muy
bueno cuando la lista est casi ordenada al principio, de manera que slo se necesitan
unas pocas pasadas por la misma para ordenarla. Su caso ms desfavorable es cuando el
ltimo nombre en la lista es el primero alfabticamente; en este caso se necesitan N - 1
pasadas para mover este nombre a la primera posicin. Se puede demostrar que el
nmero medio de pasadas necesitadas para ordenar la lista es proporcional a N. Como
cada pasada lleva consigo N-l ejecuciones del bucle interno entonces el nmero medio de
acciones o pasos ejecutados por el procesador es proporcional a N 2.
El nmero de pasos necesitados para la ejecucin de un algoritmo y por lo tanto el
tiempo requerido son atributos del propio algoritmo que caen dentro del tema genrico
de "complejidad de algoritmos". Algo diremos de complejidad ms adelante.
Concluimos este tema recordando que la secuencia, seleccin e iteracin son
construcciones adecuadas para cualquier algoritmo. En lo que sigue suplementaremos

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

41

INTRODUCCIN AL DISEO Y TEORA DE ALGORITMOS

estas construcciones con otras dos que, aunque no son estrictamente necesarias, s que
resultan convenientes.

1.12 ACTIVIDADES
1. Describa por medio de un algoritmo la explicacin de una leccin de su eleccin a sus
alumnos.
2. Refine el algoritmo anteri or por pasos sucesivos.
3. Exprese el algoritmo anterior utilizando nicamente las estructuras de secuencia,
seleccin e iteraccin.

42

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

ALGORITMOS Y LENGUAJES

2. CONCEPTOS DE MODULARIDAD, RECURSIN Y PARALELISMO

2.1 MODULARIDAD
Hemos visto en el tema anterior como se pueden desarrollar algoritmos mediante un
proceso de refinamiento por pasos sucesivos. En cada etapa el algoritmo se divide en
componentes ms pequeos que se pueden especificar con mayor detalle. El refinamiento
termina cuando cada componente se expresa de forma tal que el procesador que va a
ejecutarlo puede interpretarlo.
A menudo los componentes que surgen son bastante independientes del algoritmo
principal en el sentido de que se pueden disear sin considerar el contexto en que se
utilizan. Tales componentes se pueden hacer por personas diferentes de las que realizan
el algoritmo principal y pueden posiblemente utilizarse en otros problemas diferentes. Se
pueden considerar as como componentes "enchufables" que una vez diseados es
posible incorporarlos en cualquier algoritmo que los necesite
A modo de ilustracin consideraremos la tarea de disear ciertos algoritmos que van a
ejecutarse por un robot simple. La funcin del robot es dibujar figuras; para lograr su
objetivo est equipado con ruedas que le permiten moverse sobre una hoja de papel, y
tiene una pluma que puede apoyar sobre el papel cuando necesita dibujar una lnea.
El robot puede interpretar y ejecutar el siguiente repertorio de rdenes bsicas:
mover (x)

se mueve x cm. hacia adelante

izquierda (x)

rota x grados hacia la izquierda

derecha (x)

rota x grados hacia la derecha

elevar pluma

levanta la pluma del papel

bajar pluma

apoya la pluma en el papel

Supongamos que se desea que el robot dibuje dos cuadrados concntricos tal como se
muestra en la Figura 2.1. Inicialmente el robot se encuentra en el centro del cuadrado
(punto X) apuntando en la direccin que indica la flecha.

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

43

CONCEPTOS DE MODULARIDAD, RECURSIN Y PARALELISMO

Un esquema del algoritmo es el que se muestra a continuacin:


Paso 1

moverse al punto A

Paso 2

dibujar un cuadrado de 10 cm de lado

Paso 3

moverse al punto B

Paso 4

dibujar un cuadrado de 20 cm de lado

20 cm

10 cm

Figura 2.1 Cuadrados concntricos a dibujar por el robot que


inicialmente est en el punto X

El 2 y 4 paso de este algoritmo consiste en dibujar un cuadrado, que es un proceso


autocontenido e independiente del resto del algoritmo. Esto implica que podemos disear
un algoritmo para dibujar un cuadrado sin decirle al robot para que lo vamos a utilizar.
Una vez se ha diseado este algoritmo, podemos simplemente "colocarlo" en los puntos
apropiados del algoritmo anterior y anlogamente utilizarlo en cualquier otro algoritmo
que necesite dibujar un cuadrado.
Un algoritmo que se puede usar de esta forma en otro algoritmo se llama un mdulo (en
algunos lenguajes de programacin se llama procedimiento, rutina, subrutina o
funcin).
Un mdulo es pues un algoritmo autocontenido que se puede disear
independientemente del contexto en el que se va a utilizar.
Un algoritmo que utiliza un mdulo se dice que llama al mismo. Por ejemplo, el
algoritmo anterior llama dos veces al mdulo de dibujar cuadrado.

44

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

ALGORITMOS Y LENGUAJES

Para que este modulo sea til con generalidad debe ser capaz de dibujar un cuadrado de
cualquier tamao. Cuando se llama al mdulo, debe de indicarse el tamao especfico
que se desea. As, en el algoritmo anterior podramos escribir:
dibujar-cuadrado (10)

dibujar-cuadrado (20)

indicando que se desean dibujar cuadrados de 10 y 20 cm. de lado. El mdulo de


dibujar cuadrado sera:
mdulo dibujar-cuadrado (tamao)
{Dibuja
dibuja

un
en

cuadrado
el

de

sentido

lado

tamao

antihorario

cm.

El

cuadrado

comenzando

desde

se
la

posicin actual del robot. El robot vuelve a su posicin y


orientacin inicial, con la pluma levantada}
bajar pluma
repetir 4 veces
mover (tamao)
izquierda (90)
elevar pluma

"tamao" es un parmetro formal del mdulo: se utiliza en el cuerpo del mdulo para
definir cun grande ser el cuadrado. Cuando se llama al mdulo, el parmetro actual
10 ( 20) proporciona un valor especfico para "tamao", y determina as su dimensin
en esta opcin particular.
La forma genrica que utilizaremos para escribir mdulos es:
mdulo nombre del mdulo (parmetros formales)
{especificacin del proceso que describe el mdulo}
cuerpo del mdulo

El comentario entre corchetes es para ayudar al lector a comprender lo que hace el


mdulo; el cuerpo del mdulo expresa los detalles de cmo lo hace. El cuerpo de un
mdulo se ejecuta, el comentario por supuesto no. Una llamada a un mdulo se escribir:
nombre del mdulo (parmetros actuales)

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

45

CONCEPTOS DE MODULARIDAD, RECURSIN Y PARALELISMO

Esto se interpreta por el procesador como un directivo para ejecutar el cuerpo del
mdulo especificado, con los parmetros formales del mdulo reemplazados por los
parmetros actuales de la llamada. Los parmetros formales de un mdulo representan la
informacin que el mdulo necesita cuando se le llama.
Los parmetros actuales son los elementos de informacin proporcionados por una
llamada particular; estas informaciones toman el lugar de los parmetros formales cuando
se ejecuta el mdulo. Es obvio que debern existir el mismo nmero de parmetros
formales y actuales. Un algoritmo que se construye a partir de una serie de mdulos se
llama modular. Utilizando el mdulo dibujar-cuadrado podemos refinar nuestro
algoritmo de dibujar dos cuadrados concntricos como sigue:
izquierda (45)
mover ( 50 )

{moverse al punto A}

izquierda (135)
dibujar-cuadrado (10)

{dibujar el cuadrado interno}

derecha (135)
mover ( 50 )

{moverse al punto B}

izquierda 135)
dibujar-cuadrado ( 20 ) {dibujar el cuadrado externo}

Obsrvese que todos los pasos en este algoritmo son llamadas a mdulos No hemos
dado los algoritmos para los mdulos mover, izquierda y derecha, porque hemos
supuesto que son suficientemente simples para que el robot sea capaz de interpretar la
correspondiente llamada. Si este no es el caso, entonces cada mdulo necesita definirse
en trminos de instrucciones ms simples que el robot pueda interpretar. As, por
ejemplo, el mdulo mover se podra definir como:
mdulo mover (x)
Mueve el robot x cm hacia adelante dejando inalterada su
orientacin.
La pluma no se eleva ni se baja
Asignar x al nmero de rotaciones requeridas por las ruedas
(longitud de la rueda)

46

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

ALGORITMOS Y LENGUAJES

Llamar a este nmero N


repetir N veces
rotar todas las ruedas al tiempo

Esta definicin de mover supone que el robot puede hacer divisiones y sabe cmo girar
sus ruedas. Es importante darse cuenta que el algoritmo de dibujar dos cuadrados
concntricos no necesita saber cmo trabaja el mdulo dibujar-cuadrado; todo lo que
debe conocer es el efecto de ejecutarlo. En otras palabras, no es necesario que conozca
el cuerpo del mdulo, sino solamente la especificacin en su encabezamiento. De esta
forma se puede realizar una separacin clara de los dos problemas de diseo: el diseo
del algoritmo inicial y el de dibujar-cuadrado. Esto reduce la complejidad del proceso
de diseo y conduce por lo tanto a una realizacin ms rpida y fiable.
La potencia de la utilizacin de mdulos se puede ilustrar ms an considerando un
enfoque diferente del mdulo dibujar-cuadrado. Como un cuadrado es simplemente
un caso especial de un polgono regular podra ser ventajoso disear un mdulo para
dibujar polgonos regulares y a continuacin llamarlo con los parmetros actuales
apropiados siempre que se requiera un cuadrado.
Un mdulo para dibujar polgono es:
mdulo dibujar-polgono (tamao, N)
{Dibuja un polgono de N lados con una longitud de tamao
cm. El primer lado se dibuja de acuerdo con la orientacin
actual

del

robot.

El

robot

vuelve

su

posicin

orientacin inicial con la pluma levantada}


bajar pluma
repetir N veces
mover (tamao)
izquierda (360/N)
elevar pluma

El mdulo dibujar-cuadrado puede ahora reescribirse simplemente como:

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

47

CONCEPTOS DE MODULARIDAD, RECURSIN Y PARALELISMO

mdulo dibujar-cuadrado (tamao)


{dibuja un cuadrado de lado tamao cm .....}
dibujar-polgono (tamao,4)

Anlogamente, un mdulo para dibujar un tringulo se puede escribir como


mdulo dibujar-triangulo (tamao)
{Dibuja un tringulo equiltero de lado tamao cm .....}
dibujar-polgono (tamao,3)

Mdulos para dibujar un pentgono, hexgono, etc. se pueden escribir con igual
facilidad. Obsrvese que la nueva versin de dibujar-cuadrado no requiere ninguna
modificacin del algoritmo propuesto para dibujar dos cuadrados concntricos o
cualquier otro algoritmo que lo llame
Las ventajas de utilizar mdulos se pueden resumir como sigue:
1) Los mdulos se adecuan de forma natural en el procedimiento de refinamiento
por pasos sucesivos, dando un diseo de tipo descendente
2) Un mdulo es un componente autocontenido de cualquier algoritmo mayor que
lo llama. El diseo del mdulo y del algoritmo que lo llama se pueden
considerar separadamente, simplificando as el proceso de diseo. Como el
diseo de algoritmos es normalmente bastante difcil, cualquier simplificacin
es bienvenida. Los beneficios de la simplificacin son un diseo ms rpido y
una menor probabilidad de error.
3) Para incorporar un mdulo en un algoritmo es necesario conocer solamente lo
que el mdulo hace y no como lo hace. Lo que un mdulo hace puede ser
especificado de modo conveniente en un comentario en su encabezamiento.
4) De la misma forma que los mdulos simplifican el diseo de algoritmos,
tambin simplifican la comprensin de los mismos. La facilidad de
comprensin es muy importante si, como a menudo sucede, un algoritmo tiene
que modificarse (particularmente por personas distintas a sus autores).
5) Una vez que se ha diseado un mdulo se puede incorporar en cualquier
algoritmo que lo necesite. Es por lo tanto posible construir una "biblioteca" de

48

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

ALGORITMOS Y LENGUAJES

mdulos tales como un mdulo de ordenacin, un mdulo para resolver


ecuaciones simultneas, etc.

2.2 RECURSIN
Supongamos que deseamos expresar un algoritmo para calcular el producto de los N
primeros nmeros enteros (el factorial de N, N!). Una solucin sera
obtener valor de N
asignar a producto el valor 1
repetir para cada entero de 1 a N
multiplicar producto por entero
escribir producto

Este algoritmo emplea un bucle en el que los sucesivos nmeros enteros de 1 a N se iban
multiplicando. Un enfoque alternativo es utilizar el hecho de que el factorial de N es
simplemente el producto de N por el factorial de N-1.
factorial (N) =

N factorial (N - 1)

Esto es cierto para cualquier N que es mayor que 1. Ms an, factorial (1) = 1. De
aqu un posible algoritmo para calcular el factorial de N se expresa en el mdulo
siguiente:
mdulo factorial (N)
{Calcula el factorial de N para cualquier entero N > 0}
si N = 1
entonces la respuesta es 1
si no multiplicar N por factorial (N - l)

La ltima lnea del mdulo se tiene que ejecutar otra vez pero con los parmetros
actuales con un valor de una unidad menor. La Figura 2.2 ilustra la ejecucin del mdulo
cuando N = 3. Se observa como el clculo de factorial(3) contiene el clculo de
factorial(2) que a su vez necesita factorial(1). Las tres llamadas a la funcin
factorial representan las tres ejecuciones del mdulo que se necesitan.

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

49

CONCEPTOS DE MODULARIDAD, RECURSIN Y PARALELISMO

Vemos que el algoritmo para calcular N! se expresa en trminos de un algoritmo para


calcular (N - l)!. Podemos por lo tanto considerar el algoritmo como si estuviese
expresado en funcin del mismo algoritmo pero con la entrada N sustituida por (N-l). El
trmino utilizado para esta forma de expresin es recursin: un algoritmo recursivo es
uno que se llama a s mismo.
factorial (3):
si 3 = 1
entonces .......
si no multiplicar 3 por factorial (2)
si 2 = 1
entonces .......
si no multiplicar 2 por factorial (1)
si 1 = 1
entonces la respuesta es 1
si no .......
Figura 2.2 Clculo de factorial (3) mediante un algoritmo recursivo

La aparente circularidad de la recursin se evita asegurando que la entrada a las


sucesivas llamadas recursivas se hacen progresivamente "ms simples" en algn sentido.
Debe existir pues un caso lmite, en el que la entrada es tan "simple" que el proceso se
puede llevar a cabo sin llamarlo ms. En el ejemplo del factorial la entrada se reduce en
una unidad con cada llamada, hasta que N = 1 en cuyo caso el proceso se ejecuta. El
caso lmite se puede considerar como una rutina de escape que asegura que la ejecucin
eventualmente termina. Cualquier algoritmo recursivo debe proporcionar tal cdigo de
escape y la entrada simplificarse progresivamente de forma que dicho cdigo finalmente
se ejecuta.
Como otro ejemplo de recursin, consideremos el proceso de invertir el orden de las
letras en una palabra ("roma" se transforma en "amor"). Esto se puede hacer quitando la
primera letra de la palabra, invirtiendo el resto de la palabra y a continuacin aadiendo
la letra que se quit. La base de un algoritmo apropiado es por lo tanto

50

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

ALGORITMOS Y LENGUAJES

Paso 1

quitar la primera letra

Paso 2

invertir el resto de la palabra

Paso 3

aadir la letra quitada

El algoritmo es claramente recursivo, puesto que describe cmo invertir una secuencia
de letras en funcin de como invertir una secuencia de letras ligeramente ms corta. En
cada llamada recursiva se quita una letra de la secuencia a invertir, simplificando as
progresivamente la entrada del algoritmo.
invertir "roma"
si "roma" contiene una letra
entonces .......
si no quitar la letra "r"
invertir "oma"
si "oma" contiene una letra
entonces .......
si no quitar la letra "o"
invertir "ma"
si "ma" contiene una letra
entonces .......
si no quitar la letra "o"
invertir "a"
si "a" contiene una letra
entonces

escribirla

si no .......
aadir "m"
aadir "o"
aadir "r"

am
amo
amor

Figura 2.3 Inversin de la palabra "roma"

En el caso lmite, cuando la secuencia tiene solamente una letra, se proporciona una
rutina de escape de forma que para invertir una nica letra slo se necesita escribirla. El
algoritmo completo para invertir una secuencia de letras es:

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

51

CONCEPTOS DE MODULARIDAD, RECURSIN Y PARALELISMO

mdulo invertir (secuencia)


{invierte la secuencia dada de letras}
si secuencia contiene solamente una letra
entonces escribirla
si no quitar la primera letra de la secuencia
invertir (resto de la secuencia)
aadir la letra quitada

La Figura 2.3 ilustra la ejecucin del mdulo cuando la entrada es la palabra roma. Se
observan las sucesivas llamadas al mdulo, y la salida acumulativa de cada llamada se
muestra a la derecha de la llamada correspondiente.
Los dos algoritmos recursivos que hemos visto se pueden reemplazar por dos algoritmos
iterativos, lo que sugiere que la recursin es simplemente una iteracin expresada de otra
forma. En cierto sentido esta afirmacin es cierta y puede demostrarse que para
cualquier algoritmo que utiliza recursin existe uno equivalente expresado en forma
iterativa. Sin embargo, un algoritmo recursivo para describir un proceso particular es
mucho ms conciso que su contrapartida iterativa y muy a menudo es bastante ms
sencillo de obtener y comprender.
Veamos otros dos ejemplos.
El primero es un algoritmo recursivo que es ms conciso que su equivalente iterativo. Es
una versin recursiva del algoritmo de Euclides para determinar el mximo comn
divisor (MCD) de dos nmeros enteros positivos; la versin iterativa de este algoritmo ya
la hemos explicado. Recordemos que:
MCD (x,y) = MCD (y, resto de x/y)

a menos que y = 0 en cuyo caso MCD(x,y) = x. Esta relacin conduce inmediatamente


al siguiente algoritmo recursivo para calcular MCD(x,y).
mdulo MCD (x,y)
{Calcula el MCD de dos nmeros enteros x e y no negativos}
si y = 0
entonces la respuesta es x
si no calcular MCD (y, resto de x/y)

52

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

ALGORITMOS Y LENGUAJES

Obsrvese que la ejecucin recursiva del algoritmo termina cuando y se reduce a cero, en
cuyo caso el resultado es x. La Figura 2.4 ilustra la ejecucin del algoritmo para
determinar el MCD de 24 y 9.
Calcular MCD(24, 9)
si 9 = 0
entonces .........
si no calcular MCD (9, 6)
si 6 = 0
entonces .........
si no calcular MCD (6, 3)
si 3 = 0
entonces .........
si no calcular MCD (3, 0)
si 0 = 0
entonces

la respuesta es 3

si no .........
Figura 2.4 Clculo del MCD de 24 y 9

El segundo ejemplo es una tarea para la que es ms fcil proponer un algoritmo recursivo
que uno iterativo. El ejemplo se conoce popularmente como las "Torres de Hanoi". De
acuerdo con la leyenda una orden de monjes budistas en Hanoi ha estado ocupada
durante muchos aos en la tarea siguiente: Los monjes tienen tres barras verticales y un
conjunto de 64 discos circulares de diferentes tamaos; cada disco tiene un agujero en el
centro que le permite deslizarse por cualquiera de las barras. Inicialmente los discos
estaban todos colocados en una nica barra, uno encima de otro en orden de mayor a
menor tamao, formando una torre tal como se muestra en la Figura 2.5.
La tarea que los monjes se haban fijado era transferir esta torre original a una de las
otras barras, moviendo solamente un disco cada vez y asegurando que nunca un disco
descansa encima de uno de menor tamao. Como la estrategia de mover los discos no es
obvia, y un falso movimiento poda echar a perder muchos aos de trabajo, lo monjes
necesitaban claramente seguir fijamente un algoritmo que describe como lograr su
objetivo. Tal algoritmo se puede desarrollar como sigue:

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

53

CONCEPTOS DE MODULARIDAD, RECURSIN Y PARALELISMO

64 discos

Figura 2.5 Las torres de Hanoi

Supongamos que la barra que soporta la torre original se llama A, la barra a la que se va
a mover la torre es B y la otra C. Dadas las reglas que gobiernan el movimiento de los
discos, es obvio que la nica forma por la cual el disco del fondo de la torre original se
puede mover para formar la base de la nueva torre es quitar los otros 63 discos.
El nico sitio para poner estos 63 discos es la tercera barra, de manera que un algoritmo
para transferir la torre completa de la barra A la barra B es:
transferir los primeros 63 discos de la barra A a la C
mover el ltimo disco de la barra A a la B
transferir los 63 discos de la barra C a la B

Este algoritmo describe la tarea de transferir 64 discos entre dos barras en funcin de la
tarea de transferir 63 discos entre dos barras. Anlogamente, la tarea de transferir 63
discos entre dos barras se puede describir en trminos de la transferencia de 62 discos
entre dos barras, etc. Generalizando, un algoritmo para transferir N discos desde una
barra llamada "fuente" a una barra llamada "destino" (dada una tercera barra llamada
"espacio de trabajo") es:
transferir N - 1 discos desde "fuente" a "espacio de trabajo"
mover 1 disco desde "fuente" a "destino"
transferir N - 1 desde "espacio de trabajo" a "destino"

Este algoritmo es recursivo, y el nmero de discos que se eliminan en cada llamada


recursiva es de 1. Se debe proporcionar una rutina de escape de las sucesivas llamadas

54

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

ALGORITMOS Y LENGUAJES

cuando solamente hay un nico disco para transferirse entre barras: en este caso todo lo
que hay que hacer es cogerlo y llevarlo a su sitio.
Un algoritmo completo para transferir N discos desde " fuente" a "destino" es:
mdulo mover-torre (N, fuente, destino, espacio de trabajo)
{mueve una torre de N discos desde el disco "fuente" al
disco "destino", utilizando el disco "espacio de trabajo"}
si N =

entonces mover disco de fuente a destino


si no mover-torre(N-1,fuente,espacio de trabajo,destino)
mover 1 disco de fuente a destino
mover-torre (N-1,espacio de trabajo,destino,fuente)

Cunto tiempo le llevara a los monjes realizar su tarea? La ejecucin del algoritmo con
N = 64 resulta en dos ejecuciones con N = 63, cada uno de los cuales necesita dos
ejecuciones con N = 62, etc. De este razonamiento se sigue que la transferencia de la
torre completa requiere 264 - 1 ejecuciones del algoritmo. Como durante cada ejecucin
se mueve un disco, el nmero total de movimientos es 264 - 1. Si los monjes pudieran
mover un disco cada segundo y nunca cometiesen un error, el tiempo tomado para
transferir la torre completa sera de 600.000.000.000 aos!. Ms an se puede probar
que no existe un algoritmo mas rpido que el que acabamos de presentar.
La Figura 2.6 ilustra la ejecucin de este mdulo cuando la torre original contiene
solamente 3 discos y se van a transferir de la barra "A" a la barra " B".
transferir 3 discos de "A" a "B"
si 3 = 1
entonces .........
si no transferir 2 discos de "A" a "C"
si 2 = 1
entonces .........
si no transferir 1 disco de "A" a "B"
si 1 = 1
entonces mover disco de "A" a "B"
si no .........
mover disco de "A" a "C"

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

55

CONCEPTOS DE MODULARIDAD, RECURSIN Y PARALELISMO

transferir 1 disco de "B" a

"C"

si 1 = 1
entonces mover disco de "B" a "C"
si no .........
mover disco de "A" a "B"
transferir 2 discos de "C" a

"B"

si 2 = 1
entonces .........
si no transferir 1 disco de "C" a "A"
si 1 = 1
entonces mover disco de "C" a "A"
si no .........
mover disco de "C" a "B"
transferir 1 disco de "A" a

"B"

si 1 = 1
entonces mover disco de "A" a "B"
si no .........
Figura 2.6 Ejecucin del algoritmo de las torres de Hanoi con 3 discos

En estos momentos el lector puede estar formndose una idea de cul es la estrategia
para formular algoritmos recursivos.
El primer elemento de la estrategia es la determinacin de cmo el proceso a realizar se
puede expresar en trmino de procesos similares que difieren del original solamente por
tener una entrada que es en algn sentido ms simple (por ejemplo, un nmero ms
pequeo o una secuencia ms corta).
El segundo elemento es asegurarse que hay un caso lmite en el cul la entrada es tan
simple que el proceso se puede ejecutar sin necesidad de recurrir a ms llamadas
recursivas. El caso lmite entonces acta como una rutina de escape de la recursin. Esta
estrategia es la que hemos aplicado a todos los ejemplos anteriores.
Vamos a aplicarla para finalizar al desarrollo de un algoritmo recursivo para clasificar
una lista de nombres en orden alfabtico (este mismo algoritmo lo hemos desarrollado en
una versin iterativa en el tema anterior).

56

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

ALGORITMOS Y LENGUAJES

El algoritmo se basa en la observacin de que se puede ordenar una lista separndola en


dos mitades, clasificando cada mitad de forma independiente y luego fusionando ambas
partes. El esquema del algoritmo es por lo tanto:
ordenar la primera mitad de la lista
ordenar la segunda mitad de la lista
fusionar las dos mitades

Es fcil ver que las llamadas recursivas pueden cesar cuando la parte que se va a ordenar
se reduce a un nico nombre en cuyo caso no hay nada que hacer. De aqu que el
algoritmo para una lista de N nombres es:
mdulo ordenar (lista)
{Ordena la lista dada de N nombres en orden alfabtico}
si N > 1
entonces

ordenar (primera mitad de la lista)


ordenar (segunda mitad de la lista)
fusionar las dos mitades

La accin del algoritmo sobre una lista de siete nombres (la misma que utilizamos para
ilustrar el algoritmo de ordenacin iterativo) se muestra en la Figura 2.7.
Juan
Juan
Luis
Felipe
Arturo
Samuel
Jos
Mara

Juan
Luis
Felipe
Arturo
Samuel
Jos
Mara

Juan
Luis
Felipe
Arturo
Samuel
Jos

Luis
Felipe
Arturo
Samuel
Jos

Juan
Luis
Arturo
Felipe
Jos
Samuel

Arturo
Felipe
Juan
Luis
Jos
Mara
Samuel

Arturo
Felipe
Jos
Juan
Luis
Mara
Samuel

Mara
Figura 2.7 Acciones del algoritmo de ordenacin recursiva

La ltima lnea del algoritmo necesita un refinamiento antes de que la pueda ejecutar la
mayora de los procesadores.

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

57

CONCEPTOS DE MODULARIDAD, RECURSIN Y PARALELISMO

2.3 PARALELISMO
Cada uno de los algoritmos que hemos visto hasta aqu se han construido bajo la
hiptesis de que solamente hay disponible un procesador para ejecutarlo. Esta hiptesis
est justificada para la mayora de los computadores actuales. Sin embargo los avances
recientes en la tecnologa han hecho posible fabricar ciertos procesadores muy baratos y
es por lo tanto econmicamente posible asignar algunos procesadores a una nica tarea.
Una de las ventajas potenciales de hacerlo as es que la tarea se puede completar ms
rpidamente que si se utiliza un nico procesador.
Esta mejora en velocidad se puede conseguir solamente si se puede dividir el proceso en
subprocesos que ejecutan cada uno de los procesadores disponibles. Esto implica que el
algoritmo que describe el proceso total se debe particionar en una serie de componentes,
cada uno de los cuales define el subproceso realizado por un procesador individual. Los
componentes del algoritmo se ejecutan simultneamente por sus respectivos
procesadores, de forma que el tiempo tomado para ejecutar el algoritmo no es mayor
que el necesitado para completar su componente ms lenta. Esta forma de ejecucin se
llama paralelismo o concurrencia y un algoritmo cuyos componentes se pueden
ejecutar de esta forma se conoce como un algoritmo paralelo (en oposicin a los
algoritmos secuenciales cuyos pasos se ejecutan uno cada vez)
Como un ejemplo simple de un algoritmo paralelo consideraremos el proceso de restar
una lista de los precios de compras para varios artculos de una lista con los precios de
ventas de los mismos. El resultado ser una lista de los beneficios (o prdidas) de cada
artculo. Si hay N artculos, un algoritmo secuencial simple es:
mdulo beneficio-secuencial
{Calcula una lista de beneficios a partir de las listas de
precios de compra y venta}
comenzar con el primer elemento de cada lista
repetir N veces
restar precio de compra del precio de venta
colocar la respuesta en la lista de beneficios
considerar el prximo artculo en cada lista

La mayor parte del tiempo gastado en ejecutar este algoritmo se pasa en el cuerpo del
bucle. Como el cuerpo se ejecuta N veces, el tiempo necesitado para ejecutar el algoritmo

58

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

ALGORITMOS Y LENGUAJES

completo es proporcional a N. Supongamos sin embargo que hay disponibles N


procesadores. En este caso se puede asignar un procesador para calcular el beneficio de
cada artculo en la lista. Como stas son independientes los procesadores pueden
efectuar sus clculos en paralelo. Si los procesadores se numeran de 1 a N, un algoritmo
apropiado para el procesador i-simo es:
mdulo beneficio-paralelo (i)
{Algoritmo para que el procesador n i calcule el beneficio i-simo}
para el artculo i-simo restar el precio de compra del precio de venta
colocar la respuesta en la posicin i-sima de la lista de beneficios

El tiempo gastado para ejecutar este algoritmo no depende de la longitud de la lista.


Como todos los procesadores ejecutan el algoritmo en paralelo sus tiempos de ejecucin
se solapan y por tanto el tiempo requerido para producir la lista de beneficios completa
es tambin independiente de N. As, mientras el tiempo de ejecucin del algoritmo
secuencial aumenta en proporcin a la longitud de la lista, el tiempo de ejecucin del
algoritmo paralelo es constante. El algoritmo paralelo es N veces ms veloz que el
algoritmo secuencial pero a expensas de aumentar los procesadores por un factor
tambin de N.
Otro ejemplo ligeramente ms complicado de paralelismo, es el proceso de sumar una
fila de N nmeros. Un algoritmo secuencial, diseado para un nico procesador que
puede realizar cada vez una suma es:
mdulo suma-secuencial (N)
{Suma una fila de N nmeros}
asignar a suma el valor 0
comenzar en el primer nmero de la fila
repetir N veces
sumar el nmero a suma
considerar el siguiente nmero en la fila

Tambin en este caso la mayor parte del tiempo para ejecutar este algoritmo se pasa
dentro del bucle. As pues, el tiempo de ejecucin es proporcional a N.
La base de un algoritmo paralelo se puede ver en la Figura 2.8 que demuestra como se
pueden sumar por parejas los nmeros en la fila. La primera etapa en el algoritmo es

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

59

CONCEPTOS DE MODULARIDAD, RECURSIN Y PARALELISMO

agrupar los nmeros por parejas y calcular sus sumas. Las sumas se pueden hacer en
paralelo, a condicin de que el numero de procesadores disponibles es al menos de N/2
(de forma ms precisa, la parte entera de N/2).
3

11

13

15

28
Figura 2.8 Suma de nmeros por parejas

Las sumas resultantes pueden otra vez sumarse por parejas, en esta etapa solamente se
necesitan N/4 procesadores. La suma en paralelo de parejas de nmeros contina hasta
que resulta una suma simple. Como el nmero de parejas a sumar se reduce a la mitad en
cada etapa, el nmero de etapas necesarias es log2N. El nmero de procesadores
necesitados en cada etapa es tambin la mitad de la etapa anterior, por lo que el nmero
mximo de N/2 lo ser en la primera etapa.
Si los procesadores se numeran de 1 a N/2 y los nmeros a sumar en la fila se
representan por num[l], num[2], ......, num[N], el algoritmo ejecutado por el procesador
i-simo es:
mdulo suma-paralela(i)
{Algoritmo de suma ejecutada por el procesador i-simo}
repetir log2 N veces
asignar a num[i] el valor num[2i - 1] + num[2i]

La ejecucin paralela de este algoritmo por todos los procesadores se ilustra en la Figura
2.9. Obsrvese como las sumas en etapas sucesiva (se muestran con una lnea por
debajo) se acumulan a la izquierda de la fila, el resto queda sin modificar.

60

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

ALGORITMOS Y LENGUAJES

fila original

fila despus de la 1 etapa

11

fila despus de la 2 etapa

15

13

fila despus de la 3 etapa

28

13

Figura 2.9 Ejecucin del algoritmo de suma paralela

Como la salida de cada etapa forma la entrada a la siguiente, ninguna etapa puede
comenzar hasta que ha finalizado la etapa previa. Esto implica que todos los
procesadores deben operar con la misma velocidad o al menos esperar antes de
comenzar ejecuciones sucesivas de los cuerpos de sus bucles repetir. Es decir, los
procesadores deben sincronizarse entre s.
Como todos los procesadores operan sncronamente el tiempo empleado para sumar la
fila completa de nmeros es el mismo que el tomado por cada procesador para ejecutar
el algoritmo suma-paralela. Este tiempo es proporcional a log2N, por lo que el algoritmo
paralelo es ms rpido que el secuencial por un factor de N/log2N. La implicacin
prctica es que se pueden obtener aumentos de velocidad de 10 a 100 para valores de N
entre 100 y 1000.
Como ejemplo final de paralelismo desarrollaremos un algoritmo de ordenacin en
paralelo que hace uso del algoritmo anterior de suma-paralela. Supongamos que
deseamos ordenar una lista de N nombres en orden alfabtico (problema que ya hemos
venido tratando). De lo que ya sabemos la esencia de la ordenacin es la comparacin (y
posible intercambio) de parejas de nombres. En ese algoritmo, que fue diseado para un
nico procesador, las comparaciones eran necesariamente realizadas una cada vez.
Dado un nmero suficiente de procesadores, una manera obvia de acelerar el proceso de
ordenacin es efectuar todas las comparaciones al tiempo, esto es, comparar
simultneamente cada nombre de la lista con los restantes, determinando as para cada
uno cuntos le preceden alfabticamente. Como hay N nombres a comparar con todos los
otros, el nmero de procesadores que se necesitan es N2.
Durante la primera fase del proceso de ordenacin la tarea de cada procesador es
comparar dos nombres, registrando el resultando en uno de los cuadrados de una rejilla

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

61

CONCEPTOS DE MODULARIDAD, RECURSIN Y PARALELISMO

de N * N . El procesador que compara el nombre i -simo en la lista con el j-simo coloca


su resultado en la posicin (i, j) de la rejilla. Si el nombre i-simo precede
alfabticamente al j-simo, el procesador coloca un 0 en dicha posicin; en otro caso
pone un 1. As el algoritmo ejecutado por el procesador durante esta fase es:
mdulo comparacin-paralela(i, j)
{cada procesador ejecuta esto con diferentes valores de i y j}
si nombre [i] precede alfabticamente a nombre[j]
entonces poner un 0 en la posicin (i, j) de la matriz
si no poner 1 en la posicin (i, j) de la matriz

Todos los procesadores realizan este algoritmo en paralelo, cada uno utilizando
diferentes valores de i y j. La matriz resultante para la lista:
Juan, Luis, Samuel, Felipe, Arturo, Jos, Mara

se muestra en la Figura 2.10. El tiempo empleado para ejecutar este algoritmo es


independiente de N:

Juan

Luis

Felipe

Arturo

Samuel

Jos

Mara

Posicin

Juan

Luis

Samuel

Felipe

Arturo

Jos

Mara

Figura 2.10 Ejecucin del algoritmo de ordenacin paralela

Al final de esta fase el nmero de 1's en la fila i-sima de la matriz indica cuantos
nombres (incluyendo l mismo) preceden alfabticamente al nombre i-simo en la lista.
Esto a su vez indica dnde debera estar en la lista ya ordenada el nombre i-simo. Por

62

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

ALGORITMOS Y LENGUAJES

ejemplo, la matriz de la Figura 2.10 tiene cinco 1's en la segunda fila, indicando que
cinco nombres (incluyendo a l mismo) preceden al nombre correspondiente en la lista
original (Luis), y por lo tanto que Luis debera ocupar el quinto lugar en la lista
ordenada. Estamos suponiendo por simplicidad que todos los nombres son diferentes; si
este no es el caso el algoritmo necesita una ligera modificacin para tratar la posibilidad
de nombres idnticos.
Por lo tanto la segunda fase del algoritmo consiste en sumar el nmero de 1's en cada fila
de la matriz, determinando as la posicin correcta de cada nombre en la lista. La suma
de cada fila se puede realizar por medio del algoritmo paralelo ya desarrollado, cada fila
requiere N/2 procesadores y un tiempo de clculo proporcional a log2N.
Las sumas resultantes de la segunda fase del algoritmo se utilizan para determinar la
posicin de cada nombre en la lista ordenada. Si la suma de la fila i-sima es k, entonces
el nombre i-simo en la lista original deber ocupar la posicin k-sima en la lista
ordenada. La fase final del algoritmo es por lo tanto simplemente mover cada nombre a
su posicin correcta en la lista ordenada. Utilizando N procesadores todos los nombres se
pueden mover en paralelo, de forma que el tiempo tomado para ejecutar esta fase no es
mayor que el necesitado para mover un nombre simple, y es independiente de N.
La nica fase del algoritmo cuyo tiempo de ejecucin depende de N es la segunda, con
una duracin proporcional a log2N , de donde el tiempo para el algoritmo completo
podemos decir tambin que es proporcional a log2N. Este valor se puede comparar con
el algoritmo secuencial dado anteriormente; por ejemplo, los tiempos de ejecucin de los
algoritmos de ordenacin de las secciones 1.7 (del Tema 1) y 2.1 son proporcionales a
N2 y Nlog2N respectivamente. La diferencia dramtica en velocidad entre los algoritmos
secuencial y paralelo se puede ver en la Figura 2.11 que tabula los valores de log2N,
Nlog2N y N2 para distintos valores de N.
Por supuesto, el incremento en velocidad no es sin coste. El algoritmo de ordenacin
secuencial utiliza solamente un nico procesador, mientras el algoritmo paralelo que
acabamos de describir requiere N2/2 procesadores. Es posible lograr el mismo aumento
de velocidad utilizando solamente Nlog2N procesadores. Sin embargo en la actualidad no
se conoce ninguna forma de hacerlo con menos procesadores. As pues el mejor
algoritmo paralelo conocido da un incremento de velocidad de N veces al costo de un
aumento de Nlog2N en el nmero de procesadores.

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

63

CONCEPTOS DE MODULARIDAD, RECURSIN Y PARALELISMO

log2N

Nlog2N

N2

10

0,000003 seg.

0,00003 seg.

0,0001 seg.

100

0,000007 seg.

0,0007 seg.

0,01 seg.

1000

0,00001 seg.

0,01 seg.

1 seg.

10000

0,000013 seg.

0,13 seg.

1,7 min.

100000

0,000017 seg.

1,7 seg.

2,8 horas

Figura 2.11 Comparacin del tiempo de ejecucin de diferentes algoritmos

2.4 ACTIVIDADES
1. Describa un algoritmo de su eleccin que utilice el concepto de modularidad.
2. Describa un algoritmo de su eleccin que utilice el concepto de recursin.
3. Describa un algoritmo de su eleccin que utilice el concepto de paralelismo.

64

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

ALGORITMOS Y LENGUAJES

3. INTRODUCCIN A LAS ESTRUCTURAS DE DATOS

3.1 INTRODUCCIN
Los dos temas anteriores se han concentrado sobre las estructuras de control; esto es,
sobre las construcciones que se pueden utilizar para controlar el orden y circunstancias
en las cuales se ejecutan los pasos individuales de un algoritmo. La eleccin de las
estructuras de control apropiadas (secuencia, seleccin o iteracin) es una parte esencial
del desarrollo de un algoritmo, pero no se puede realizar este sin considerar las
informaciones o datos que el algoritmo manipula.
En general, los datos manipulados por un algoritmo no son simplemente una coleccin
arbitraria de elementos no relacionados, sino que consisten en grupos de informacin que
estn de alguna forma relacionados unos con otros. Como ejemplo, consideremos un
algoritmo que se utiliza para el mantenimiento de la informacin personal de los
empleados de un compaa. Los datos manipulados por el algoritmo consisten en
nombres, direcciones, edades, puestos de trabajos etc.
Estos elementos de datos no son meramente una masa amorfa de informacin, sino que
poseen relaciones lgicas entre si. Una relacin obvia entre un nombre particular y su
direccin, edad y puesto de trabajo es que todos estos elementos describen a la misma
persona.

Personal administrativo

Joaqun Snchez

27

Lpez de Hoyos 34
Gerente
42

Mara Prez

Figura 3.1 Ejemplo de datos no estructurados

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

65

INTRODUCCIN A LAS ESTRUCTURAS DE DATOS

Joaqun
Snchez

Lpez de
Hoyos 34

42

Mara
Prez

Princesa 17

27

Gerente

Personal
administrativo

Benjamn Embajadores 23
Gonzlez

Tornero

Figura 3.2 Ejemplo de datos estructurados en registros

Los datos pueden por lo tanto verse no como una jungla de elementos sin relacionar (tal
como se muestra en la Figura 3.1), sino como una coleccin de registros, cada uno de lo
cuales contiene toda la informacin respecto a un empleado particular (ver Figura 3.2).
Jos
Lpez

Juan
Director General
Lesmes Comercializacin

Presidente

David Director General


Gmez Produccin

Figura 3.3 Relacin lgica entre registros que reflejan la estructura de una compaa

Estos registros pueden as mismo tener conexiones lgicas entre ellos reflejando las
relaciones que existen entre las personas que describen. Por ejemplo, determinados
empleados (y por lo tanto los registros que los describen) pueden estar relacionados por
la condicin de estar trabajando en la mima seccin de la compaa o un empleado puedo
estar relacionado a algn otro en virtud de ser su supervisor inmediato (ver Figura 3.3).
Los datos que se organizan para reflejar las relaciones lgicas entre sus elementos se

66

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

ALGORITMOS Y LENGUAJES

dicen que estn estructurados; los datos elementales y sus relaciones todos
conjuntamente forman una estructura de datos.

3.2 ESTRUCTURAS DE DATOS MS USUALES


De hecho hemos estado utilizando estructuras de datos en los dos temas anteriores sin
mencionarlas explcitamente. Por ejemplo los algoritmos de ordenacin que
desarrollamos todos operaban sobre una lista de nombres. Tal lista es una estructura de
datos simple en la cual los nombres individuales estn relacionados por su orden fsico.
Un nombre viene o antes o despus de otro nombre en la lista. Los algoritmos de
ordenacin transforman una lista en otra modificando el orden fsico de los nombres para
hacerlos coincidir con su orden alfabtico.
Una lista es un ejemplo de un tipo particularmente conocido de una estructura de datos
conocida como una secuencia. Una secuencia es un conjunto de elementos que se
ordenan de tal forma que cada elemento excepto uno (llamado el ltimo) tiene un
sucesor, cada elemento excepto uno (llamado el primero) tiene un predecesor. Ejemplos
de secuencias son:
l) Una palabra, que es una secuencia de letras.
2) Un texto en castellano, que es una secuencia de palabras separadas por espacios
y otros signos de puntuacin.
3) Un nmero, que se representa en forma escrita como una secuencia de dgitos.
4) Un tren, que es una secuencia de vagones (precedidos por una mquina).
5) Un listn telefnico, que es una secuencia de registros, cada uno de los cuales
contiene un nombre, una direccin y un nmero de telfono.
Una secuencia es una estructura particularmente til cuando se desea procesar sus
elementos uno despus de otro. Un algoritmo que describe tal procesamiento tiene la
forma general siguiente:

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

67

INTRODUCCIN A LAS ESTRUCTURAS DE DATOS

Comenzar en el principio de la secuencia


mientras no se alcanza el final de la secuencia hacer
procesar el siguiente elemento

Si se sabe que la secuencia contiene al menos un elemento el bucle mientras se puede


sustituir por un bucle repetir. Si se conoce el nmero de elementos la iteracin
indefinida se puede reemplazar por una iteracin definida. Ejemplos de algoritmos
actuando sobre secuencias de acuerdo con este esquema general se dieron en los dos
temas anteriores.
Ciertas clases de secuencias ocurren tan frecuentemente que se le han dado nombres
especiales. Mencionamos aqu tres de ellas.
1. Un array es una secuencia de longitud fija en la cual cada elemento se
identifica por su posicin. As nos referimos al primer elemento, al segundo
elemento, al i-simo elemento, etc. Un ejemplo es una fila de nmeros:
num(l), num(2), ...., num(N) que sumbamos en el algoritmo que describamos

en el tema anterior. Cada nmero se identifica por su posicin (1), (2), .... ,
(N) en la fila, de una forma anloga con el uso de subndices en matemticas.
2. Una cola es una secuencia de longitud variable en la que los elementos se
aaden siempre en un extremo y se extraen por el otro extremo. Se sigue pues
que el orden en que los elementos se quitan es el mismo que en el que se
aaden. Una cola es una estructura de datos particularmente til para elementos
que van a ser manipulados sobre la base de que el primero que llega es el
primero en ser atendido.
3. Una pila es una secuencia de longitud variable en la cual los elementos se
aaden y se extraen por el mismo extremo. As el orden en el que los
elementos se eliminan es el inverso de como llegan. (Una pila de platos es un
ejemplo sencillo que refleja este tipo de estructura; el ltimo plato colocado en
la pila es el primero que tiene que ser extrado de ella).
Otro tipo de estructura de datos es el rbol, un ejemplo del cual se muestra en la Figura
3.4 (los rboles en informtica crecen hacia abajo!).

68

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

ALGORITMOS Y LENGUAJES

Oracin
Sintagma
Nominal

Sintagma
Predicativo
Sintagma
Nominal

Determinante Nombre Verbo

Sintagma
Preposicional
Sintagma
Nominal

Determinante Nombre Preposicin

Determinante Nombre

Mi

hermano

el

lee

peridico

en

la

cama

Figura 3.4 Estructura arborescente de una oracin en castellano

Los datos en un rbol se representan por sus nodos, o puntos de ramificacin, y se


disponen jerrquicamente. Las ramas del rbol representan relaciones lgicas entre un
elemento de datos en un nivel de la jerarqua y algunos elementos en el siguiente nivel
inferior. El nodo en el nivel ms alto de la jerarqua se le llama raz del rbol. Los nodos
en las extremidades ms inferiores se denominan hojas. Un rbol es claramente una
estructura de datos apropiada para expresar cualquier relacin jerrquica, tal como la
estructura de gestin de la compaa de la Figura 3.3, la estructura de una oracin en
castellano (ver Figura 3.4), o los sucesivos refinamientos de mdulos (ver Figura 3.5).
dibuja-cuadrado

dibuja-polgono

mover

calcular nmero de
vueltas necesitadas

girar a izquierda

rotar todas calcular nmero de


las ruedas vueltas necesitadas

rotar las ruedas


a la izquierda

Figura 3.5 rbol de los sucesivos refinamientos del mdulo dibuja -cuadrado del tema 2

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

69

INTRODUCCIN A LAS ESTRUCTURAS DE DATOS

Obsrvese que cada nodo en un rbol es as mismo la raz de un rbol ms pequeo.


Incluso las hojas se pueden considerar como las races de rboles que son tan pequeos
que no tienen ramas. En general, los rboles ms pequeos se llaman subrboles del
rbol completo. As pues un rbol es esencialmente una estructura de datos recursiva
(recuerde el apartado 2.2 sobre recursin del tema anterior), ya que cualquier rbol se
puede definir en trminos de otros rboles como sigue:
Un rbol es:
1) Un conjunto vaco, o
2) Un nodo ms un conjunto (posiblemente vaco de ramas, cada una
conduciendo a un rbol).
Como veremos a continuacin, la estructura recursiva de los rboles es particularmente
propicia para la descripcin de algoritmos recursivos.
En general, los algoritmos describen procesos que transforman una estructura de datos
(la entrada) en otra estructura de datos (la salida). Por ejemplo, los algoritmos de
ordenacin mencionados anteriormente describen como transformar una secuencia en
otra mientras que un algoritmo para analizar oraciones en castellano describe como
transformar una secuencia de palabras en un rbol tal como se muestra en la Figura 3.4.
Algunas veces como en el caso del algoritmo de ordenacin por el mtodo de la burbuja,
la transformacin se puede efectuar simplemente manipulando los elementos dentro del
marco de la estructura de datos original.
En muchos casos, se puede necesitar no obstante, algunas estructuras de datos
intermedias tal como se ilustra en la Figura 3.6. El desarrollo del algoritmo en estos
casos est ntimamente ligado a la eleccin de una estructura de datos apropiada. La
rejilla en el algoritmo de ordenacin paralela del apartado 2.3 del tema anterior es un
ejemplo de una estructura de datos intermedia entre una secuencia de entrada de
nombres no ordenados y una secuencia de salida de nombres ordenados.

70

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

ALGORITMOS Y LENGUAJES

Algoritmo
Estructura
de datos
de entrada

Estructura
de datos
intermedia

Estructura
de datos
de salida

Figura 3.6 Utilizacin de una estructura de datos intermedia en un algoritmo

3.3 REPRESENTACIN INTERNA DE LAS ESTRUCTURAS DE DATOS


3.3.1 Asignacin secuencial
Las pilas y las colas se pueden representar en memoria como un bloque contiguo. Por
conveniencia, supondremos que cada nodo ocupa una palabra. Suponemos que hemos
reservado un bloque de memoria llamado LISTA que tiene L palabras.
Para la representacin de una pila necesitamos una palabra adicional el puntero de pila
(PP) para decirnos donde est en cada momento la cumbre de la pila. Inicializamos PP a
0. Esto significa que la pila est inicialmente vaca o nula.
Para aadir un elemento a la pila, primero sumamos 1 a PP y a continuacin
almacenamos el elemento en LISTA (PP). Inversamente, para eliminar un elemento,
recuperamos LISTA (PP) y a continuacin restamos 1 de PP. Si intentamos hacer PP
mayor que L, se produce un error puesto que en LISTA no hay ms espacio para
almacenar ningn elemento. Anlogamente, una peticin de eliminar o extraer un
elemento de la pila cuando PP es 0 (cuando la pila est vaca) produce tambin un error.
La representacin de las colas es ligeramente ms complicada. Necesitamos dos
punteros, uno para cada extremo de la LISTA. Llamemos a estos D y A que representan
delante y detrs. (Aadimos elementos por detrs y los extraemos por delante, de la
misma forma que en una lnea de espera). Inicializamos ambos D y A a 1. Para aadir un
elemento a la cola, primero incrementamos A y luego almacenamos el elemento en LISTA
(A). Para extraer un elemento, incrementamos D y a continuacin extraemos LISTA (D).
Como LISTA es finita, no podemos permitir que D y A se incrementen indefinidamente.
Obsrvese que cuando se incrementa D, todos los elementos de la lista LISTA (k) estn

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

71

INTRODUCCIN A LAS ESTRUCTURAS DE DATOS

disponibles y se pueden volver a usar. Por lo tanto, cuando A ( D) se hacen tan grandes
como L (apuntando al final de la lista) en el siguiente incremento lo volvemos a poner a
1. De esta forma D persigue a A alrededor de la lista. Surgen condiciones de error si D
alcanza e intenta pasar a A (intento de extraer elementos no almacenados) o si A se hace
tan grande que alcanza a D (intento de poner ms de L - 1 elementos en la cola. Por
qu solamente L - 1?).
3.3.2 Listas enlazadas
La mayor dificultad en utilizar bloques contiguos de memoria para el almacenamiento de
listas es que las adiciones y las supresiones en la mitad de la misma son difciles y
debemos poner una acotacin fija al tamao de la lista. Si tenemos solamente una lista,
podemos siempre asignar toda la memoria disponible a ella, pero esto es malgastarla ya
que (en cualquier momento) podemos estar utilizando solamente una pequea parte de
esa memoria. Si tenemos algunas listas, debemos asignar algn lmite a cada una de ellas.
Sin embargo, hay otra forma de parcelar la memoria que permite mucha mayor
flexibilidad. En este esquema, cada nodo dentro de una lista contiene, adems del
elemento almacenado, la direccin (o subndice) del prximo elemento en la lista. Cada
nodo se puede almacenar en una posicin arbitraria de la memoria. No obstante si
almacenamos en un registro donde est el primer nodo, todos los otros se pueden
encontrar siguiendo el camino a lo largo de estos punteros. El primer nodo nos dice
donde est el segundo nodo, el segundo donde est el tercero, etc. (comparar las Figuras
3.7, 3.8 y 3.9). En el esquema secuencial mantenamos ndices independientes de la lista
para decirnos donde estbamos buscando en la lista. Para una lista enlazada,
almacenamos punteros a posiciones de memoria que contienen las direcciones de los
nodos bajo consideracin.

72

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

ALGORITMOS Y LENGUAJES

Direccin

Nombre

1043

LISTA[1]

+253

1044

LISTA[2]

-16

1045

LISTA[3]

1046

LISTA[4]

+37

1047

LISTA[5]

+172

1048

LISTA[6]

-3

Figura 3.7 Lista almacenada de forma secuencial en memoria

En la Figura 3.8 el smbolo representa el puntero nulo y significa que se est al final de
la lista.
Direccin

Dato

Puntero

2013

-3

2014

+37

3108

2378

+253

3107

Puntero
de lista

Direccin

Dato

Puntero

2404

2014

3107

-16

2404

3108

+172

2013

2378

Figura 3.8 Lista almacenada de forma arbitraria en memoria con enlace entre los elementos

Ciertas operaciones sobre las listas se realizan mucho ms fcilmente en el esquema


enlazado. stas incluyen la adicin de un nodo en cualquier parte de la lista, la supresin
de un nodo y la concatenacin de algunas listas. Para suprimir el nodo k, por ejemplo,
simplemente hacemos que el nodo k - 1 apunte al nodo k + 1 (ver Figura 3.10).
Obsrvese que el nodo en la direccin 2.404 est fuera de la lista simplemente por que no
se le apunta ni desde el puntero de lista ni desde ningn otro nodo de la lista.

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

73

INTRODUCCIN A LAS ESTRUCTURAS DE DATOS

2378

Direccin

2378

+253

3107

3107

-16

2404

2404

2014

2014

+37

3108

3108

+172

2013

2013

-3

Dato

Puntero
de lista

Puntero

Figura 3.9 La misma lista enlazada de la Figura 3.8, con los nodos apareciendo en el
orden en que lo hacen en la lista en lugar de por su posicin en memoria.

En el esquema secuencial, habramos tenido que mover todos los nodos ms all del
nodo k un lugar hacia arriba para llenar el hueco dejado por la supresin del nodo k (ver
Figura 3.11).
Por otra parte, operaciones tales como encontrar el nodo j-simo son mucho ms lentas
en una lista enlazada. En la lista secuencial, simplemente habramos accedido a LISTA
(j). En el esquema enlazado, debemos comenzar en el primer nodo y seguir los punteros

hasta que alcanzamos el nodo j. Tambin, dependiendo de cuantas posiciones de


memoria se necesitan para almacenar un elemento, la lista enlazada puede necesitar ms
espacio de memoria para cada nodo, ya que se debe almacenar tambin un puntero.
(Cuando un nodo de una lista enlazada no ocupar ms espacio que en una lista
almacenada de forma secuencial?).

74

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

ALGORITMOS Y LENGUAJES

2378

Direccin

2378

+253

3107

3107

-16

2404

2404

2014

2014

+37

3108

3108

+172

2013

2013

-3

Dato

Puntero
de lista

Puntero

Figura 3.10 Lista enlazada de las Figuras 3.8 y 3.9 pero con el tercer nodo suprimido

La asignacin de memoria, sin embargo, puede ser mucho ms eficaz. Podemos


mantener una zona de palabras de memoria disponibles, todas ellas enlazadas
conjuntamente. Cuando cualquiera de nuestras listas necesita ampliarse, se puede tomar
una palabra de esta zona comn. Anlogamente, cuando la lista no necesita ya una
palabra, podemos retornarla (re-enlazndola) a la zona comn. Esquemas de esta clase se
conocen como gestin dinmica de la memoria.
Recuerde que cuando representbamos una cola utilizando memoria secuencial y uno de
nuestros ndices alcanzaba el final de la lista, ponamos en condiciones iniciales al ndice
para apuntar al primer elemento. La asignacin dinmica de memoria de una lista
enlazada hace innecesaria esta clase de puesta de nuevo en condiciones iniciales (la lista
contendr exactamente el nmero de palabras que necesita realmente, ni ms ni menos.

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

75

INTRODUCCIN A LAS ESTRUCTURAS DE DATOS

Direccin

Nombre

1043

LISTA[1]

+253

1044

LISTA[2]

-16

1045

LISTA[3]

+37

1046

LISTA[4]

+172

1047

LISTA[5]

-3

1048

LISTA[6]

Figura 3.11 La misma lista secuencial de la Figura 3.7 pero con el tercer elemento de la
lista suprimido y todos los elementos restantes movidos u n lugar hacia arriba

Hay ocasiones, sin embargo, que se desea mantener una lista enlazada de un tamao fijo
y hacerla sin asignacin dinmica (por ejemplo, cuando sabemos que una lista nunca va a
necesitar tener ms de n nodos de longitud, y que la mayor parte del tiempo su tamao
no ser mucho menor que n). En tales casos nos gustara que nuestros punteros fueran
capaces de ir de forma conveniente desde el ltimo nodo de la lista hacia atrs al
primero.
Una forma sencilla de realizar esto es enlazar el ltimo nodo con el primero. Esto, en
efecto, completa un crculo de nodos, cada uno apuntando al siguiente. Una estructura
de este tipo se denomina una lista circular (si en la Figura 3.8 el campo "puntero" de la
posicin 2.013 contuviese 2.378 en lugar de la lista sera circular).
Una generalizacin simple de la lista enlazada es la lista doblemente enlazada, donde
cada nodo contiene un puntero a su sucesor (como antes) y otro a su predecesor. En una
lista circular doblemente enlazada, no solamente el ltimo nodo apunta hacia el
primero, sino tambin de forma inversa (ver Figura 3.12). Cuales son las ventajas y
desventajas de las listas doblemente enlazadas?.

76

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

ALGORITMOS Y LENGUAJES

Puntero
de lista

a) Lista enlazada simple

Puntero
de lista

b) Lista circular enlazada simple

Puntero de
lista izquierdo

c) Lista enlazada doble

Puntero
de lista

d) Lista circular enlazada doble

Puntero de
lista derecho

Figura 3.12 Tipos de listas enlazadas

3.4 EJEMPLO DE APLICACIN: ALGORITMO DE ORDENACIN UTILIZANDO UN RBOL


BINARIO

A modo de ilustracin desarrollaremos otro algoritmo de ordenacin, que utiliza un rbol


como una estructura de datos intermedia en la transformacin de la secuencia de entrada
no ordenada en la secuencia de salida ya ordenada . El rbol utilizado es una clase
especial conocida como rbol binario; llamado as porque cada nodo tiene a lo ms dos
ramas que salen de l.
Un rbol binario es una estructura particularmente til para la ordenacin, puesto que las
dos ramas de cada nodo se pueden utilizar para representar relaciones de "antes" y
"despus". De forma ms precisa, un rbol binario est ordenado si los datos en cada
nodo siguen a todos los datos en el subrbol izquierdo del nodo (es decir todos los datos
que pueden ser alcanzados desde la rama izquierda del nodo) y precede a todos los datos
en el subrbol derecho del nodo (alcanzados a travs de la rama derecha del nodo). La

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

77

INTRODUCCIN A LAS ESTRUCTURAS DE DATOS

Figura 3.13 muestra dos rboles binarios ordenados alfabticamente; en la Figura 3.13b,
por ejemplo, Juan sigue alfabticamente a cada nombre de su subrbol izquierdo y
precede a todos los nombres en su subrbol derecho. Lo mismo se aplica a cualquier otro
nodo en el rbol. Obsrvese que no todos los nodos necesitan tener completas las dos
ramas; el nmero de ramas depende de la distribucin alfabtica de los nombres en el
rbol y de la forma en que se construy el rbol (que vamos a exponer a continuacin).
Juan

Felipe

Juan

Luis

Felipe

Arturo

Luis

Samuel

Jos

Mara
a)

b)

Figura 3.13 Dos rboles binarios ordenados alfabticamente

La base del algoritmo de ordenacin es:


Paso 1) Transformar la secuencia de entrada no ordenada en un rbol binario ordenado.
Paso 2) Transformar el rbol binario en una secuencia de salida.
Como los dos pasos son independientes podemos escribir cada uno de ellos como un
mdulo separado. Los dos mdulos necesitados son construir-rbol que construye el
rbol a partir de la entrada y sacar-rbol que produce la lista de salida a partir del
rbol. Desarrollamos cada uno de estos mdulos, utilizando como ejemplo la lista de
entrada siguiente:
Juan, Luis, Samuel, Felipe, Arturo, Jos, Mara

El rbol se construye comenzando con nada y aadiendo cada nombre de la lista de


entrada en secuencia. Una primera aproximacin al mdulo construir-rbol es por lo
tanto:

78

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

ALGORITMOS Y LENGUAJES

mdulo construir-rbol (L, A)


{construye

un

rbol

binario

ordenado

partir

de

una

lista de nombres de entrada L}


comenzar en el principio de L
mientras L tenga nombres hacer
aadir el siguiente nombre a A.

El proceso de aadir un nombre al rbol (la ltima lnea del algoritmo anterior) se puede
describir mediante un mdulo recursivo. Si todava no existe el rbol (est vaco) se crea
un nuevo rbol con el nombre como su raiz y nico nodo. Si el rbol existe el nombre
que se aade se compara con el nombre en la raz. Si precede alfabticamente al nombre
que hay en la raz entonces se debe aadir al subrbol izquierdo, en otro caso se debe
aadir al subrbol derecho. El mdulo para aadir un nombre es:
mdulo aadir-nombre (nombre, A)
{aade nombre al rbol binario ordenado A}
si A est vaco
entonces crear un nuevo subrbol que tenga como raz nombre
si no si nombre precede al nombre de la raz de A
entonces aadir-nombre (nombre, subrbol izquierdo A)
si no aadir-nombre (nombre, subrbol derecho A)

Obsrvese que la recursin eventualmente cesa puesto que el rbol que es el parmetro
actual del mdulo se hace ms pequeo con las sucesivas llamadas. Cuando se hace tan
pequeo como para estar vaco se aade el nuevo nombre como raz (y nico nodo) de
un nuevo subrbol y termina. En la Figura 3.14 se muestra la adicin del nombre Jos a
un rbol construido parcialmente. En sucesivas llamadas recursivas de aadir-nombre
Jos se aade al subrbol izquierdo de Juan y al subrbol derecho de Felipe. Como
este ltimo subrbol est vaco se crea un nuevo subrbol con Jos como su nico nodo.
Juan

Felipe

Arturo

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

Luis

Jos

Samuel

79

INTRODUCCIN A LAS ESTRUCTURAS DE DATOS

Figura 3.14 Adicin de "Jos" a un rbol binario construido parcialmente

El mdulo construir-rbol completo es:


mdulo construir-rbol (L, A )
{Construye

un

rbol

binario

ordenado

partir

de

una

lista de nombres L}
comenzar al principio de L
mientras L tenga nombre hacer
aadir-nombre (prximo nombre, A )

donde el mdulo aadir-nombre se defini anteriormente.


El mdulo sacar-rbol que produce una lista ordenada del rbol binario puede
escribirse tambin de forma recursiva. La salida de un rbol completo en el orden
correcto se consigue sacando el subrbol izquierdo de la raz, a continuacin la raz y
finalmente el subrbol derecho de la raz. La recursin cesa cuando el rbol que hay que
sacar se reduce a que no existe y por lo tanto no hay nada que hacer. El mdulo es:
mdulo sacar-rbol (A)
{sacar

todos

los

nodos

del

rbol

binario

en

orden

de

izquierda a derecha}
si A no est vaco
entonces

sacar-rbol (subrbol izquierdo de A)


escribir el nombre que hay en la raz de A
sacar-rbol (subrbol derecho de A)

E1 algoritmo de ordenacin completo se puede escribir de la forma siguiente:

80

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

ALGORITMOS Y LENGUAJES

mdulo ordena (L)


{ordena la lista L en orden alfabtico}
comenzar con un rbol vaco llamado A
construir-rbol (L, A)
sacar-rbol (A)

3.5 ACTIVIDADES
1. Elija un conjunto de datos que se puedan tratar favorablemente con una estruct ura de
array.
2. Elija un conjunto de datos que se puedan tratar favorablemente con una estructura de
cola.
3. Elija un conjunto de datos que se puedan tratar favorablemente con una estructura de
pila.
4. Elija un conjunto de datos que se puedan tratar favorablemente con una estructura de
rbol.
5. Algoritmo de insercin de un elemento en una cola .
6. Algoritmo de insercin de un elemento en una pila .

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

81

INTRODUCCIN A LAS ESTRUCTURAS DE DATOS

82

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

ALGORITMOS Y LENGUAJES

APNDICE I. CDIGO ASCII

El cdigo ASCII (siglas de American Code for Information Interchange) es un conjunto


de caracteres reconocido internacionalmente que se utiliza principalmente por todos los
ordenadores que soportan el sistema operativo MS-DOS. La ventaja de que este cdigo
sea un estndar universal es que todos los caracteres alfanumricos disponen de la misma
representacin binaria en la memoria de la mquina, lo cual facilita el intercambio de
informacin entre ordenadores. Se suele representar por una tabla o lista en la que cada
caracter se identifica por la posicin que ocupa en la tabla o lista. As, la A es el 65
porque ocupa la posicin 65 de la tabla, mientras que la a es el 97 por ser esa su
posicin.
El cdigo ASCII puede ser de 7 bits (27 = 128 caracteres) o en su versin extendida de 8
bits (28 = 256 caracteres), siendo esta ltima la que ms se emplea en los ordenadores
actuales, pero por contra la que ms puede diferir de un fabricante de ordenadores a
otro, a diferencia de la versin de 7 bits que es ms estndar. El que sea de 7 o de 8 bits
indica el nmero de bits que va a utilizarse para almacenar en memoria cada carcter.
El conjunto de caracteres est dividido en dos grandes grupos: caracteres especiales (del
0 al 31) y los restantes (del 32 al 255 en la versin de 8 bits). Los caracteres especiales
del 0 al 31 suelen representar funciones de control, como por ejemplo, el 13 es el retorno
de carro, el 7 el timbre, el 10 el avance de la lnea de las impresoras, etc. Los caracteres
del 128 al 256 constituyen una mezcolanza de caracteres grficos, letras griegas,
smbolos monetarios y caracteres no utlizados en la lengua inglesa (por ejemplo, la y
las vocales acentuadas).
Habitualmente, en los ordenadores con sistema operativo Ms-Dos es posible escribir un
carcter ASCII pulsando la tecla <Alt> y tecleando la posicin que ocupa en la tabla.
Por ejemplo, para obtener el carcter habra que mantener pulsada la tecla <Alt> y
teclear simultneamente el nmero 132.

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

83

CDIGO ASCII

Valor Carcter
decimal
NUL
0
SOH
1
STX
2
ETX
3
EOT
4
ENQ
5
ACK
6
BEL
7
BS
8
HT
9
LF
10
VT
11
FF
12
CR
13
SO
14
SI
15
DLE
16
DC1
17
DC2
18
DC3
19
DC4
20
NAK
21
SYN
22
ETB
23
CAN
24
EM
25
SUB
26
ESC
27
FS
28
GS
29
RS
30
US
31

84

Valor Carcter
decimal
32
!
33
34
#
35
$
36
%
37
&
38
'
39
(
40
)
41
*
42
+
43
,
44
45
.
46
/
47
0
48
1
49
2
50
3
51
4
52
5
53
6
54
7
55
8
56
9
57
:
58
;
59
<
60
=
61
>
62
?
63

Valor Carcter
decimal
@
64
A
65
B
66
C
67
D
68
E
69
F
70
G
71
H
72
I
73
J
74
K
75
L
76
M
77
N
78
O
79
P
80
Q
81
R
82
S
83
T
84
U
85
V
86
W
87
X
88
Y
89
Z
90
[
91
\
92
]
93
^
94
_
95

Valor Carcter
decimal
`
96
a
97
b
98
c
99
d
100
e
101
f
102
g
103
h
104
i
105
j
106
k
107
l
108
m
109
n
110
o
111
p
112
q
113
r
114
s
115
t
116
u
117
v
118
w
119
x
120
y
121
z
122
{
123
|
124
}
125
~
126
127
DEL

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

ALGORITMOS Y LENGUAJES

Valor Carcter
decimal

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

Valor Carcter
decimal

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

Valor Carcter
decimal

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

Valor Carcter
decimal

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247
248

249

250

251

252

253

254
255

85

CDIGO ASCII

86

DPTO. DE INFORMTICA Y AUTOMTICA. UNED.

Das könnte Ihnen auch gefallen