Você está na página 1de 48

Algoritmos, Datos y Programas - 2010

CONCEPTOS BÁSICOS
Informática: es la ciencia que estudia el análisis y la resolución de problemas utilizando computadoras.

Computadora: máquina digital y sincrónica, con cierta capacidad de cálculo numérico y lógico, controlado por
un programa almacenado y con probabilidad de comunicación con el mundo exterior. La finalidad de la
computadora es ayudar al hombre a realizar tareas repetitivas en menor tiempo y con mayor exactitud.

Digital: maneja señales y procesa información representada con valores binarios (0 ó 1).

Sincrónica: realiza operaciones coordinadas por un reloj central.

Capacidad de cálculo numérico y lógico: gracias a la Unidad Aritmético-Lógica (ALU).

Programa Almacenado: internamente se tienen instrucciones almacenadas que el procesador lee,


interpreta y ejecuta ordenadamente.

Algoritmo: especificación rigurosa (clara y unívoca) de la secuencia de instrucciones a realizar sobre un


autómata para alcanzar un resultado deseado en un tiempo finito (un algoritmo comienza y termina).

Dato: es una representación de un objeto del mundo real mediante la cual podemos modelizar aspectos del
problema que se quiere resolver con un programa sobre una computadora.

Programa: conjunto de instrucciones u órdenes ejecutables sobre una computadora, que permite cumplir con
una función o requerimiento específico (dichas órdenes se expresan en un lenguaje de programación concreto).

Lenguaje de programación: es el conjunto de instrucciones permitidas y definidas por sus reglas sintácticas y su
valor semántico, para la expresión de soluciones a problemas.

DEL PROBLEMÁ REÁL Á SU SOLUCION POR COMPUTÁDORÁ

Problema del
Análisis Diseño Implementación Solución
mundo real
Abstracción Descomposición

Modelo Solución Algoritmos


Modularizada

En la etapa de análisis se trata de encontrar los aspectos principales del problema del mundo real y determinar
en forma clara y concreta el objetivo que se desea, esto se denomina especificación. De allí se establece un
modelo o abstracción del problema real que permitiría su resolución en una computadora.

1
Algoritmos, Datos y Programas - 2010

A partir del modelo es necesario avanzar en la etapa del diseño de una solución. El primer paso en esta etapa es
la modularización, es decir, la descomposición funcional de todas las acciones que propone el modelo. Esto
ayuda a reducir la complejidad, a distribuir el trabajo y en el futuro a re-utilizar los módulos.

Una vez que se tiene la descomposición en módulos, se debe comenzar con su implementación: esto requiere
escribir algoritmos en un lenguaje de programación y elegir la representación de los datos.

Finalmente, cuando se tiene un programa escrito en un lenguaje real y depurado de errores, se procede a la
verificación, es decir, que la ejecución del programa conduzca al resultado deseado, con datos representativos
del problema real.

PROGRÁMÁ = INSTRUCCIONES + DÁTOS


Las componentes básicas de un programa son instrucciones y datos. (Niklaus Wirth, científico la computación)

Las instrucciones (o acciones) representan las operaciones que ejecutará la computadora al interpretar el
programa.

Los datos representan objetos del mundo real, son los valores de información de los que se necesita disponer y
en ocasiones transformar para ejecutar la función del programa

Es decir, a partir de un contexto determinado por las precondiciones el programa transforma la información y
debiera llegar al resultado esperado produciendo un nuevo contexto, caracterizado por las postcondiciones.

Pre-condición es la información que se conoce como verdadera antes de iniciar el programa (ó módulo).

Post-condición es la información que debería ser verdadera al concluir el programa (ó módulo), si se cumplen
adecuadamente los pasos especificados.

ESTRUCTURÁS DE CONTROL
Existen en todos los lenguajes de programación un conjunto mínimo de instrucciones que permiten especificar
el control del algoritmo que se quiere implementar, se lo conoce como estructura de control.

 SECUENCIA: es la estructura de control más simple, está representada por una sucesión de operaciones (por
ej. asignaciones), en la que el orden de ejecución coincide con el orden físico de aparición de las
instrucciones.

 DECISIÓN: en un algoritmo representativo de un problema real es prácticamente imposible que todo sea
secuencial. Es necesario tomar decisiones en función de los datos del problema.

2
Algoritmos, Datos y Programas - 2010

La estructura básica de decisión entre dos alternativas es la que se representa simbólicamente:

La sintaxis para una decisión en Pascal es la siguiente:

If (Condición) then begin


Acciones_por_condición_verdadera;
End
Else begin
Acciones_por_condición_falsa
End;

 SELECCIÓN: en una extensión de la estructura básica de decisión, para el caso que las alternativas sean más
de dos. Simbólicamente:

La sintaxis para una decisión en Pascal es la siguiente:

Case (Variable_Decisión) of
Posibilidad1: Acciones_para_posibilidad_1;
Posibilidad2: Acciones_para_posibilidad_2;
...
Else Acciones_para_posibilidades_no_contempladas_antes;
End;

3
Algoritmos, Datos y Programas - 2010

Consideraciones para la estructura Selección en Pascal (CASE):

 La variable de decisión debe ser de tipo ordinal (entero, boolean, char).


 Puede haber más de un valor en cada una de las entradas
 Un valor debe aparecer en una sola de las entradas
 Deben incluirse todas las posibilidades

 REPETICIÓN: es una extensión natural de la secuencia. Consiste en repetir N veces un bloque de acciones.
Este número de veces que se deben ejecutar las acciones es fijo y conocido de antemano. Simbólicamente:

La sintaxis para una repetición en Pascal es la siguiente:

For indice:= valor_inicial to valor_final do begin


Acciones
End;

Consideraciones acerca de la variable índice en Pascal:

 La variable de control debe ser de tipo ordinal (entero, boolean, char).


 NO debe modificarse dentro de las acciones del lazo.
 Está implícito que en cada ciclo la variable índice toma el valor siguiente de acuerdo al tipo ordinal
asociado a dicha variable. Conceptualmente, el índice se actualiza en cada ciclo y se testea respecto del
valor final deseado. Notar que valor_final - valor_inicial + 1 es el número de veces que se ejecuta el ciclo.
 Al terminar el ciclo, la variable índice no tiene un valor definido (su uso se limita a la repetición).

4
Algoritmos, Datos y Programas - 2010

 ITERACIÓN: puede ocurrir que se desee ejecutar un bloque de instrucciones desconociendo el número exacto
de veces que se ejecutan. Para estos casos existen las estructuras de control iterativas condicionales.
Como su nombre lo indica, las acciones se ejecutan dependiendo de la evaluación de la condición.
Estas estructuras se clasifican en pre-condicionales y post-condicionales.

Las estructuras iterativas pre-condicionales primero evalúan la condición y si es verdadera se ejecuta el


bloque de acciones. Dicho bloque se pueda ejecutar 0, 1 ó más veces.
El valor inicial de la condición debe ser conocido o evaluable antes de la evaluación de la condición.

La sintaxis para una iteración pre-condicional en Pascal es la siguiente:

While (Condición) do begin


Acciones
End;

En cambio, en las estructuras iterativas post-condicionales primero se ejecuta el bloque de acciones y luego se
evalúa la condición. A diferencia de la iteración pre-condicional, el bloque de acciones se ejecuta 1 ó más veces.

La sintaxis para una iteración post-condicional en Pascal es la siguiente:

Repeat
Acciones
Until (Condición);

5
Algoritmos, Datos y Programas - 2010

ESTRUCTURÁ DE UN PROGRÁMÁ
Sintaxis de un programa en lenguaje Pascal:

Program identificador;

Const
{Definición de constantes}

Type
{Definición de Tipos de datos definidos por el usuario}

Var
{Declaración de variables}

Procedure
{Definición de procedimientos}

Function
{Definición de funciones}

Begin {Cuerpo del Programa}


Sentencias
End.

CÁLIDÁD DE UN PROGRÁMÁ
Los factores que determinan la calidad del software se clasifican en tres grupos:

 Operatividad del producto (características operativas):

 Corrección (¿Hace lo que se le pide?)


El grado en que una aplicación satisface sus especificaciones y consigue los objetivos encomendados por
el cliente.

 Fiabilidad (¿Lo hace de forma fiable todo el tiempo?)


El grado que se puede esperar que una aplicación lleve a cabo las operaciones especificadas y con la
precisión requerida.

 Eficiencia (¿Qué recursos hardware y software necesito?)


La cantidad de recursos hardware y software que necesita una aplicación para realizar las operaciones
con los tiempos de respuesta adecuados.

6
Algoritmos, Datos y Programas - 2010

 Revisión del producto (capacidad para soportar cambios).

 Facilidad de mantenimiento (¿Puedo localizar los fallos?)


El esfuerzo requerido para localizar y reparar errores. Se va a vincular con la modularización y con
cuestiones de legibilidad y documentación.

 Flexibilidad (¿Puedo añadir nuevas opciones?)


El esfuerzo requerido para modificar una aplicación en funcionamiento

 Facilidad de prueba (¿Puedo probar todas las opciones?)


El esfuerzo requerido para probar una aplicación de forma que cumpla con lo especificado en los
requisitos.

 Transición del producto (adaptabilidad a nuevos entornos).

 Portabilidad (¿Podré usarlo en otra máquina?)


El esfuerzo requerido para transferir la aplicación a otro hardware o sistema operativo.

 Reusabilidad (¿Podré utilizar alguna parte del software en otra aplicación?)


Grado en que las partes de una aplicación pueden utilizarse en otras aplicaciones

 Interoperabilidad (¿Podrá comunicarse con otras aplicaciones o sistemas informáticos?


El esfuerzo necesario para comunicar la aplicación con otras aplicaciones o sistemas informáticos

LEGIBILIDÁD Y DOCUMENTÁCION
Legibilidad: el código fuente de un programa debe ser fácil de leer y entender. Esto obliga a acompañar a las
instrucciones con comentarios adecuados. Relacionado con la presentación de documentación.

Documentación: todo el proceso de análisis y diseño del problema y su solución debe estar documentado
mediante texto y/o gráficos para favorecer la comprensión, la modificación y la adaptación a nuevas funciones.

Un programa bien documentado será fácil de leer y mantener. Es común que la mayoría de los lenguajes de
programación provean algún mecanismo de documentación, por ejemplo, a través de la inserción de
comentarios en el programa.

Un programa sin comentarios revela un estilo pobre de programación y peligroso para el mantenimiento
adecuado del mismo.

Un programa bien documentado será fácil de leer y mantener.

7
Algoritmos, Datos y Programas - 2010

Es recomendable realizar un comentario general del objetivo del programa o del módulo de programa en
cuestión, que refleje una especificación del problema a resolver, lo más completa posible.

Su lectura debería ser suficiente para poder entender las acciones que se llevan a cabo en el mismo.

Los identificadores se deberán elegir de manera tal que sean autoexplicativos.

Los comentarios intercalados en el programa (documentación online), deben realizarse con criterio para
contribuir a la claridad del programa.

Cuando se realiza el mantenimiento de un programa no sólo se actualiza el código, sino también los comentarios
del programa. Debe quedar claro que los comentarios no son un agregado al programa sino parte del mismo.

CORRECCION Y EFICIENCIÁ
Corrección: Un programa es correcto cuando cumple con la función especificada; esto significa que cumple con
los requerimientos propuestos.

Para determinar cuáles son esos requerimientos se debe tener una especificación completa, precisa y no
ambigua del problema a resolver antes de escribir el programa.

Para medir si un programa es correcto se debe probar con datos reales que permitan verificar su función.

La verificación de programas es una labor muy importante, y la búsqueda de técnicas de verificación eficientes
es actualmente campo de investigación en la Ciencia de la Computación.

Eficiencia: es una métrica de calidad de los algoritmos, asociada con una utilización óptima de los recursos del
sistema de cómputo donde se ejecutará el programa.

MODULÁRIZÁCION
Modularizar significa dividir un problema en partes funcionalmente independientes, que encapsulen
operaciones y datos. Cada módulo puede pensarse como una caja negra con una función lógica bien definida
(QUÉ) que puede ser implementada internamente de muchos modos (CÓMO). La descomposición es una técnica
que se basa en el paradigma “divide y vencerás” y tiene siempre un objetivo: dividir cada problema en
subproblemas, y estos a su vez en subproblemas más pequeños, deben ser de forma tal que:

 Cada subproblema está en un mismo nivel de detalle.


 Cada subproblema puede resolverse independientemente.
 Las soluciones de los subproblemas pueden combinarse para resolver el problema original

8
Algoritmos, Datos y Programas - 2010

El método de diseño descendente (Top Down) es conocido también como modularización. Esquemáticamente:

Un buen diseño de programa va de lo general a lo particular, esto es que un problema sea descompuesto en un
número de subproblemas (módulos). Cada módulo tendrá una tarea específica bien definida y se comunicarán
entre sí adecuadamente para conseguir un objetivo común.

Un módulo es simplemente un “trozo de código”, o un conjunto de instrucciones más un conjunto de


definiciones de datos que realiza una tarea lógica.

IMPORTANCIA DE LA MODULARIZACIÓN

Mayor productividad, al dividir un sistema de software en módulos funcionalmente independientes, un equipo


de desarrollo puede trabajar simultáneamente en varios módulos, incrementando la productividad (es decir,
reduciendo el tiempo de desarrollo global del sistema).

Reusabilidad del código, es decir la posibilidad de utilizar repetidamente el producto de software desarrollado.

Mantenimiento, la modularización otorga facilidades de mantenimiento correctivo. La división lógica de un


sistema en módulos permite aislar los errores que se producen con mayor facilidad. Esto significa poder corregir
los errores en menor tiempo y disminuye los costos de mantenimiento de los sistemas.

Escalabilidad, la modularización otorga facilidades para el crecimiento del sistema. Los sistemas de software
reales crecen (es decir aparecen con el tiempo nuevos requerimientos del usuario). La modularización permite
disminuir los riesgos y costos de incorporar nuevas prestaciones a un sistema en funcionamiento

Legibilidad, un efecto de la modularización es una mayor claridad para leer y comprender el código fuente. El
ser humano maneja y comprende con mayor facilidad un número limitado de instrucciones directamente
relacionadas.

PROCEDIMIENTOS Y FUNCIONES
Los procedimientos y las funciones son algunos de los recursos con los que cuentan los lenguajes de
programación para especificar la modularización.

9
Algoritmos, Datos y Programas - 2010

Las funciones pueden pensarse como operadores definidos por el usuario, que reciben variables (parámetros
por valor) y producen un resultado único.

Los procedimientos son verdaderos subprogramas que interactúan en el espacio de datos del módulo que los
invoca a través de parámetros por referencia.

Procedimiento: es un conjunto de instrucciones que realizan una tarea específica y como resultado puede
retornar 0, 1 o más valores. Para devolver el resultado necesita. Permite operaciones de lectura y escritura. Se
invocan escribiendo su nombre seguido de los datos de comunicación. Sintaxis en Pascal:

Procedure Nombre_procedimiento (lista de parámetros);


Var
{Declaración de variables locales al módulo}
Begin
Sentencias…
End;

Funciones: es un módulo que realiza una única tarea y devuelve siempre un sólo valor de tipo simple. Para
devolver el resultado se asigna al nombre de la función como última instrucción. Respecto de las operaciones de
lectura y escritura, no es aconsejable introducirlas como parte del módulo. Se pueden invocar: dentro de un if, o
de un while, o asignarla a una variable o dentro de un write. Pueden recibir sólo parámetros de entrada. Sintaxis:

Function Nombre_función (lista de parámetros formales): tipo;


Var
{Declaración de variables locales al módulo}
Begin
Sentencias…
Nombre_función:=…;
End;

 Tipo: es el tipo del dato que devolverá la función. Debe ser de tipo simple.
 Al final del cuerpo de la función es obligatorio asignarle un valor del tipo devuelto al nombre de la función.

La lista de parámetros es opcional en ambos casos (funciones y procedimientos). El control vuelve a la


instrucción siguiente a la del llamado (en el programa principal).

El número y tipo de los argumentos utilizados en la invocación a una Función o un Procedimiento deben
coincidir con el número y tipo de parámetros del encabezamiento del módulo.

ÁLCÁNCE DE LOS DÁTOS: DÁTOS LOCÁLES Y GLOBÁLES


Los datos globales son aquellos que se declaran en la sección de declaración del programa principal. En cambio,
los datos locales son aquellos que se declaran en la sección de declaración de un módulo individual

10
Algoritmos, Datos y Programas - 2010

OCULTAMIENTO Y PROTECCIÓN DE DATOS

La comunicación de los datos entre el programa y los módulos puede hacerse mediante parámetros y variables
globales. Pero utilizar variables globales tiene varias desventajas:

 Demasiados identificadores (conflictos de nombres).


 No se especifica la comunicación deseada entre los módulos.
 Posibilidad de perder integridad de los datos, al modificar involuntariamente en un módulo datos de
alguna variable que luego deberá utilizar otro módulo.

La solución a estos problemas ocasionados por el uso de variables globales es una combinación de ocultamiento
de datos (Data Hidding) y uso de parámetros:

El ocultamiento de datos significa que los datos exclusivos de un módulo NO deben ser "visibles" o utilizables
por los demás módulos.

El uso de parámetros significa que los datos compartidos se deben especificar como parámetros que se
trasmiten entre módulos.

Es decir, se analiza para cada módulo y los datos propios se declaran locales al módulo, mientras que los datos
compartidos se declararán como parámetros.

COMUNICÁCION ENTRE MODULOS: USO DE PÁRÁMETROS


La comunicación externa de un módulo con el resto del sistema puede no existir, pero si existe esa
comunicación debe hacerse a través de los parámetros. Los parámetros son variables que tienen como
característica principal transferir información entre los módulos. Deben definirse en el encabezado del módulo
(parámetros formales) y se debe especificar el tipo de datos con el que se corresponde, también deben
especificarse en la invocación del módulo (parámetros actuales). En Pascal y la mayoría de los lenguajes se exige
que haya igual cantidad de parámetros formales que actuales y la correspondencia entre ellos es por posición.
Es decir, el primer parámetro actual se corresponde con el primero formal, y así sucesivamente.

Parámetro por valor (IN): significa que el módulo pasa una copia de los datos a otros módulos, el módulo que la
recibe (sobre una variable local) puede realizar operaciones y/o cálculos, pero no podrá efectuar ningún cambio
sobre el dato original. Al producir una copia de los datos, esto puede significar una utilización importante de
memoria y tiempo de cómputo. Un parámetro por valor debiera ser tratado como una variable de la cual el
Procedimiento o Función hace una copia y la utiliza localmente.

Parámetro por referencia (OUT, INOUT): significa que no se envía una copia del valor del dato, sino que envían
la dirección donde se encuentra el dato, con lo cual se puede operar con ella y su valor original dentro del
módulo, y las modificaciones que se produzcan se reflejan en los demás módulos que conocen la variable. Como
opera directamente sobre la dirección de la variable original, no se requiere memoria local. La sintaxis que
utiliza Pascal para identificar un parámetro por referencia consiste en poner previo a este la palabra clave var.

11
Algoritmos, Datos y Programas - 2010

TIPOS DE DÁTOS
Un tipo de dato es una clase de objetos ligados a un conjunto de operaciones para crearlos y manipularlos. Se
caracterizan por:

 Un rango de valores posibles.


 Un conjunto de operaciones realizables sobre ese tipo.
 Una representación interna.

Al definir un tipo de dato lo que se está indicando es la clase de valores que pueden tomar sus elementos y las
operaciones que pueden realizarse sobre ellos.

TIPOS SIMPLES

Los tipos de datos simples existen en todos los lenguajes de programación (también llamados estándar o
definidos por el lenguaje) y permiten manipular las representaciones más sencillas de información. Son:

 Tipo Numérico: el tipo de dato numérico es el conjunto de los valores numéricos que pueden representarse
de dos formas:

 Entero: es el tipo de dato numérico más simple de todos (elementos del tipo: ..., -2, -1, 0, 1, 2,...). Dado
que una computadora tiene memoria finita, la cantidad de valores enteros que se pueden representar
sobre ella son finitos (existe un número entero máximo y otro mínimo, generalmente denominado
maxint). Si se utilizan 16 dígitos binarios (bits) para almacenar en memoria cada número entero, esto
permite un rango de valores enteros entre -215 y +215.

 Real: es una clase de dato numérico que permite representar números decimales. La representación
para números reales se denomina coma flotante y es una generalización de la notación exponencial o
científica, que consiste en definir cada número como una mantisa (parte decimal) y un exponente
(posición de la coma).

Las operaciones válidas para el tipo de dato numérico son:

 Suma (+), resta (-), multiplicación (*): aceptan operandos enteros o reales, su resultado podrá ser
entero (si ambos son enteros) o real (si alguno de los operandos es real).
 división (/): su resultado será un real independientemente del operando real o entero.
 división entera (div) y módulo (mod): sólo para enteros y su resultado es el cociente de una división
entera (div) o el resto de la misma (mod).

El orden de precedencia es:

1. operadores *, /
2. operadores +, -
3. operadores div y mod.

12
Algoritmos, Datos y Programas - 2010

Además de los operadores matemáticos, el tipo de dato numérico posee operadores relacionales que
permiten comparar valores. Dichas relaciones son: igualdad (=), desigualdad (<>) y orden (<, <=, >, >=). El
resultado es del tipo de dato lógico (Verdadero o Falso).

 Tipo Lógico: el tipo de dato lógico, también llamado boolean permite representar datos que pueden tomar
solamente uno de dos valores: verdadero (true) y falso (false). Se utiliza en situaciones donde representan
dos alternativas a una condición. Los operadores lógicos básicos son (por orden de precedencia):

1. negación (not),
2. conjunción (and),
3. disyunción (or).

 Tipo Carácter: el tipo carácter representa un conjunto finito y ordenado de caracteres que la computadora
reconoce. El estándar ASCII establece cuáles son los elementos de dicho conjunto y el orden de precedencia
entre los mismos. Ejemplos de caracteres son:

 caracteres especiales: ‘!’, ‘#’, ‘$’, ‘%’, …


 Dígitos: ‘0’, ‘1’, ‘2’, …, ‘8’, ‘9’
 Letras mayúsculas: ‘A’, ‘B’, ‘C’, …, ‘Y’, ‘Z’
 Letras minúsculas: ‘a’, ‘b’, ‘c’, …, ‘y’, ‘

Un valor del tipo de dato carácter es sólo uno de los símbolos mencionados.
Dos caracteres se pueden comparar con los operadores relacionales =, <>, >, <, >=, <=, y el resultado de
cualquiera de ellos es un valor de tipo de dato lógico.

Salvo el tipo real, los otros tres tipos de datos tienen sus elementos ordenados discretamente, es decir existe un
elemente anterior y otro posterior. Por eso, a los tipos enteros, carácter y lógico se los denomina tipos de datos
ordinales.

CONSTANTES Y VARIABLES

Dado que hay diferentes tipos de datos, estos deben especificarse. Y a esta especificación dentro de un
programa se la conoce como declaración. Una vez declarado un tipo podemos asociar al mismo variables,es
decir nombres simbólicos que pueden tomar los valores característicos del tipo.

Conceptualmente, se tienen datos constantes que no cambian durante la ejecución del programa o datos
variables que durante la ejecución del programa pueden cambiar. Tantos las constantes como las variables
deben guardarse en la memoria de datos de una computadora y en ambos casos estarán representadas por un
nombre (identificador) asociado con una dirección única de memoria. El contenido (valor) de dicha dirección
será asignado una única vez para las constantes y, posiblemente, muchas veces para variables.

13
Algoritmos, Datos y Programas - 2010

DECLARACIONES

En Pascal, la declaración de constantes se realiza mediante la palabra clave const, de la forma:

const nombre = valor

donde “nombre” es el identificador que representa el nombre de la constante. El tipo de dato de la constante
queda definido implícitamente por el tipo de dato de valor.

Por su parte, las variables en Pascal se declaran utilizando la palabra clave var, de la forma:

var nombre_de_variable: tipo_de_variable

o, si hay varias variables del mismo tipo:

var nombre_de_variable_1,.., nombre_de_variable_n: tipo_de_variable

Los diferentes tipo_de_variable posibles en Pascal son:

Integer tipo de dato numérico entero


Real tipo de dato numérico real
Boolean tipo de dato lógico
Char tipo de dato carácter

Algunos lenguajes, como Pascal, exigen que se especifique a qué tipo pertenece cada una de las variables y
verifican que el tipo de los datos asignados a esa variable se correspondan con su definición. Esta clase de
lenguajes se denomina fuertemente tipados (strongly typed). Otra clase de lenguajes, que verifica el tipo de las
variables según su nombre, se denomina auto tipados (self typed). Existe una tercera clase de lenguajes que
permiten que una variable tome valores de distinto tipo durante la ejecución de un programa. Esta se denomina
dinámicamente tipados (dinamically typed).

ASIGNACIONES

Una de las sentencias básicas que poseen los lenguajes de programación es la asignación. Y es de la forma:

Nombre_de_variable:= expresión

Se evalúa la expresión de la derecha y se almacena el resultado en la variable de la izquierda, por lo que para
que la asignación sea válida (en Pascal) deben ser del mismo tipo o compatibles.

14
Algoritmos, Datos y Programas - 2010

TIPOS DEFINIDOS POR EL USUARIO

Un tipo de dato definido por el usuario es aquel que no existe en la definición del lenguaje (no estándar), donde
el usuario (programador) es el encargado de determinar su denominación, y el conjunto de valores y
operaciones que dispondrá el mismo. En Pascal, los tipos deben ser declarados antes de ser usados. La
declaración de tipos se hace a través de la palabra clave TYPE de la siguiente forma:

Type identificador = tipo_base;

Donde identificador es el nombre con que se conocerá al tipo de dato en el programa y tipo_base puede ser un
tipo estándar o alguno de los tipos de datos definidos por el usuario.

VENTAJAS DE DECLARAR TIPOS

 Flexibilidad: en el caso de ser necesario modificar la forma en que se representa el dato, sólo se debe
modificar una declaración en lugar de un conjunto de declaraciones de variables.

 Documentación: se pueden usar como identificador de los tipos, nombres autoexplicativos, facilitando
de esta manera el entendimiento y lectura del programa.

 Seguridad: se reducen los errores por uso de operaciones inadecuadas del dato a manejar, y se pueden
obtener programas más confiables.

 Tipo Enumerativo: un dato enumerativo puede verse como una lista ordenada de valores posibles para las
variables del tipo. Es un tipo de dato simple.

DECLARACIÓN

Un tipo enumerativo en Pascal se declara sólo enumerando sus valores encerrándolos entre paréntesis:

Type
Identificador = (valor_1, valor_2,…, valor_n);

 Los valores que se definen en la lista no pueden ser de los tipos estándar, tampoco pueden repetirse
valores entre identificadores distintos.
 Las operaciones válidas sobre las variables asociadas a este tipo son la asignación y la comparación.
 NO es posible realizar operaciones de entrada y salida, debido a esto estas variables son de uso interno,
que colaboran en la claridad del programa.

Como es una lista ordenada, el tipo enumerativo permite aplicar tres funciones relacionadas con el orden:

 PRED: devuelve el valor anterior del enumerativo correspondiente.


 SUCC: devuelve el valor siguiente del enumerativo.
 ORD: da la posición relativa del argumento dentro de la definición del enumerativo.

15
Algoritmos, Datos y Programas - 2010

Ventajas y Desventajas de los tipos enumerativos

 Promueven código autodocumentado.


 Ayudan a la legibilidad y mantenimiento de los programas.
 Permiten crear tipos de datos a medida de las especificaciones del problema en cuestión.
 Sin embargo, es restrictivo su uso debido a que no se puede realizar sobre ellas operaciones de
entrada/salida.

 Tipo Subrango: un tipo de dato subrango es un tipo ordinal que consiste de una sucesión de valores de un
tipo ordinal tomado como base. Es un tipo simple.

DECLARACIÓN

Se especifica indicando los valores inicial y final de la sucesión, separados por dos puntos seguidos:

Type
Identificador = valor_inicial .. valor_final;

 Las operaciones de un tipo de dato subrango se heredan del tipo base.

Ventajas de los tipos subrangoFacilita el chequeo de posibles errores, pues permite que el lenguaje verifique si
los valores asignados se encuentran dentro del rango establecido.

 Ayuda al mantenimiento del programa.

 Tipo Conjunto: un tipo de dato conjunto representará una colección de datos simples ordinales, sin
elementos repetidos y sin ningún orden interno. No es un tipo de dato simple. De la definición, se tiene que
se puede tener conjunto de enteros, caracteres, subrango ó enumerativos. La cantidad de elementos que
contiene el conjunto puede estar limitada por la implementación en cada lenguaje o sistema operativo. En
Pascal el número máximo de elementos de un conjunto es 255. El ordinal de cada elemento debe ser un
valor comprendido entre 0 y 255.

DECLARACIÓN

Type
Identificador = set of tipo_ordinal;

ASIGNACIONES

A una variable de tipo conjunto se le puede asignar valores escribiendo sus elementos consecutivamente,
encerrados entre corchetes y separados por comas, en la sección de instrucciones ejecutables.

Begin
.....
conjLetras := [„a‟, ‟b‟]; {el conj. tendrá las letras “a” y “b”}
conjLetras2 := [„a‟ .. ‟z‟]; {el conj. tendrá letras de “a” a “z”}
conjLetras3 := [ ]; {conjunto vacío}

16
Algoritmos, Datos y Programas - 2010

conjEdad := [1, 3, 20]; {el conj. contendrá los núm. 1, 3, 20}


.....
End;

OPERACIONES PERMITIDAS CON CONJUNTOS

Además de la asignación, Pascal permite:

 Intersección: se representa con el signo * y da como resultado otro conjunto. En el conjunto resultado
aparecen solamente los elementos comunes a los dos conjuntos. Ej.:

Begin
.....
conjLetras:= [„a‟ , ‟b‟] + [„j‟ , ‟k‟];
conjLetras2:= [„a‟] + [„l‟ , ‟m‟];
conjLetras3 := conjLetras * conjLetras2;
....
End;

 Unión: se representa con el signo + y da como resultado otro conjunto. En este conjunto resultado
aparecen los elementos de los dos conjuntos y aquellos elementos repetidos aparecen una vez. Ej.:

Begin
.....
conjMinus:= [„a‟..‟z‟];
conjLetras:= conjMinus + [„A‟..‟Z‟];
....
End;

 Diferencia: se representa con el signo - y da como resultado otro conjunto. Este conjunto resultado
contiene los elementos que están en el primer conjunto y no están en el segundo. Ej.:

Begin
....
conjLetras := [„a‟ , ‟b‟ , ‟c‟];
conjLetras2 := [„b‟ , ‟d‟ , ‟e‟];
conjLetras3 := conjLetras - conjLetras2;
....
End;

 Pertenencia: se representa con el operador IN y da como resultado un valor lógico. Esta operación
devuelve verdadero si el elemento está en el conjunto y falso en caso contrario. Ej.:

Begin
....
conjLetras := [„a‟, ‟ b‟ , ‟c‟];
res = „a‟ IN conjLetras;
....
End;

17
Algoritmos, Datos y Programas - 2010

 Se pueden usar los operadores relacionales para determinar si un conjunto está incluido en otro (<=), si
son distintos (<>) ó iguales (=).

 Un conjunto NO admite operaciones de lectura y escritura.

 Las operaciones de un tipo de dato subrango se heredan del tipo base.

 Tipo String: un tipo de dato string es una sucesión (cadena) de caracteres de un largo determinado, que se
almacenan en un área contigua de la memoria. Un carácter es una letra, número ó símbolo. Cuando se
trabaja con el tipo de dato string, se tienen k caracteres tratados como una sola variable (donde k es la
longitud del string). No es un tipo de dato simple.

DECLARACIÓN

Type
Identificador = string [longitud];

En Pascal, si no se especifica la longitud ese identificador podrá contener como máximo 255 caracteres.

ASIGNACIONES

Para asignar valor a una variable de tipo de dato string se hace igual que si fuera una variable de tipo
carácter. Si se le asigna mayor cantidad de caracteres que lo declarado como longitud máxima, los últimos a
partir de esa longitud se pierden y se dice que la hilera de caracteres “se trunca”.

Program uno;
Var
cad1: string[20];
cad2: string[5];
Begin
cad1:= „buenos días!‟;
cad2:= cad1;
End.

OPERACIONES PARA STRINGS

 Los strings pueden compararse con los operadores relacionales carácter por carácter: =, <>, <=, =>. Si
las cadenas que se comparan son de igual longitud y contienen los mismos símbolos, en el mismo
orden, el resultado de la operación igual (=) es verdadero. Si tienen distinta longitud el resultado de la
comparación es falso.

18
Algoritmos, Datos y Programas - 2010

TIPOS ESTRUCTURADOS

Una estructura de datos es un conjunto de variables (no necesariamente del mismo tipo) relacionadas entre sí
de diversas formas y que se puede operar como un todo, bajo un nombre único. Esto resulta útil porque permite
al programador representar los elementos del mundo real, que generalmente son más complejos. Es decir, los
tipos de datos simples tienen la “debilidad” de representar valores de datos únicos.

De acuerdo a la cantidad de valores que contienen, las estructuras de datos pueden ser:

 Simples: representan un único valor, por ejemplo, un número entero o un carácter.


 Compuestas: pueden contener más de un valor, por ejemplo un registro.

De acuerdo a los tipos de datos que almacenan, las estructuras de datos pueden clasificarse en:

 Homogénea: si los datos que la componen son todos del mismo tipo.
 Heterogénea: si los datos que la componen son de distinto tipo.

De acuerdo a la cantidad de espacio de memoria utilizado por la estructura durante la ejecución del programa:

 Estática: si la cantidad de elementos que contiene es fija, es decir, la cantidad de memoria que se utiliza
no varía durante la ejecución de un programa.
 Dinámica: si el número de componentes y, por lo tanto, la cantidad de memoria, puede variar durante la
ejecución de un programa.

 Tipo Registro: un registro es un conjunto de valores con tres características básicas:

1. Los valores pueden ser de distinto tipo; esto convierte a un registro en una estructura heterogénea.

2. Los valores almacenados en un registro son llamados campos, y cada uno de ellos tiene un
identificador; los campos son nombrados individualmente, como variables ordinarias. El acceso a un
campo de un registro es directo, y se hace referenciando a su nombre.

3. El almacenamiento ocupado por un registro es fijo, así que se trata de una estructura estática.

DECLARACIÓN DE UN REGISTRO

En Pascal, los tipos registro se construyen identificando al tipo como registro y luego especificando, entre las
palabras claves record y end, el nombre y tipo de los campos individuales (pueden ser tipos estándar o
definidos por el usuario, simples, o estructurados).

Type
Nombre_registro = record
Campo_1: tipo_campo_1;
Campo_2: tipo_campo_2;

End;

19
Algoritmos, Datos y Programas - 2010

ACCESO A LOS CAMPOS DE UN REGISTRO

En Pascal, para acceder a los campos de un registro, se necesita especificar tanto el nombre del registro
como el del campo que interesa. Esto se denomina calificar al campo:

Nombre_variable_registro.nombre_campo

donde nombre_variable_registro es el nombre de una variable de un tipo registro definido


previamente y, nombre_campo es el campo del registro que se quiere acceder.

ANIDAMIENTO DE REGISTROS

Las variables estructuradas, como los registros, pueden estar anidadas (una dentro de otra). Es decir, un
campo de un registro puede, a su vez, ser otro registro. Para acceder, se debe hacer una doble calificación:

Nombre_variable_registro.nombre_campo.nombre_campo

OPERACIONES SOBRE REGISTROS

 Dado que los campos de un registro son variables de algún tipo de dato, las operaciones posibles sobre
un campo son las permitidas para el tipo de dato correspondiente. Es decir, las operaciones deberán
aplicarse a cada uno de los campos que lo componen. Sólo la asignación podrá realizarse sobre todo un
registro y esto será posible siempre y cuando las variables utilizadas sean del mismo tipo registro.

 No pueden realizarse comparaciones entre registros completos (con ninguno de los operadores
relacionales), para saber si dos registros son iguales se debe evaluar la igualdad campo a campo

 No se pueden aplicar operaciones de lectura/escritura sobre las variables de tipo registro. Pero sí es
posible leer o escribir cada uno de los campos que corresponden a tipo que soportan L/E.

SENTENCIA WITH

Cuando se trabaja con registros, hay ocasiones en que el acceso a los campos a través de la calificación suele
ser tediosa. Para solucionar este inconveniente, Pascal provee una sentencia WITH que permite que un
registro sea nombrado una vez, y luego sea accedido directamente. Ejemplo:

With nombre_variable_registro do begin


… { sentencias que referencian sólo a los campos del registro }
End;

20
Algoritmos, Datos y Programas - 2010

 Tipo Arreglo: es una colección ordenada e indexada de elementos, con las siguientes características:

1. Todos los elementos son del mismo tipo; es decir, es un tipo de dato homogéneo.

2. Los elementos pueden recuperarse en cualquier orden, simplemente indicando la posición que
ocupan dentro de la estructura, por este motivo se dice que es una estructura indexada.

3. La memoria ocupada a lo largo de la ejecución del programa es fija, es una estructura estática.

Conceptos a destacar de los arreglos:

 El nombre de la variable tipo arreglo está asociada a un área de memoria fija y consecutiva (del
tamaño especificado en la declaración), que es el lugar donde se almacenarán los valores.

 El índice de un arreglo debe ser un tipo de dato ordinal, el cual permitirá acceder a cada elemento
del arreglo. El valor de dicho índice puede verse como el desplazamiento respecto de la posición
inicial del arreglo.

 Los arreglos pueden ser de distintas dimensiones. Esta dimensión indica la cantidad de índices
necesarios para acceder a un elemento del arreglo.

 El mayor inconveniente en el uso de arreglos se relaciona con que sus características estáticas
obligan, en ocasiones, a sobredimensionar la memoria requerida.

VECTORES

Un vector o arreglo lineal es un tipo de dato arreglo con un índice, es decir, con una dimensión.

Elem. 1 Elem. 2 Elem. 3 ----- Elem. n-1 Elem. n

Posición 1 Posición 2 Posición 3 Posición n-1 Posición n

En un vector, la manera de hacer referencia a alguno de sus elementos es a través del nombre del arreglo y
la posición del elemento dentro del mismo, de la forma:

Vector [posición]

Dentro de la memoria, cada celda del vector ocupa lugar en forma consecutiva a partir de la dirección inicial
de memoria asignada. La cantidad de espacio asignado al vector depende del número de celdas que el
mismo contiene y del tipo de dato que se asigna a cada una de ellas. Ej. Un vector de 5 celdas de enteros (2
bytes) ocupará 5 x 2 = 10 bytes.

21
Algoritmos, Datos y Programas - 2010

DECLARACIÓN DE UN VECTOR

La declaración debe contener tanto el tipo de elemento que contendrá el arreglo como el rango de valores
que puede tomar el índice, lo que define además la cantidad de elementos que componen la estructura:

Type
nombre_tipo_vector = array [indice] of tipo_de_dato;

donde nombre_tipo_vector es el identificador que se le da al tipo, índice es el rango de valores que


puede tomar el índice (en Pascal un ordinal, normalmente un subrango de tipos ordinales predefinidos por
el lenguaje) y tipo_de_dato es el tipo de dato de los elementos del vector.

ASIGNACIÓN DE VALORES A UN VECTOR

La asignación de un valor a un elemento de un vector tiene la siguiente forma:

Vector [posición] := valor


donde posición debe ser un valor literal o una variable (en ambos casos debe corresponderse con el tipo
de índice definido para el vector) y valor debe ser un valor literal o una variable del tipo de dato que
almacena el vector.

DIMENSIÓN FÍSICA Y DIMENSIÓN LÓGICA

La dimensión física del vector es el tamaño especificado en la declaración de la estructura.

La dimensión lógica es la dimensión efectiva del vector, esto es la cantidad de celdas que realmente se
utilizan, la cantidad de elementos que existen en el vector. Siempre debe ser menor o igual a la dimensión
física del vector.

Esto resulta útil a la hora de agregar o insertar elementos en el vector, ya que debe verificarse que exista
espacio suficiente en el mismo, es decir, debe verificarse que dim.Log < dim.Fis

OPERACIONES CON VECTORES

 AGREGAR AL FINAL (APPEND)

Procedure Agregar_al_final (var v: vector; var dimLog: integer;


elemento: integer;
var exito : boolean);
Begin
If (dimF > dimLog) then begin {verifica espacio suficiente}
v[dimLog + 1]:= elemento;
dimLog := dimLog + 1; {actualiza la cantidad de elementos}
exito := true
end
else exito := false;
End;

22
Algoritmos, Datos y Programas - 2010

 INSERTAR (INSERT )

Procedure Insertar (var v: vector; var dimLog: integer;


elemento: integer; pos: posicion;
var exito: boolean );
Var
i: integer;
Begin
if (dimF > dimLog) then begin {verifica espacio suficiente}
exito := true;
i := dimLog;
While ( i >= pos ) do begin
v [ i + 1 ] := v [ i ] ;
i := i - 1 ;
end;
v [pos] := elemento;
dimLog := dimLog + 1; { Actualiza cantidad de elementos }
end
else éxito := false;
End;

 BORRAR

Procedure Borrar (var v: vector; var dimLog: integer;


var elemento: integer; pos: posicion;
var exito: boolean );
Var
j: integer;
Begin
if pos >=1 and pos <= dimLog then begin {verifica valor de pos}
exito := true
elemento := v[pos] ;{Guarda el valor del elemento a borrar}
for j:= pos to dimLog-1 do
v [ j ] := v [ j + 1 ] ;
dimLog := dimLog-1 ; {Actualiza cant. elementos del vector}
end
else exito := false;
End;

23
Algoritmos, Datos y Programas - 2010

 BÚSQUEDA

El proceso de ubicar información particular en una colección de datos es conocido como método de
búsqueda. En todos los casos los métodos de búsqueda consisten en buscar un dato que tiene una
propiedad particular, y en caso de encontrarlo retornar alguna información relacionada con el ítem.
Considerando la siguiente declaración genérica:

Const
Maxlen = … {máxima longitud del vector, es decir, Dim. Física }
Type
TipoElem = … { tipo de dato de los elementos del vector }
Indice = 0..maxlen;
Tvector = array [1..maxlen] of TipoElem;

 Búsqueda Lineal (o secuencial): se aplica cuando se debe buscar un elemento dentro de un vector sin tener
información sobre la manera en que este se encuentra organizado. Se procede linealmente (en forma
secuencial) comenzando desde el principio de la estructura, analizando los elementos uno a uno hasta
encontrarlo o hasta llegar al final.

El siguiente algoritmo busca el elemento x en el vector (pasado por referencia) y retorna la posición tan
pronto como sea posible, es decir, no sigue recorriendo el vector una vez que ya encontró el elemento. Si x
no es ningún elemento del vector, se retorna 0.

Procedure búsqueda_lineal (x: TipoElem; var v:TVector;


dimLog: Indice; var j:Indice);
Begin
j:=1;
while (j<=dimLog) and (x<>v[j]) do
j:=j+1;
if (j>dimLog) then j:=0;
End;

En el siguiente algoritmo se comienza agregando el elemento buscado (x) al final del vector (previamente
hay que verificar que dimLog < dim. Física), de forma tal que se reduzca la cantidad de preguntas de cada
iteración a la mitad (la condición si el elemento existe no se hace porque el dato ahora seguro existe). Este
ítem agregado al final del vector se conoce como “centinela” y es quien evita que el bucle sea infinito.

Procedure búsqueda_lineal_con_centinela(x: TipoElem; var v: TVector;


dimLog: Indice; var j:Indice);
Begin
{ se debe validar que hay espacio físico en el vector }
v[dimLog+1]:=x;
j:=1;
while (x<>v[j]) do
j:=j+1;
if (j>dimLog) then
j:=0;
End;

24
Algoritmos, Datos y Programas - 2010

Características de la Búsqueda Lineal o Secuencial

 Se aplica cuando los elementos no tienen orden.


 Requiere excesivo consumo de tiempo en la localización del elemento.
 Número medio de comparaciones (dimLog + 1) /2
 Es ineficiente a medida que el tamaño del arreglo crece.

 Búsqueda Binaria: se aplica sobre vectores ordenados basándose en la estrategia “divide y vencerás”.
i. Se compara el ítem buscado con el que se halla en el medio del vector.

ii. Si los dos elementos son iguales la búsqueda termina.

iii. Si el elemento buscado es menor que el que se halla en el punto medio del vector, se continúa la
búsqueda en la primera mitad del vector ignorando el otro 50% de los datos, caso contrario sobre la
segunda mitad. Se continúa así, restringiendo el análisis a porciones más pequeñas del vector.

iv. El proceso termina cuando se encuentra el elemento buscado (cuando coincida con un punto medio)
o cuando la porción del vector sea tan pequeña que ya no contenga elementos, en cuyo caso se
puede concluir que el elemento buscado no pertenece al vector.

Procedure búsqueda_binaria (var v:Tvector, j:Indice; dimLog:Indice;


x:TipoElem);
Var
pri, ult, medio: Indice;
Begin
j :=0;
pri:= 1;
ult:= dimLog;
medio := (pri + ult ) div 2;
while (pri <= ult) and ( x <> v [medio]) do begin
if ( x < v [medio] ) then
ult:= medio -1;
else
pri:= medio +1;
medio := (pri + ult) div 2;
end;
if (pri < = ult) then
j := medio
else
j := 0;
End;

Características de la Búsqueda Binaria

 Se aplica cuando los elementos tienen orden. Caso contrario debería ordenarse el vector previamente.
 El número medio de comparaciones es (1+log2 (dimLog+1) ) /2.
 Cuando dimLog crece el número medio de comparaciones es log2 (dimLog+1)/2.

25
Algoritmos, Datos y Programas - 2010

 ORDENACIÓN

Al proceso por el cual un grupo de elementos puede ser ordenado se lo conoce como algoritmo de
ordenación. Son útiles porque la organización de la información en un vector permite realizar búsquedas
más eficientes. Los algoritmos de ordenación buscan intercambiar los elementos o llevarlos al lugar
adecuado de manera de dejar la estructura ordenada. Considerando la siguiente declaración genérica:

Const
Maxlen = … {máxima longitud del vector, es decir, Dim. Física }
Type
TipoElem = … { tipo de dato de los elementos del vector }
Indice = 0..maxlen;
Tvector = array [1..maxlen] of TipoElem;

 Método de Selección: es el más sencillo, busca el elemento menor según el criterio adoptado y lo ubica al
comienzo, intercambiándolo con el primero (v[1]), a continuación se busca el segundo elemento menor del
vector y se intercambia con v[2] y así sucesivamente. Para ordenar un vector completo es necesario realizar
dimLog-1 pasadas por el vector, luego de eso el elemento más grande queda acomodado automáticamente.

Procedure Ordenar_selección (var v: tVector; dimLog: indice );


var
i, j, p: indice;
item : tipoElem;
begin
for i:= 1 to dimLog-1 do begin {busca el mín entre v[i],…, v[N]}
p := i;
for j := i+1 to dimLog do
if v[ j ] < v[ p ] then
p:=j; {intercambia v[i] y v[p] }
item := v[ p ];
v[ p ] := v[ i ];
v[ i ] := item;
end;
end;

Funcionamiento:

3 5 2 1
Paso 1: se intercambia v[1] con v[4]

1 5 2 3
Paso 2: se intercambia v[2] con v[3]

1 2 5 3
Paso 3: se intercambia v[3] con v[4]

1 2 3 5

26
Algoritmos, Datos y Programas - 2010

 Método de Intercambio (o Burbujeo): similar al de selección, realiza dimLog -1 pasadas, pero no mueve
ítems grandes distancias sino que a lo sumo 1 distancia, esto es porque se comparan ítems adyacentes y se
los intercambia si están desordenados. Al fin de cada pasada el mayor viaja en forma de “burbuja” y queda
al fondo del vector (no es necesario re - compararlo).

Procedure Ordenar_intercambio (var v: tVector; dimLog: índice);


var
i, j, p: indice;
item: tipoElem;
begin
for i:=dimLog downto 2 do begin { pone el mayor elemento de
for j := 1 to i-1 do v[1],…,v[i] en v[i]}
if v[ j ] > v[ j+1 ] then begin
item := v[ j ]; {intercambiar elementos}
v[ j ] := v[ j+1 ];
v[ j+1 ] := item;
end;
end;
end;

Funcionamiento:
Pasada 1

3 5 2 1
3 5 2 1
3 2 5 1

Pasada 2

3 2 1 5
2 3 1 5

Pasada 3

2 1 3 5
1 2 3 5

27
Algoritmos, Datos y Programas - 2010

 Método de Intercambio con centinela: utiliza una variable lógica o centinela para corregir el problema del
algoritmo anterior que, a pesar de no haber cambios, los elementos del vector se siguen comparando hasta
terminar realizando un trabajo innecesario. De esta manera, en caso de no producirse ningun cambio, se
termina el proceso. Pese a esto no es de lo más eficiente.

Procedure Ordenar_intercambio_con_centinela (var v: tVector;


dimLog: indice );
var i, j: indice;
item: tipoElem;
huboCambio: boolean;
begin
i := dimLog;
repeat
huboCambio := false;
for j := 1 to i-1 do
if v[ j ] > v[ j+1 ] then begin
item := v[ j ]; {intercambiar elementos }
v[ j ] := v[ j+1 ];
v[ j+1 ] := item;
huboCambio := True;
end;
i := i - 1;
until( (i < 2) or not (HuboCambio);
end;

 Método de Inserción: este método ordena el vector de entrada insertando cada elemento v[i] entre los i-1
anteriores que ya están ordenados. Para esto comienza a partir del segundo elemento, suponiendo que el
primero ya está ordenado. Si los dos primeros elementos están desordenados los intercambia. Luego toma
el tercer elemento y busca su posición correcta con respecto a los dos primeros. En general para el elemento
i, busca su posición con respecto a los i-1 elementos anteriores y de ser necesario lo inserta adecuadamente.

Procedure Ordenar_insercion (var v: tVector; dimLog: indice );


var
i, j: indice;
item: tipoElem;
begin
for i:=2 to dimLog do begin
item := v[i];
j := i-1; { apunta al primer elemento a comparar }
while (j>0) and (v[ j ] > item) do begin
v[ j+1 ] := v[ j ]; { se corre 1 lugar a la derecha }
j := j - 1;
end;
v[ j+1 ] := item; { inserta el item }
end;
end;

28
Algoritmos, Datos y Programas - 2010

Funcionamiento:
Pasada 1

3 5 2 1
v[1] ordenado
Pasada 2

2 3 5 1
v[1]…v[3] ordenado
Pasada 3

1 2 3 5
v[1]…v[4] ordenado

Análisis Empírico de los Algoritmos de Ordenación de Vectores

29
Algoritmos, Datos y Programas - 2010

MATRICES

Una matriz es un tipo de dato arreglo con dos dimensiones o índices. También puede pensarse en ella como
un vector de vectores. Es un grupo de elementos homogéneo, con un orden interno y en el que se necesitan
dos índices para referenciar un único elemento de la estructura

Elem. Elem. Elem. ----- Elem. Elem.


1, 1 1, 2 1, 3 1, n-1 1, n
FILAS Elem. Elem. Elem. ----- Elem. Elem.
2, 1 2, 2 2, 3 2, n-1 2, n
Elem. Elem. Elem. ----- Elem. Elem.
m, 1 m, 2 m, 3 m, n-1 m, n
COLUMNAS

En una matriz, la manera de referenciar a alguno de sus elementos es a través del nombre del arreglo y dos
valores de índice que indiquen la posición en fila y columna del elemento dentro del mismo, de la forma:

Matriz [fila, columna]

Cada celda de la matriz ocupa posiciones consecutivas de memoria, a partir de la dirección inicial asignada.
Por Ej., una matriz de 3x6 donde cada elemento ocupa 4 bytes, ocupará en total 3 x 6 x 4 = 72 bytes.

DECLARACIÓN DE UNA MATRIZ

La declaración debe contener tanto el tipo de elemento que contendrá el arreglo como el rango de valores
que puede tomar el índice, lo que define además la cantidad de elementos que componen la estructura:

Type
nombre_tipo_matriz = array [índice_fila, índice_columna] of tipo_dato;

donde nombre_tipo_matriz es el identificador que se le da al tipo, índice_fila es el rango de


valores que puede tomar el índice de filas (en Pascal un ordinal, normalmente un subrango),
índice_columna es el rango de valores que puede tomar el índice de columna (no necesariamente igual
o compatible al de las filas) y tipo_dato es el tipo de dato de los elementos de la matriz.

ASIGNACIÓN DE VALORES A UNA MATRIZ

La asignación de un valor a un elemento de una matriz tiene la siguiente forma:

Matriz [fila, columna] := valor

donde fila y columna deben ser un valor literal o una variable (en ambos casos debe corresponderse
con el tipo de índice definido para la matriz) y valor debe ser un valor literal o una variable del tipo de
dato que almacena la matriz.

30
Algoritmos, Datos y Programas - 2010

ARREGLOS N-DIMENSIONALES

La cantidad de dimensiones permitidas para un arreglo está acotada por el lenguaje de programaciñon y ,
básicamente por el espacio que la estructura ocupa en la memoria. Los arreglos siempre se definen
utilizando la misma metodolodia, sólo hay diferencia en la definición de las dimensiones. Un arreglo de tres
dimensiones recibe el nombre de tensor. Los índices de cada dimensión están determinados por sub-rangos
de tipo de dato entero.Una matriz es un tipo de dato arreglo con dos dimensiones o índices. También puede
pensarse en ella como un vector de vectores. Es un grupo de elementos homogéneo, con un orden interno y
en el que se necesitan dos índices para referenciar un único elemento de la estructura

DECLARACIÓN

En general, la declaración de un arreglo n-dimensional tiene la forma:

Type
nombre_tipo_arreglo_ndim = array [índice1, índice2, …, indiceN] of
tipo_dato;

donde cada índice es un subrango de algún tipo ordinal y tipo_dato es el tipo de dato de los elementos
del arreglo, y una vez definido se pueden declarar variables del mismo.

ARREGLOS COMO PARÁMETROS

Un arreglo puede ser enviado como parámetro a un módulo o puede recibirse como respuesta de un
determinado proceso. Un módulo que necesita información contenida en un arreglo solo como dato de
entrada, recibirá el parámetro por valor, mientras que necesitará recibirlo por referencia si debe retornar el
arreglo modificado. Pero, desde el punto de vista de la eficiencia en la utilización de recursos no siempre es
aconsejable que las estructuras de datos arreglo sean enviadas como parámetros por valor, porque el
contenido de la variable que se envía es copiado sobre la variable del módulo que recibe el dato y de esta
forma la memoria de la computadora está simultáneamente ocupada por dos variables distintas con los
mismos valores. De acuerdo a esto, no siempre es conveniente enviar a un módulo un tipo de dato arreglo
como parámetro por valor. En los casos en que la duplicación de memoria sea importante (no despreciable)
conviene utilizar un parámetro por referencia, obviamente tomando los recaudos para no modificar el
arreglo dentro del módulo invocado, ya que esto tendría un efecto lateral (side effect) sobre los datos.

31
Algoritmos, Datos y Programas - 2010

ALOCACIÓN DE MEMORIA
Existen dos tipos de alocación de memoria:

 Alocación Estática (stack) - variables estáticas

Las estructuras estáticas se caracterizan porque el espacio de memoria se reserva con anticipación en la
memoria física de la computadora y no cambia durante la ejecución del programa (ó módulo, en caso de ser
variables locales al mismo).

 Char = 1byte
 Integer = 2 bytes
 Real = 6 bytes
 Boolean = 1 byte
 String = cantidad de caracteres + 1
 Registro = la suma de lo que ocupa c/ campo
 Puntero = 4 bytes

Esto permite una comprobación de tipos en tiempo de compilación pero tiene como inconveniente la
rigidez, ya que las estructuras estáticas no pueden crecer o decrecer durante la ejecución del programa. Es
decir, se presentan problemas:

 cuando necesitamos utilizar estructuras muy grandes y no sabemos a priori la cantidad de


elementos que vamos a introducir en ella.
 cuando ya no utilizamos más una variable. El lugar sigue estando ocupado innecesariamente hasta
que finalice la ejecución del programa.

 Alocación Dinámica (heap) - variables dinámicas o referenciadas

Las estructuras dinámicas se caracterizan por permitir que la reserva de memoria se realice en tiempo de
ejecución. De esta forma se puede reservar y liberar posiciones de memoria según sea necesario durante la
ejecución del programa.

32
Algoritmos, Datos y Programas - 2010

 Tipo Puntero: es un tipo de variable usada para almacenar la dirección en memoria de otra variable, en
lugar de un dato convencional. Mediante la variable de tipo puntero se accede a esa otra variable,
almacenada en la dirección de memoria que señala el puntero. Es decir, el valor de la variable de tipo
puntero es una dirección de memoria. Se dice que el puntero apunta o señala a la variable almacenada en la
dirección de memoria que contiene el puntero. Lo que interesa es el dato contenido en esa variable
apuntada. No hay que confundir la variable apuntada con el puntero.

Los punteros pueden apuntar solamente a variables dinámicas, es decir, a datos que están almacenados en
memoria dinámica (heap). Cada variable de tipo puntero puede apuntar a un único tipo de dato.
Una variable de tipo puntero se indica con ^ y ocupa 4 byte de memoria (stack) para su representación
interna en Pascal.

DECLARACIÓN DE UN PUNTERO

Type nombre_tipo_puntero = ^Tipo_variable_apuntada;

Una variable de tipo puntero ocupa una cantidad de memoria fija (4 bytes), independiente del tipo de dato
al que apunta. Un dato referenciado o apuntado, no tienen memoria asignada, o lo que es lo mismo no
existe inicialmente espacio reservado en memoria para este dato. Para poder emplear variables dinámicas
es necesario emplear un tipo de dato que permita referenciar nuevas posiciones de memoria que no han
sido declaradas a priori y que se van a crear y destruir en tiempo de ejecución.

En Pascal la creación y destrucción de variables dinámicas se realiza mediante los siguientes procedimientos:

 new(var_tipo_puntero)
Adquiere la memoria necesaria para una variable dinámica.
Retorna la dirección de memoria en donde se guarda el dato del tipo apuntado. Es decir, el valor de la
variable de tipo puntero será una dirección de memoria.

 dispose(var_tipo_puntero)
Libera la memoria adquirida mediante el new().
Luego de liberar la memoria apuntada por el puntero, deja dicho puntero indefinido.

ASIGNACIÓN DE UN VALOR A UN PUNTERO

p:= q

(p y q deben ser del mismo tipo. Luego de la asignación p y p apuntan al mismo dato).

p:=nil

(asignación nula, P no apunta a ninguna dirección de memoria).

33
Algoritmos, Datos y Programas - 2010

ASIGNACIÓN DE VALOR AL OBJETO APUNTADO

p^:= 30;
(a lo que apunta el puntero p, se le asigna el valor 30)

p^:= q^
(punteros distintos apuntarán a objetos iguales, es decir, lo que apunta p tendrá el mismo valor de lo que
apunta q)

COMPARACIÓN

(p = q), (p <> q)
(se comparan, mediante relacionales, las direcciones de memoria)

ENTRADA/SALIDA

No se pueden leer y escribir punteros, pero sí es posible leer y escribir los objetos que ellos referencian
(dependiendo del tipo apuntado): writeln (p^);

 Tipo Lista: una lista enlazada es una colección de elementos homogéneos, con una relación lineal que los
vincula, es decir, que cada elemento tiene un predecesor (salvo el primero) y un sucesor (excepto el último).
Los elementos que componen una lista son los nodos (donde cada nodo está representado por un registro) y
tales elementos no ocupan posiciones secuenciales o contiguas de memoria. Es decir pueden aparecer
dispersos en la memoria, pero mantienen un orden lógico interno. Los nodos se conectan por medio de
enlaces o punteros. Cuando se necesita espacio adicional, nuevos nodos pueden ser alocados y agregados a
la estructura (con un New) y cuando existen nodos que ya no se necesitan, pueden ser borrados, liberando
memoria (con Dispose).

Es decir, una lista enlazada es una estructura dinámica, que permiten definir una estructura sin conocer a
priori la cantidad de datos a almacenar; liberando o reservando memoria según sea conveniente.

DECLARACIÓN DE UNA LISTA

Type
lista= ^nodo; {notar la naturaleza recursiva de
nodo= record la definición de una lista }
dato: tipo_dato;
sig: lista;
End;

Var
pri: lista; {memoria estática reservada}

34
Algoritmos, Datos y Programas - 2010

Lógicamente, una lista enlazada tiene la siguiente forma:

Puntero Dato Dato Dato Nil


inicial

Para saber dónde está el primer elemento de una lista, se guarda en una celda de memoria la dirección del
primer nodo. Esta celda apunta al principio de la lista y suele llamarse puntero inicial. Si se quiere leer la
lista, se comienza en la posición indicada por ese puntero y se halla el primer dato junto con un puntero al
siguiente nodo. Si se sigue ese puntero, se halla el segundo dato y así sucesivamente hasta el final de la lista.
Para detectar el final de la lista, se utiliza un puntero nulo (nil) que indica que no hay más nodos en la lista.

OPERACIONES CON LISTAS

 AGREGAR AL COMIENZO DE UNA LISTA

procedure agregar_comienzo (var pri:lista; n:integer);


var
nue:lista;
begin
new (nue);
nue^.dato := n;
nue^.sig := pri;
pri := nue;
end;

 AGREGAR AL FINAL DE UNA LISTA

procedure agregar_final (var pri: lista; n: integer);


var
act, nue, ant: lista;
begin
new (nue);
nue^.dato := n;
nue^.sig := nil;
if (pri = nil) then {es el primer elemento}
pri := nue
else begin {se busca el último elemento para enganchar}
act := pri;
while (act <> nil) do begin
ant := act;
act := act^.sig;
end;
ant^.sig := nue;
end;
end;

35
Algoritmos, Datos y Programas - 2010

 INSERTAR ORDENADO

procedure insertar_ordenado (var pri: lista; n: integer);


var
act, nue, ant: lista;
begin
new (nue);
nue^.dato := n;
nue^.sig := nil;
ant := pri;
act := pri;
while (act <> nil) and (n > act^.dato) do begin {busca posic.}
ant := act;
act := act^.sig;
end;
if (act = pri) then begin {lista vacia ó se inserta adelante}
nue^.sig := pri;
pri := nue
end
else begin {Se avanzó. Luego se inserta al medio o al final}
ant^.sig := nue;
nue^.sig := act;
end;
end;

 BORRAR UN ELEMENTO

procedure Borrar_elemento (var pri: lista; n:integer);


var
ant, act: lista;
begin
act := pri;
ant := pri;
while (act <> NIL) do begin
if (act^.dato = n) then begin
if (act = pri) then begin
pri := act^.sig;
ant := pri;
end
else
ant^.sig := act^.sig;
end
else
ant^.sig := act^.sig;
act := act^.sig;
end;
end;

36
Algoritmos, Datos y Programas - 2010

 BORRAR TODAS LAS INSTANCIAS

procedure borrar_instancias (var pri: lista; n:integer);


var
ant, act: lista;
begin
act := pri;
ant := pri;
while (act <> NIL) do begin
if (act^.dato = n) then begin
if (act = pri) then begin
pri := act^.sig;
ant := pri;
dispose (act);
act := pri
end
else begin
ant^.sig:=act^.sig;
dispose (act);
act := ant^.sig
end;
else begin
ant := act;
act := act^.sig;
end;
end;
end;
end;

 IMPRIMIR UNA LISTA

procedure imprimir (pri: lista);


begin
writeln ('---------- LISTADO ----------');
while (pri <> nil ) do begin
writeln ('Numero: ', pri^.dato);
pri := pri^.sig;
end;
end;

37
Algoritmos, Datos y Programas - 2010

 LOCALIZAR LA DIRECCIÓN DE UN ELEMENTO

procedure localizar_elem (var pri:lista; n: integer; var pos: lista);


var
act: lista;
begin
if (pri = nil) then {lista vacía}
writeln („ERROR‟);
else begin {ubicarse al principio de la lista}
act := pri;
while (act <> nil) and (n <> act^.dato) do {se avanza}
act := act^.sig;
if (act <> nil) and (n = act^.dato) then
pos := act {guarda la dirección}
else {se acabó la lista y no se encontró el elemento}
writeln („NO HALLADO‟)
end;
end;

 ACCEDER AL K -ÉSIMO ELEMENTO DE LA LISTA

procedure acceder_kesimo (var pri:lista; k:integer; var num: integer);


var
act: lista;
pos: integer;
begin
if (pri = nil) then
writeln („ERROR – La lista no contiene elem.‟)
else begin
pos := 1; {inicializa contador para las posiciones}
act := pri;
while (pos < k) and (act <> nil) do begin
pos := pos + 1;
act := act^.sig;
end;
if (pos = k) then begin
num:= act^.dato;
writeln („El número es: „,num);
end
else
writeln (k, „excede la longitud.‟);
end;
end;

38
Algoritmos, Datos y Programas - 2010

ARREGLOS Y LISTAS: ANÁLISIS COMPARATIVO

Los arreglos se almacenan en memoria estática. La ocupación de memoria de resuelve en tiempo de


compilación. Ocupan posiciones consecutivas de memoria.

Las listas se almacenan en memoria dinámica. La ocupación de memoria de resuelve en tiempo de


ejecución. Se disponen aleatoriamente en memoria. Se relacionan lógicamente.

 Espacio: se refiere a la cantidad de memoria consumida por una estructura de datos dada.

Los arreglos son más económicos.

Las listas requieren espacio extra para los enlaces.

 Tiempo: se refiere al tiempo que toma almacenar o recuperar datos.

En las Listas el acceso es secuencial, el tiempo para acceder a un ítem es proporcional a su posición en la
lista (porque cada nodo contiene la dirección del próximo). Es decir, el tiempo para localizar un ítem no es
constante en una lista.

En los arreglos, en cambio, el acceso es directo gracias a la variable índice. El tiempo para localizar un ítem
es siempre el mismo ya que:

dirección del elemento actual = dirección base + ( Offset * Índice )

39
Algoritmos, Datos y Programas - 2010

LISTAS CIRCULARES

Las listas circulares presentan la particularidad de que el último elemento de la lista en lugar de almacenar
un puntero nulo (nil), apunta al principio de la lista.

Puntero Dato Dato Dato


inicial

Luego, las listas circulares presenta la ventaja, respecto de las listas simples, que cada nodo de la lista es
accesible desde cualquier otro nodo de ella. Sin embargo, esto puede producir bucles o lazos infinitos
(porque ahora no habrá nodo que apunte a nil).

 BORRAR LA POSICIÓN P DE UNA LISTA CIRCULAR NO VACIA

Procedure suprime (var pri: listacircular; p: listacircular; var encontre:


boolean);
var
ant, act : listacircular;
begin
ant := pri;
act := pri;
encontre := false;
while (act <> p ) and (ant^.sig<> pri ) do begin
ant := act;
act := act^.sig;
end;
if (act = p ) then begin
encontre := true;
if (ant = act) then
if (act^.sig = act) then begin {la lista solo tiene 1 nodo}
pri := nil
dispose (act)
end
else begin
pri := ant^.sig;
act:= pri; {actualiza puntero sig del último nodo}
While (act^.sig <> p) do
act := act^.sig;
act^.sig:= pri;
dispose (ant)
end
else begin
ant^.sig := act^.sig;
dispose (act);
end
end;
end;

40
Algoritmos, Datos y Programas - 2010

LISTAS DOBLES (LISTAS CON DOBLE ENLACE)


Son listas enlazadas que tienen dos enlaces en lugar de uno, es decir, los nodos se encuentran enlazados a
otros dos nodos por medio de criterios diferentes. Esto implica que se pueda recorrer la lista en dos sentidos
(ordenes) diferentes (se tienen 2 “vistas” diferentes de los mismos datos).

VENTAJAS: pueden recorrerse de dos formas, ya sea para efectuar una operación con cada elemento o para
insertar/actualizar y borrar. No se utiliza espacio extra...

INCONVENIENTE: ocupan más memoria por nodo que una lista simple…

DECLARACIÓN

type
lista = ^nodo;
nodo = record
sig1: lista;
dato: ...;
sig2: lista;
end;

listadoble= record
orden1: lista;
orden2: lista;
end;
var
ld: listadoble;

41
Algoritmos, Datos y Programas - 2010

 EJEMPLO AGREGAR EN LISTA CON DOBLE ENLACE

type
alumno = record
apellido: string[30];
numero: integer;
dni: string[12];
end;

lista = ^nodo;
nodo = record
dato: alumno;
sig_ape: lista;
sig_num: lista;
end;

lista_doble = record
pri_ape: lista;
pri_num: lista;
end;

procedure agregar (var ld: lista_doble; a:alumno);


var
nue: lista;
begin
new (nue);
nue^.dato:=a;
nue ^.sig_ape := nil;
nue ^.sig_num := nil;
if (ld.pri_nom = nil ) then begin {La lista esta vacía?}
ld.pri_ape := nue;
ld.pri_num:= nue;
end
else begin {Como no esta vacía agrego por los 2 ordenes}
agregar_X_apellido(ld, nue);
agregar_X_numero(ld, nue);
end;
end;

42
Algoritmos, Datos y Programas - 2010

procedure agregar_X_apellido (var ld: lista_doble; nue:lista);


var
ant,act: lista;
begin
act:= ld.pri_ape;
while (act <> nil) and (nue^.dato.apellido > act^.dato.apellido) do
begin
ant:= act;
act:= act^.sig_ape;
end;
if (act = ld.pri_ape) then begin {Inserto primero}
nue^.sig_ape:= ld.pri_ape;
ld.pri_ape := nue;
end
else begin {Es al medio o al final}
ant^.sig_ape := nue;
nue^.sig_ape := act;
end;
end;

procedure agregar_X_numero (var ld: lista_doble; nue:lista);


var
ant,act: lista;
begin
act:= ld.pri_num;
while (act <> nil) and (nue^.dato.numero > act^.dato.numero) do begin
ant:= act;
act:= act^.sig_num;
end;
if (act = ld.pri_num) then begin {Inserto primero}
nue^.sig_num:= ld.pri_num;
ld.pri_num := nue;
end
else begin {Es al medio o al final}
ant^.sig_num := nue;
nue^.sig_num := act;
end;
end;

43
Algoritmos, Datos y Programas - 2010

LISTAS DOBLEMENTE ENLAZADAS


Son listas que tienen dos enlaces. Cada enlace recorre la lista en un orden considerando el mismo criterio.
Una posibilidad es que se enganchen para realizar un recorrido de la lista ordenada en forma ascendente y
descendente por algún criterio.

VENTAJAS: pueden recorrerse de dos formas, ya sea para efectuar una operación con cada elemento o para
insertar/actualizar y borrar.

INCONVENIENTE: ocupan más memoria por nodo que una lista simple.

DECLARACIÓN

type
puntero = ^nodo;
nodo = record
ant: puntero;
info: .....;
sig: puntero;
end;
listaDoble = record
pri: puntero;
ult: puntero;
end;
var
l : listaDoble;

44
Algoritmos, Datos y Programas - 2010

 EJEMPLO INSERTAR ORDENADO EN LISTA DOBLEMENTE ENLAZADA

procedure InsertaOrdenado ( l: listaDoble; x: char);


var
act, nue : nodo;
begin
new (nue);
nue^.info := x;
nue^.sig := nil;
nue^.ant := nil;
if (l.pri = nil) then begin
l.pri := nue;
l.ult := nue;
end
else begin
act:= l.pri;
while (act <> nil) and (x > act^.info) do
act:= act^.sig;
if (act = l.pri) then begin
nue^.sig := l.pri;
l.pri^.ant := nue;
l.pri := nue;
end
else
if (act <> nil) then begin
nue^.ant := act^.ant;
act^.ant^.sig := nue;
nue^.sig := act;
act^.ant := nue;
end
else begin
nue^.ant := l.ult;
l.ult^.sig := nue;
l.ult := nue;
end;
end;
end;

LISTAS CON MÚLTIPLES ENLACES


Son listas cuyos nodos están enlazados por diferentes criterios.

VENTAJAS: pueden recorrerse siguiendo diferentes enlaces, lo que permite vistas diferentes de la misma
información.

INCONVENIENTE: ocupan más memoria por nodo.

45
Algoritmos, Datos y Programas - 2010

MERGE DE LISTAS

 EJEMPLO 1: Se tienen dos listas creadas de manera ordenada. Se implementa un algoritmo que combina
ambas listas y genera una tercera lista ordenada. Ambas listas están ordenadas por el mismo criterio. La lista
nueva también es generada ordenada por el mismo criterio.


begin
crearListaOrdenada (l1);
crearListaordenada (l2);
l3:= nil;
merge (l1, l2, l3);
end.

procedure merge (l1,l2: lista; var l3:lista);


var
min : integer;
begin
minimo(l1, l2, min);
while (min <> 999) do begin
insertarAtras (l3, min);
minimo (l1, l2, min);
end;
end;

procedure minimo (var l1:lista; var l2: lista; var min:integer);


begin
if (l1 = nil) and (l2=nil) then
min:=999
else
if (l1<> nil) and (l2<> nil) then
if (l1^.datos <= l2^.datos) then begin
min := l1^.datos;
l1 := l1^.sig;
end
else begin
min := l2^.datos;
l2 := l2^.sig;
end
else
if (l1 <> nil) and (l2 = nil) then begin
min := l1^.datos;
l1 := l1^.sig;
end
else begin
min := l2^.datos;
l2 := l2^.sig
end;
end;

46
Algoritmos, Datos y Programas - 2010

 EJEMPLO 2: Se disponen de dos listas que contienen información de las ventas realizadas por c/u de las 2
sucursales de un supermercado. De cada venta se conoce: el código de producto y la cantidad vendida.
Se realiza un módulo que procesa los datos (recorriendo solo una vez las listas) y genera una nueva lista
ordenada por cod. de producto que contiene cada producto vendido y la cantidad total vendida.

type
venta = record
cod_pro: integer;
cant_vend: integer;
end;
lis_ventas = ^nodo_ven;

nodo_ven = record
ven: venta;
sig: lis_ventas;
end;
lis_totales = ^nodo_tot;
nodo_tot = record
cod_prod: integer;
cant_tot: real;
sig: lis_totales;
end;

procedure totalizar(lista1, lista2: lis_ventas; var tot: lis_totales);


var
min: venta;
prod_actual, total_prod : integer;
ult : lis_totales;
L1,l2: lis_ventas;
begin
tot := nil;
l1:= lista1;
l2:= lista2;
minimo (l1, l2, min);
while (min.cod_pro<>999) do begin {mientras listas no vacías}
prod_actual := min.cod_prod;
total_prod := 0;
while (prod_actual=min.cod_prod) do begin {mientras mínimo no
cambia, acumulo las ventas del mismo prod.}
total_prod := total_prod + min.cant_vend;
minimo (l1, l2, min);
end;
insertar_atras(tot, ult, prod_act, total_prod); {Cuando el
mínimo cambia guardo en la lista nueva el producto acumulado}
end;
end;

47
Algoritmos, Datos y Programas - 2010

procedure minimo (Var l1:lista; var l2: lista; var min:venta);


begin
if (l1 = nil) and (l2=nil) then min:=999
else
if (l1<> nil) and (l2<> nil) then
if (l1^.datos <= l2^.datos) then begin
min:= l1^.ven;
l1:= l1^.sig;
end
else begin
min:= l2^.ven;
l2:= l2^.sig;
end
else
if (l1 <> nil) and (l2 = nil) then begin
min:= l1^.ven;
l1:= l1^.sig;
end
else begin
min:= l2^.ven;
l2:= l2^.sig
end;
end;

procedure insertar_atras (var pri, ult: lis_totales; prod, cant: integer);


var
nue: lis_totales;
begin
new (nue);
nue^sig := nil;
nue^.cod_prod := prod;
nue^.cant_tot := cant;
if (pri = nil) then {La lista esta vacía?}
pri := nue; {NUE es el primero}
else
ult^.sig := nue; {El ultimo ahora tiene como sig. al nuevo
ultimo}
ult := nue; {El ultimo es el que acabo de agregar}
end;

48

Você também pode gostar