0% encontró este documento útil (0 votos)
13 vistas110 páginas

Estructuras Lineales de Datos

Descargar como pptx, pdf o txt
Descargar como pptx, pdf o txt
Descargar como pptx, pdf o txt
Está en la página 1/ 110

Fundamentos de Programación II

Tema 3. Estructuras lineales de datos:


listas, pilas, colas

Luís Rodríguez Baena (luis.rodriguez@upsam.net)

Universidad Pontificia de Salamanca (campus Madrid)


Escuela Superior de Ingeniería y Arquitectura
Tipos abstractos de datos

Procedimientos y funciones generalizan el concepto de operador.


● El programador puede definir sus propios operadores y aplicarlos sobre
operandos de tipos no definidos en el lenguaje.
En un algoritmo en lugar de utilizar sólo los operadores que utiliza el lenguaje, tipos
mediante procedimientos y funciones se pueden aplicar sus propios operandos a
de datos no definidos por el lenguaje.
o Por ejemplo, se puede ampliar el operador de multiplicación para multiplicar
matrices.
● Procedimientos y funciones encapsulan las operaciones, las aíslan del
cuerpo del algoritmo.
Tipo Abstracto de Datos (TAD).
● Amplía el concepto de procedimiento a la definición de datos.
● Modelo matemático del dato junto con las operaciones que se pueden
definir sobre él.
● Utilizan también generalización y encapsulamiento.
Son generalizaciones de los tipos de datos primitivos.
Facilitan la localización de la definición del tipo y de las operaciones para su
manejo.

Universidad Pontificia de Salamanca (Campus Madrid)


2
Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012
Tipos abstractos de datos (II)

Por ejemplo, seÁrea(c)


operaciones puede definir el tipo de datos Cuadrado
y Perímetro(c)que y las
devolverían el
valor del área y del perímetro del cuadrado c.
El cuadrado se puede implementar de distintas formas:
● Con la posición de los cuatro vértices en las coordenadas de un
plano.
registro=punto
real : x,y
fin_registro
registro=cuadr
ado
punto:
infIzq,
infDer,
supIzq, supDer
fin_registro
● Con la posición de un
punto y el tamaño del lado.
registro=cuadrado
punto:origen 3
real: lado
fin_registro
Tipos abstractos de datos (III)

El procedimiento área podría implementarse de distintas formas


dependiendo de cómo se haya definido el cuadrado.
real función Área(valor cuadrado: c)
inicio
devolver(c.lado * c.lado)
fin_función

real función Área(valor cuadrado: c)


var
real : lado
inicio
//lado es la distancia entre dos puntos
lado raiz2((c.infIzq.x – infDer.x)**2+(c.infIzq.y –
infDer.y)**2)
devolver(lado * lado)
fin_función
● Si en un programa utilizamos el tipo de datos Cuadrado y tenemos definidas
en ese tipo de dato la función Área, la llamada a la función será Area(c),
independientemente de la implementación que hayamos hecho.

4
Universidad Pontificia de Salamanca (Campus Madrid)
Luis Rodríguez Baena, Escuela Superior de Ingeniería y
Arquitectura, 2012
Tipos abstractos de datos (IV)

Estructuras de datos “físicas” y “lógicas”.


● Podemos considerar que una estructura de datos física es la
queimplementa el lenguaje de programación que se está utilizando.

● implementa el lenguaje
Una estructura y que sería
de datos lógica creamos
una aestructura
partir de de
los datos
tipos que
de no
datos
y
las estructuras de datos físicas que proporciona el lenguaje.
● Este concepto puede variar de un lenguaje a otro:
Conjunto: presente en Pascal y no presente en C.
Cadena: presente en Java, pero no presente en Pascal estándar.
Archivos indexados: presente en Cobol y no presente en C.
Las estaban definidas
estructuras por que
de datos el lenguaje
se han de especificación
utilizado de ya
hasta ahora
algoritmos utilizado (son estructuras de datos “físicas”).
● El necesarias para el
lenguaje define declarar un array,
tipo array acceder
e incluye a un elemento, etc.
las herramientas

5
Universidad Pontificia de Salamanca (Campus Madrid)
Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012
Tipos abstractos de datos (V)

Los lenguajes no soportan todas las estructuras de datos


posibles.
● En muchas ocasiones es necesario realizar la definición de la
estructura de datos y declarar las operaciones primitivas que la
manejan.
Haremos la definición del Tipo Abstracto de Datos.
o Definir el tipo de dato que contendrán.
o Establecer la organización de los datos utilizando los datos primitivos.
o Establecer las operaciones primitivas para manejar el tipo de dato.
Las estructuras de datos utilizadas en este tema (pilas, colas,
listas enlazadas) no están implementadas en el lenguaje de
programación.
● Será necesario definirlas con las estructuras de datos disponibles.
● Será necesario implementar las operaciones primitivas para
manejarlas.

Universidad Pontificia de Salamanca (Campus Madrid)


Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012 6
Datos estáticos y dinámicos

Dato estático.
● Dato que no puede variar su ubicación a lo
largo de la ejecución del programa.
● Se reserva espacio en tiempo de
(Pila) (Pila)
compilación.
Memoria estática Memoria estática

es necesario saber de antemano su a a 5


Cuando el programa empieza su ejecución

tamaño y ubicación en la memoria.


● Se almacena en una zona de memoria
estática: pila.
● El dato se identifica por una variable que no
es más que una dirección de memoria
dónde está almacenada la información.
● Cuando se asigna un valor a ese dato, se
almacena directamente en esa dirección de
memoria.
entero: a a 5
● Cuando se accede a ese dato, por ejemplo
al ejecutar la instrucción escribir(a), se
accede de forma directa al contenido de esa
dirección de memoria.
7

Universidad Pontificia de Salamanca (Campus Madrid)


Datos estáticos y dinámicos (II)

Dato dinámico.
● Realiza una asignación dinámica de memoria.
Reserva espacio para almacenar la información en tiempo de ejecución.
● Cuando el programa comienza su ejecución, sólo se reserva espacio para
almacenar una referencia a la posición donde se almacenará el dato, no
para almacenar el dato en sí.
La variable que guarda la dirección de memoria (la referencia) es el
puntero.
El puntero se almacena en la pila.
● Durante la ejecución del programa es posible reservar memoria
para el dato al que apunta el puntero.
El dato en sí se almacena en una zona de memoria dinámica: el
montículo.
● En cualquier momento se puede reservar o liberar ese espacio.

Universidad Pontificia de Salamanca (Campus Madrid)


Luis Rodríguez Baena, Escuela Superior de Ingeniería y 8
Arquitectura, 2012
Datos estáticos y dinámicos (III)

Definición de un puntero.
puntero_a tipoDato : varPuntero
● tipoDato, cualquier tipo de dato
Memoria estática
estándar o definido por el usuario. (Pila)
● Al arrancar el programa la variable de
a 5
tipo puntero no está inicializada (no
tiene ningún valor). pt
r1
Datos estáticos y dinámicos (IV)

Reservar espacio en el montículo.


reservar(varPuntero)
● Busca espacio en memoria para almacenar una variable del tipo de
varPuntero.
● varPuntero se carga con la dirección de memoria que se ha encontrado.
Referencia al dato apuntado por el puntero.
● Se utiliza el operador ↑.
varPuntero↑
● Si varPuntero hace referencia a la zona de memoria a la que apunta,
varPuntero↑ hace referencia al contenido de dicha zona de memoria.
● Hay que tener en cuenta que:
varPuntero es una variable de tipo puntero, por lo que sólo es posible asignarla
otro puntero (otra variable de tipo puntero, puntero nulo o reservar espacio).
o Los operadores de asignación o las instrucciones de lectura o escritura no funcionan de
la misma forma para variables de tipo puntero que para otro tipo de variables.
varPuntero↑ hace referencia al contenido de la memoria a la que apunta al
puntero, por lo que es un dato del tipo base del puntero.
o Sobre ella se podrán hacer todas las operaciones que se puedan hacer con el tipo base
del puntero.

Universidad Pontificia de Salamanca (Campus Madrid)


Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012 10
Datos estáticos y dinámicos (V)

Memoria estática Memoria dinámica


(Pila) (montículo)

a 5

pt
r1
pt
r2
Datos estáticos y dinámicos (VI)

Asignación de variables de tipo


puntero.
● Lo que asigna no es el
contenido, sino la dirección de
memoria, la referencia.
Comparación de variables de
Datos estáticos y dinámicos (VII)

Liberar espacio de
almacenamiento.
liberar(varPuntero)
● Deja libre la posición de
memoria, volviéndola a
marcar como zona libre.
Estructuras de datos dinámicas

Sus componentes están dispersos por la memoria.


● Al no ocupar posiciones contiguas es necesario establecer un
mecanismo para acceder al siguiente elemento de la estructura.
● Es necesario saber cuál es el primer elemento de la estructura
Cada elemento de la estructura es un nodo.
● Cada nodo contiene la información y, por lo menos, un puntero
indicando cual es el siguiente elemento de la estructura.

● Existe una variable de tipo puntero que apunta al primer nodo de la


estructura.

Universidad Pontificia de Salamanca (Campus Madrid)


14
Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012
Estructuras de datos lineales y no
lineales

Estructuras de datos lineales.


● Cada componente tiene un único sucesor y un único predecesor con
excepción del último y el primero.
Estructura de datos no lineal.
● Cada componente puede tener varios sucesores y varios predecesores.

Universidad Pontificia de Salamanca (Campus Madrid)


15
Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012
Estructuras de datos lineales: listas

Estructura lineal compuesta por una secuencia de 0 o más


elementos de algún tipo determinado y ordenados de
alguna forma.
Puede crecer o disminuir en el número de elementos y
podrán insertarse o eliminarse elementos en cualquier
posición sin alterar su orden lógico.

Universidad Pontificia de Salamanca (Campus Madrid)


16
Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012
Estructuras de datos lineales: listas (II)

Listas contiguas.
● Los elementos ocupan posiciones contiguas de memoria.
● Se pueden implementar con arrays.
Los elementos ocuparían posiciones correlativas del array.
Presentan dos problemas:
o La inserción o el borrado de elementos implica mover las posiciones
para mantener el orden original.
o El número de elementos de la lista se puede modificar, pero no puede
sobrepasar el tamaño máximo del array.

Universidad Pontificia de Salamanca (Campus Madrid)


Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012 17
Estructuras de datos lineales: listas (III)

array[1..8] de cadena : v
V V
1 ANA 1
ANA
2 CARLOS 2
CARLOS
3 DANIEL 3 DANIEL
está lleno
Error, no se puede
4 JUANA insertar(v,’PEPE’,n) 4 JUANA
insertar(v,’CARMEN’,n) insertar porque el array

5 MANOLO 5
MANOLO
6 PEPA 6
PEPA
7 RAU n=7 7 PEP
8 8
RAUL n=8

V V
1 ANA 1
ANA
2 CARLOS 2
CARLOS
3 DANIEL 3
DANIEL
4 JUANA borrar(v,5,n) 4 JUANA
18
5 MANOLO 5
PEPA
Estructuras de datos lineales: listas (IV)

Listas enlazadas.
● Los elementos no ocupan posiciones contiguas de memoria.
Aparecen dispersos por el almacenamiento.
● Cada elemento contiene una referencia al siguiente elemento de la
estructura.
● El orden lógico lo darán los enlaces que hay entre elementos.
● El primer elemento en el orden lógico no tiene por qué
corresponderse con el primer elemento almacenado.
El necesario indicar cuál es el primer elemento en el orden lógico.
● También es necesario indicar cual será el último elemento en el
orden lógico de la estructura.
● La inserción o eliminación de elementos no implica mover los
elementos de sitio.
Sólo se modifican las referencias al siguiente elemento.
● Si se utilizan estructuras de datos dinámicas el número de
elementos será virtualmente ilimitado.

Universidad Pontificia de Salamanca (Campus Madrid)


Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012 19
Estructuras de datos lineales: listas (V)

Implementación mediante arrays de registros…


Pilas

Es un tipo especial de lista.


Estructura lineal de datos compuesta por una secuencia de
elementos en la que las operaciones sólo se pueden realizar por uno
de sus extremos llamado cima (tope o top).
● Estructuras de tipo LIFO (Last In-First Out).
Se utiliza para poder recuperar elementos en
entran.
orden inverso a como

● Ejemplos reales: montones de platos.


● Aplicaciones en informática.
Evaluación de algunos tipos de expresiones
Cuadros de diálogos, pantallas y menús desplegables.
que secuadro
o Cada ha abierto.
se abre encima de otro; al cerrarse
uno, el cuadro activo es el último

Simulación de la recursividad.
…orden inverso a como ha entrado.
En general, cualquier aplicación en la que se necesite
recuperar información en

22
Pilas (II)
Pilas (III)

La estructura de tipo Pila no se considera implementada en


nuestro lenguaje de programación.
● En otros lenguajes, como .NET, existe la clase Stack (pila en inglés)
que implementa pilas e incluye todas las operaciones que se
pueden hacer sobre las pilas.
Será necesario crear el tipo de dato Pila.
● Determinar las operaciones básicas que se pueden realizar sobre el tipo
de dato Pila: las operaciones primitivas.
● Definir el tipo de elementos que contendrá la pila.
● Definir la organización de los datos utilizando los datos y
estructuras de datos que ofrezca el lenguaje de programación.
● Implementar las operaciones primitivas para la organización de los
datos definida.
Dependiendo de la organización definida, la implementación de las
operaciones primitivas variará.

Universidad Pontificia de Salamanca (Campus Madrid)


24
Luis Rodríguez Baena, Escuela Superior de Ingeniería y
Arquitectura, 2012
Pilas (IV)

Operaciones primitivas.
● Procedimiento PilaNueva(ref pila: p)
Crea un pila sin elementos.
● Función lógica EsPilaVacía(valor pila: p).
Devuelve verdad si la pila está vacía.
● Procedimiento PInsertar (ref pila:p; valor TipoElemento:e)
o Push(ref pila : p; valor TipoElemento: e).
Inserta un elemento e en la pila y devuelve la pila resultante.
TipoElemento es un tipo de dato genérico que se corresponde al tipo de dato
de los elementos que contendrá la pila.
● Procedimiento Cima(valor pila: p; ref TipoElemento : e).
Devuelve en el argumento e el elemento situado en la cima de la pila.
● Procedimiento PBorrar(ref pila : p).
Elimina el elemento cima de la pila y devuelve la pila resultante.
● Procedimiento Pop(ref pila : p; ref TipoElemento : e) o
Sacar(ref pila : p; ref TipoElemento : e).
Elimina un elemento de la cima de la pila, devolviendo la pila resultante y el
elemento extraído.

Universidad Pontificia de Salamanca (Campus Madrid)


Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012 25
Realizaciones mediante arrays

Las pilas se pueden implementar utilizando estructuras de datos dinámicas


(listas enlazadas) o estáticas (arrays).
● La pila está definida por la posición dónde está el último elemento (la cima).
Este dato es lo único que necesitamos para trabajar con pilas.
● Si se implementa con un array, también es necesario determinar dónde se almacenará la
información (el array el).
Como se trata de estructuras de datos estáticas, debemos definir también el tamaño máximo del array
(MaxPila).
● Además el tipo de dato TipoElemento definirá el tipo de elementos que almacenará la
pila.
Definición de las estructuras de datos. MaxPila

const
MaxPila = …
tipos
… = TipoElemento
registro = Pila cima

entero : cima
array[1..MaxPila] de TipoElemento : el
fin_registro el

Pila
Universidad Pontificia de Salamanca (Campus Madrid)
Luis Rodríguez Baena, Escuela Superior de Ingeniería y 26
Arquitectura, 2012
Realizaciones mediante arrays (II)

Procedimiento PilaNueva.
● Se limita a inicializar la cima de la pila a 0.
Función EsPilaVacía,
● Devuelve verdad si la pila está vacía.

procedimiento PilaNueva(ref pila : p)


inicio
p.cima 0
fin_procedimiento

lógico: función EsPilaVacía(valor pila :p) cima = 0


inicio
devolver(p.cima = 0)
fin_función
p

PilaNueva(p)
EsPilaVacía(p) //Devuelve verdad

Universidad Pontificia de Salamanca (Campus Madrid)


Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012 27
Realizaciones mediante arrays (III)

Procedimiento PInsertar
● Inserta en la posición cima
un elemento de
TipoElemento.
● En la implementación con arrays, es necesario comprobar si la pila está
llena (si cima=MaxPila).

procedimiento PInsertar(ref pila:p;


valor TipoElemento:e)
inicio
sisi_no
p.cima = MaxPila entonces 120
ANA
// p.cima
Error, la p.cima + 1
pila está
llena MANOLO
LUIS cima
fin_si p
3

p.el[p.cima] e MANOLO

fin_procedimiento Pinsertar(p,’MANOLO’)
Pinsertar(p,’ANA’)
Pinsertar(p,’LUIS’) 28
Realizaciones mediante arrays (IV)

Procedimiento Cima
● Devuelve el dato de TipoElemento situado en la posición cima.
● Es necesario comprobar si la pila contiene elementos (si cima <> 0).

procedimiento Cima(valor pila : p ;


ref TipoElemento : e)
inicio
si p.cima = 0 entonces
// Error la pila está vacía
si_no
LUIS cima
e 3
p.el[p.cima] ANA
fin_procedimiento MANOLO
fin_si
p
Cima(p,nombre)
escribir(nombre)
//Escribe
‘LUIS’

Universidad Pontificia de Salamanca (Campus Madrid) 29


Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012
Realizaciones mediante arrays (V)

Procedimiento PBorrar
● Elimina el elemento cima de la pila
● Es necesario comprobar si la pila contiene elementos (si cima <> 0).

procedimiento PBorrar(ref pila : p)


inicio
si EsPilaVacía(p) entonces LUIS cima
LUIS
// Error la pila está vacía 21
ANA
ANA
si_no
p.cima p.cima - 1 MANOLO
MANOLO
fin_si p
fin_procedimiento PBorrar(p)
PBorrar(p)

Universidad Pontificia de Salamanca (Campus Madrid)


Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012 30
Realizaciones mediante arrays (VI)

Procedimiento Pop (Sacar)


● Elimina y devuelve el elemento de TipoElemento situado en la cima
de la pila.
● Es necesario comprobar si la pila contiene elementos (si cima <> 0).

procedimiento Pop(ref pila:p; ref TipoElemento:e)


inicio
si EsPilaVacía(p) entonces LUIS cima
// Error la pila está vacía 0
ANA
si_no
e p.el[p.cima] MANOLO
p.cima p.cima - 1 p
fin_si Pop(p,nombre)
fin_procedimiento escribir(nombre)
//escribe ‘MANOLO’

Universidad Pontificia de Salamanca (Campus Madrid)


Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012 31
Realización mediante una lista
enlazada

La pila se considera un conjunto de nodos almacenados de forma dinámica.


Cada elemento del nodo contiene la información (de tipo TipoElemento)
y un puntero al siguiente elemento.

La pila está definida por la posición del primer elemento que será por
Realización mediante una lista
enlazada (II)

Procedimiento PilaNueva

procedimiento PilaNueva(ref pila : p)


inicio
p nulo
fin_procedimiento
Realización mediante una lista enlazada
(III)

Procedimiento PInsertar
● No es necesario comprobar si hay espacio suficiente para
elemento.
almacenar el
Se supone que en el montículo (memoria dinámica) siempre habrá
espacio.

procedimiento PInsertar(ref pila : p ; valor


TipoElemento : e)
var
aux↑.sig
pila : aux p
inicio
reservar(aux)

aux↑.info
e p aux
fin_procedimiento

34
Realización mediante una lista
enlazada (IV)
PInsertar(p,’MANOLO’)
PInsertar(p,’ANA’)

reservar(aux)
Realización mediante una lista enlazada
(V)

Procedimiento Cima
● Es necesario comprobar si la pila tiene elementos (p <>
nulo)

procedimiento Cima(valor pila : p ; ref TipoElemento : e)


inicio
si p = nulo entonces
// Error, la pila está vacía
si_no e p↑.info

fin_si
fin_procedimiento

36
Universidad Pontificia de Salamanca (Campus
Madrid)
Luis Rodríguez Baena, Escuela Superior de
Realización mediante una lista
enlazada (VI)

Procedimiento PBorrar PBorrar(p)

● Es necesario comprobar si la
pila tiene elementos (p <>
nulo)

aux p
procedimiento PBorrar( ref pila : p)
Realización mediante una lista enlazada
(VII)

Procedimiento Pop (Sacar).


● Es necesario comprobar si la pila tiene elementos (p <>
nulo)

procedimiento Pop( ref pila : p ; ref TipoElemento: e)


var
pila : aux
inicio
si EsPilaVacía(p) entonces
// error, la pila está vacía
e
si_no p↑.info

aux p
p p↑.sig
liberar(aux)
fin_si
fin_procedimiento

38
Universidad Pontificia de Salamanca (Campus
Madrid)
Luis Rodríguez Baena, Escuela Superior de
Realización mediante una lista
enlazada (VIII)
Ejemplo 3.1

Utilizando las operaciones primitivas para trabajar con pilas, diseñe


un procedimiento que devuelva una copia de una pila ya creada.
● Es necesario utilizar una pila auxiliar para copiar los elementos en el mismo
orden que la pila original.

Universidad Pontificia de Salamanca (Campus Madrid)


40
Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012
Ejemplo 3.1 (II)

Versión iterativa.

procedimiento CopiarPila(ref pila : p,copia)


var
TipoElemento : e
Pila : aux
inicio
//Copia los elementos en orden inverso en una pila auxiliar
PilaNueva(aux)
mientras no EsPilaVacia(p) hacer
Pop(p,e)
PInsertar(aux,e)
fin_mientras
//Restaura los
elementos en la
pila copia
PilaNueva(copia)
mientras no
EsPilaVacía(aux)
hacer
Pop(aux,e)
PInsertar(copia,e)
PInsertar(p,e) //
Hay que resturar
la pila original
porque se ha
vaciado 41
fin_mientras
fin_procedimiento
Ejemplo 3.1 (III)

Versión recursiva.
procedimiento CopiarPila(ref pila
: p,copia)
var
TipoElemento : e
inicio
//Si p está vacía estaríamos
en el caso trivial
//Si p está vacía, la copia
también es una pila vacía
si EsPilaVacía(p) entonces
PilaNueva(copia)
si_no Pop(p,e)
CopiarPila(p,copia)
PInsertar(copia,e)
Pinsertar(p,e)
fin_si
fin_procedimiento

42

Universidad Pontificia de Salamanca (Campus


Madrid)
Ejercicios con pilas

1. Diseñe un procedimiento que permita eliminar el elemento n de una


pila dejando los restantes elementos tal y como estaban.
2. Diseñe un procedimiento que permita buscar y eliminar un elemento
de una pila dejando los restantes elementos tal y como estaban.
3. Realizar una función que devuelva el mayor de una pila de enteros.
4. Realizar un algoritmo que lea un archivo de texto y lo devuelva en
otro archivo de texto con las palabras en orden inverso. Se supone que
en el texto cada palabra está separada por un único espacio en blanco,
con excepción de la última palabra.
5. Realizar un procedimiento QuickSort iterativo.

Universidad Pontificia de Salamanca (Campus Madrid)


Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012

43
Colas

Estructura lineal de datos compuesta por un conjunto de elementos en la


que la adición de nuevos elementos se hará por un extremo de la cola,
final (rear), y la salida de elementos por el contrario, principio (front).
Estructura de datos de tipo FIFO (first in-first out), es decir el
primer elemento en entrar es el primero en salir.
En aplicaciones informáticas se utiliza para controlar procesos que
tengan que realizarse en un cierto orden (colas de impresión, colas de
prioridades, etc.)

principio final
e0 e1 e2 e3 e4 e5 e6 e7

Universidad Pontificia de Salamanca (Campus Madrid)


Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012

44
Colas (II)

La estructura de tipo Cola no se considera implementada en


nuestro lenguaje de programación.
● En otros lenguajes, como .NET, existe la clase Queue (cola en
inglés) que implementa colas e incluye todas las operaciones que se
pueden hacer sobre las colas.
Será necesario crear el tipo de dato Cola.
● Determinar las operaciones básicas que se pueden realizar sobre el tipo
de dato Cola: las operaciones primitivas.
● Definir el tipo de elementos que contendrá la cola.
● Definir la organización de los datos utilizando los datos y
estructuras de datos que ofrezca el lenguaje de programación.
● Implementar las operaciones primitivas para la organización de los
datos definida.
Dependiendo de la organización definida, la implementación de las
operaciones primitivas variará.

Universidad Pontificia de Salamanca (Campus Madrid)


45
Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012
Colas (III)

Operaciones
primitivas.

ColaNueva(re
f cola: c),
inicializa una
nueva cola.
● EsColaVacía(valor cola :c), una función lógica que
devuelve verdad si la cola está vacía.
● CInsertar(ref cola : c; valor tipoElemento: e),
inserta un elemento de tipo TipoElemento en la cola en la
posición final.
● CBorrar(ref cola : c), elimina el elemento principio
de la cola.
● Primero(valor cola : c; ref tipoElemento : e),
obtiene el valor del elemento situado en la posición principio
46
de la cola.
● Sacar(ref cola : c; ref tipoElemento : e), elimina
Realizaciones mediante arrays

Declaración de las estructuras de datos.


● Para implementar una cola es necesario saber cuál es el primer elemento que se
ha introducido y cuál es el último.
Se tratará de los enteros p y f.

● Si se implementa como un array, es necesario también determinar dónde se


almacenarán los elementos.
Se trata del array de elementos el.
o El tipo base del array es el tipo de dato genérico TipoElemento.
o El array tiene un tamaño de MáxCola elementos.

const
MaxCola = …
tipos
… = TipoElemento
registro = cola
entero : p,f
array[1..MaxCola] de TipoElemento : el
fin_registro

Universidad Pontificia de Salamanca (Campus Madrid)


47
Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012
Realizaciones mediante arrays (II)

ColaNueva(c)
Realizaciones mediante arrays (III)

Con esta implementación es posible que no se pueda insertar porque el


puntero f ha llegado al último elemento del array y que, sin embargo,
todavía quede sitio.
Puede haber varias soluciones…
● Mover todos los elementos hacia adelante cada vez que de borra un
elemento.
Siempre se eliminaría el elemento 1 y el primer elemento siempre sería la
posición 1.
● Crear un array circular.
El siguiente elemento a la posición MaxCola es el elemento 1.
o Si hay sitio, al llegar al final del array se seguiría insertando por el elemento 1.

Universidad Pontificia de Salamanca (Campus Madrid)


Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012 49
Realización mediante una lista
enlazada

La cola se considera un conjunto de nodos almacenados de forma


dinámica (una lista enlazada).
Cada elemento del nodo contiene la información (de tipo
TipoElemento) y un puntero al siguiente elemento.
La cola estará compuesta por las direcciones del primer nodo de la
estructura (principio) y el último nodo de la estructura (final).
● El dato que define la cola es un registro formado por esos dos punteros.

tipos
… = TipoElemento
registro : cola
puntero_a nodo : p,f
fin_registro
registro = nodo
TipoElement info
o : : sig
puntero_a
nodo
fin_registro
Universidad Pontificia de Salamanca (Campus Madrid)
50
Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012
Realización mediante una lista enlazada
(II)

Procedimiento ColaNueva.
procedimiento ColaNueva(ref cola : c)
inicio c
c.p nulo p f
//c.f nulo //No sería necesario
fin_procedimiento ColaNueva(c)
EsColaVací (c)
Función EsColaVacía. //Devuelve verdad
lógico: función EsColaVacía(valor cola : c)
inicio
devolver(c.p = nulo) //o (c.f = nulo)
fin_función

Universidad Pontificia de Salamanca (Campus Madrid)


51
Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012
Realización mediante una lista enlazada
(III)

Procedimiento CInsertar
● No es necesario
comprobar si hay espacio
suficiente para almacenar el
elemento.
Se supone que, con
estructuras dinámicas,
el espacio es ilimitado
● Hay que comprobar si
es el primer elemento de la
cola.
Si es cierto, el frente
de la cola también
debe apuntar a esee
aux↑.info
elemento.
Si no, el último
elemento deberá
apuntar al nuevo
elemento.

procedimiento
CInsertar(ref cola :
c ; valor 52
TipoElemento : e)
var
Realización mediante una lista
enlazada (IV)
CInsertar(c,’LUIS’)

c
p f

reservar(aux) reservar(aux)

aux
Realización mediante una lista enlazada
(V)

Procedimiento Primero
● Es necesario comprobar si la pila tiene elementos (c.p <>
nulo)

procedimiento Primero(valor cola : c; ref TipoElemento : e)


inicio
si c.p = nulo entonces
// Error, la cola está vacía
e c.p↑.info
si_no

fin_si
fin_procedimiento

54
Universidad Pontificia de Salamanca (Campus
Madrid)
Luis Rodríguez Baena, Escuela Superior de
Realización mediante una lista
enlazada (VI)
CBorrar(c)
Procedimiento CBorrar

procedimiento CBorrar(ref cola : c)


aux c.p
var
puntero_a nodo : aux
inicio
si c.p = nulo entonces
Realización mediante una lista enlazada
(VII)

Procedimiento Sacar.
● Combina los procedimientos CBorrar y Primero.

procedimiento Sacar(ref cola : c ; ref TipoElemento : e)


var
puntero_a nodo : aux
inicio
si c.p = nulo entonces
// Error, la cola está vacía
si_no
e c.p↑.info
aux c.p
c.p c.p↑.sig
liberar(aux)
fin_procedimiento

Universidad Pontificia de Salamanca (Campus Madrid)


Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012 56
Realización mediante una lista
enlazada (VIII)
Sacar(c,e)

c
p f

e c.p↑.info ANA c.p c.p↑.sig

e
Ejemplo 3.2

Utilizando una pila y una cola, realizar una función que


reciba una cadena y devuelva el valor lógico verdad, si es
un palíndromo.
● Si se meten todos los caracteres de la cadena al mismo tiempo en
una pila y en una cola, al sacarlos de las dos estructuras de datos
saldrán en orden inverso: los caracteres de la cola saldrán del
primero al último, los de la pila del último al primero. Si todos los
caracteres son iguales, se tratará de un palíndromo.
La función longitud(cadena) devuelve el número de caracteres de
una cadena.
o Por ejemplo, longitud(‘hola’) devuelve 4.
Para hacer referencia al carácter n de una cadena se utiliza el
selector de array.
o Si la cadena c es ‘hola’, c[2] sería el carácter ‘o’.

Universidad Pontificia de Salamanca (Campus Madrid)


Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012 58
Ejemplo 3.2 (II)

lógico función EsPalíndromo(valor cadena :


cad)
var
Pila : p
Cola : c
TipoElemento : e1, e2
entero : i
inicio
PilaNueva(p)
ColaNueva(c)
//Se insertan
todos los
caracteres
de la cadena
en la
//pila y en la
cola al
mismo tiempo
desde i 1 hasta longitud(cad)
hacer CInsertar(c,cad[i])
PInsertar(p,cad[i])
fin_desde
//Se sacan los caracteres de la pila y
la cola hasta que
//se encuentra un carácter distinto o
hasta que alguna de
//las estructuras esté vacía
repetir
Pop(p,e1)
59
Sacar(c,e2)
hasta_que (e1 <>
e2) o
Ejercicios con colas

1. El problema de Josephus.
● Cuenta una leyenda sobre el historiador judio Josephus Flavius que, durante las guerras judeo-
romanas, él y otros 40 soldados judíos quedaron atrapados en una cueva rodeados por los romanos.
Visto que tenían pocas posibilidades de salir con vida, decidieron suicidarse. Josephus y un amigo suyo
no estaban muy felices con esa idea. Así pues, propusieron que si había que hacerlo, se hiciera con
cierto orden: se colocarían en círculo y se irían suicidando por turno cada
tres empezando a contar por uno determinado. Josephus y su amigo se colocaron de tal forma que fueron
los dos últimos y decidieron seguir viviendo.
● Realizar un algoritmo que devuelva el orden en que salieron los soldados. El número de soldados será
m y el salto será n.
2. Se tiene una cola de procesos. Cada elemento contiene la prioridad (de 1 a 20) y un
identificador de proceso único. Se desea hacer un listado con el orden de salida de los
procesos.
3. Se tiene una cola de procesos. Cada elemento contiene la prioridad (de 1 a 20) y un
identificador de proceso único. Se desea hacer un listado con el orden de salida de los
procesos con prioridad p.
4. Se tiene una cola de procesos. Cada elemento contiene información sobre el identificador de
proceso único y su prioridad (de 1 a 20). Los elementos de la cola están ordenados por
prioridad. Diseñar un procedimiento que permita ordenar un nuevo proceso en la cola.

Universidad Pontificia de Salamanca (Campus Madrid)


60
Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012
Listas enlazadas

Estructura lineal de datos compuesta por un conjunto de nodos que ocupan


posiciones no contiguas de memoria.
Cada nodo contiene la información del componente y, al menos, un puntero
que indica la posición del siguiente nodo.
● En el último nodo, la posición del siguiente elemento será un puntero nulo.
● Al no ocupar posiciones contiguas en memoria y ser variable la posición del primer nodo de
la estructura, la lista tendrá otro puntero que indicará la dirección del primer nodo de la
estructura.
Pilas y colas son un tipo especial de listas enlazadas con la entrada y la
salida limitadas.
● En el caso de las listas enlazadas, las inserciones y eliminaciones se podrán hacer
por cualquier punto de la estructura.
Tipos de listas enlazadas.
● Listas simplemente enlazadas o listas simples.
● Listas doblemente enlazadas.
● Listas circulares.
● Listas con cabecera.
● Combinaciones de las anteriores.

Universidad Pontificia de Salamanca (Campus Madrid)


Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012 61
Listas enlazadas (II)

miLista
C F M S V
Listas enlazadas simples

Sólo tienen un puntero indicando el siguiente


elemento.
Laimplementada
estructura deen nuestro
datos lenguaje
“Lista de programación”.
enlazada” no se
considera
implementa listas enlazadas e incluye todas las operaciones que se
● Otros lenguajes, como .Net tienen la clase LinkedList que
pueden hacer sobre ellas.
tipo de dato Lista: las operaciones primitivas.
Será necesario crear el tipo de dato Lista.
● Determinar las operaciones básicas que se pueden realizar sobre
el estructuras de datos que ofrezca el lenguaje de programación.

● Definir
datoseldefinida.
tipo de elementos que contendrá la lista.
● Definir la organización de los datos utilizando los datos y
operaciones primitivas variará.
● Implementar las operaciones primitivas para la organización de
los
63
Dependiendo de la organización definida, la implementación de las
Listas enlazadas simples (II)

Operaciones primitivas.
● ListaNueva(ref lista:l), convierte la lista l en una lista
vacía.
● EsListaVacía(valor lista:l), devuelve verdad si la lista l
está vacía.
● LInsertar(ref lista:l;valor tipoElemento:e),
inserta el elemento e en la lista l.
● LBorrar(ref lista:l), elimina un elemento de la lista l.
● LPrimero(valor lista:l; ref tipoElemento : e),
devuelve la información del primer elemento de la lista en el
argumento e.
● LSiguiente(valor lista:l; ref lista:sig), devuelve
la dirección del siguiente nodo de la lista en el argumento sig.

Universidad Pontificia de Salamanca (Campus Madrid)


Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012
64
Realizaciones mediante arrays

Los datos se almacenarían en un


array de nodos.
info sig
● Cada nodo tendría la 1 TORO 0
información y el índice del animales
2 MANUEL 4
siguiente elemento de la lista. 6
3 -1
● Los elementos vacíos se 4 PEPE 0
marcan, por ejemplo, con -1 personas
5 PERRO 1
en el campo sig. 7
6 DELFIN 10
● En la memoria pueden 7 JUANA 2

coexistir varias listas. 8 -1

La lista estaría definida por la 9

-1 dirección del primer nodo de la 10 GATO

5 estructura. 11
-1

65
Universidad Pontificia de Salamanca (Campus Madrid)
Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012
Realizaciones mediante arrays (II)

Insertar “ANA” en la lista de Borrar el “GATO” de la lista


de personas en la primera posición. animales.
info sig info sig
1 TORO 0
1 TORO 0
animales
2 MANUEL 4 animales
6 2 MANUEL 4
6
3 -1
3 -1
4 PEPE 0
4 PEPE 0
personas 5 PERRO 1 personas
9 5 PERRO 1
6 DELFIN 10 9
6 DELFIN 5
7 JUANA 2
7 JUANA 2
8 -1
8 -1
9 ANA 7
9 ANA 7
10 GATO 5
10 GATO -1
11 -1
11 -1

Universidad Pontificia de Salamanca (Campus Madrid)


66
Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012
Realizaciones mediante punteros

Se considerará la lista enlazada como una estructura de datos recursiva.


● Si la lista está vacía, ésta será un puntero nulo.
● Si tiene elementos, será un puntero que apunta a un nodo con los campos
con la información del elemento, y sig que será
info, otra lista.

● Cada lista será o bien un puntero nulo o un puntero al siguiente nodo.


Una listavacía.
estará estará compuesta por un conjunto de listas, la última de la cuales

● Serán listas,
cualquiera detanto el puntero
los campo que indica la dirección del primer elemento como
siguiente.

tipos
… = TipoElemento
puntero_a nodo : Lista
registro = nodo
TipoElemento : info
Lista : sig
fin_registro

67
Universidad Pontificia de Salamanca (Campus Madrid)
Luis Rodríguez Baena, Escuela Superior de Ingeniería y
Arquitectura, 2012
Realizaciones mediante punteros (II)

Procedimiento ListaNueva

procedimiento ListaNueva(ref lista : l)


inicio
l nulo
fin_procedimiento
Realizaciones mediante punteros (III)

Procedimiento LInsertar

procedimiento LInsertar(ref lista : l; valor TipoElemento : e)


var
lista : aux
inicio
reservar(aux)
aux↑.sig l
aux↑.info e l
aux
fin_procedimiento

● El argumento l puede ser tanto puntero de inicio de la lista


como cualquier de los campos sig de cada nodo.

Universidad Pontificia de Salamanca (Campus Madrid)


Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012 69
Realizaciones mediante punteros (IV)
Realizaciones mediante punteros (V)

LInsertar(l,’B’)

reservar(aux)
Realizaciones mediante punteros (VI)

LInsertar(l↑.sig↑.sig,’E’)

reservar(aux)
Realizaciones mediante punteros (VII)

Procedimiento LPrimero.
● Devuelve la información del primer elemento de la lista.
procedimiento LPrimero(valor lista : l; ref TipoElemento : e)
inicio
si l = nulo entonces
// Error, la lista está vacía
si_no
e l↑.info
fin_si
fin_procedimiento

● Es necesario
comprobar si la lista
tiene elementos (l
<> nulo).
● El argumento l, puede ser tanto el puntero de inicio de la lista
como cualquiera de los campos sig de cada nodo.
73
Realizaciones mediante punteros (VIII)

LPrimero(l,e)
escribir(e) //Escribe B
LPrimero(l↑.sig,e)
escribir(e) //Escribe C
LPrimero(l↑.sig↑.sig↑.sig,e)
escribir(e) //Escribe F

B
C
E
F
M

74
Realizaciones mediante punteros (IX)

Procedimiento LSiguiente.
● Devuelve la la dirección del siguiente nodo de la lista

procedimiento LSiguiente(valor lista : l; ref lista : siguiente)


inicio
si l = nulo entonces
// Error, la lista está vacía
si_no
siguiente
l↑.sig
fin_si
fin_procedimiento
● Es necesario comprobar si la pila tiene elementos (p <> nulo).
● El argumento l, puede ser tanto el puntero de inicio de la lista como cualquiera de
los campos siguiente.
LSiguiente(l↑.sig,siguienteNodo)

Universidad Pontificia de Salamanca (Campus Madrid)


75
Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012
Realizaciones mediante punteros (X)

Recorrido de la lista.
● Se utiliza una combinación de los procedimiento LPrimero y
LSiguiente .

var
lista : aux
TipoElemento : e
...
aux miLista
mientras no EsListaVacía(aux) hacer
LPrimero(aux,e)
escribir(e)
LSiguiente(aux,aux)
fin_mientras

Universidad Pontificia de Salamanca (Campus Madrid)


Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 76
2012
Realizaciones mediante punteros (XI)

Procedimiento LBorrar
● Elimina el elemento al que apunta la lista pasada como argumento.
procedimiento LBorrar(ref lista : l)
var
lista : aux
inicio
s EsListaVacía(l) entonce
// error, la lista está vacía
si_no
aux l
l l↑.sig
liberar(aux)
fin_si
fin_procedimiento

Universidad Pontificia de Salamanca (Campus Madrid)


Luis Rodríguez Baena, Escuela Superior de 77
Ingeniería y Arquitectura, 2012
Realizaciones mediante punteros (XII)

LBorrar(l)

aux l
Realizaciones mediante punteros (XIII)

LBorrar(l↑.sig)

aux l
Ejemplo 3.3

Utilizando las operaciones primitivas para trabajar con


listas, diseñe las siguientes operaciones básicas:
a. Un procedimiento que copie una lista.
b. Una función que devuelva en número de elementos de una
lista.
c. Una función lógica que indique si un elemento pertenece a una
lista.
d. Una función qué busque un elemento en una lista. Si existe
devolverá su dirección, en caso contrario devolverá un puntero
nulo.
e. Una función que devuelva la dirección del último nodo de la
lista.
f. Un procedimiento que invierta una lista.

Universidad Pontificia de Salamanca (Campus Madrid)


80
Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012
Ejemplo 3.3. (II)

La copia de una lista sería prácticamente igual que la


copia de una pila.
procedimiento CopiarLista(valor lista: l ; ref lista:copia)
var
TipoElemento : e
inicio
//Si l está vacía estaríamos en el caso trivial
//Si l está vacía, la copia también es una lista vacía
si EsListaVacía(l) entonces
ListaNueva(copia)
si_no LPrimero(l,e)
LSiguiente(l,l)
CopiarLista(l,copia)
LInsertar(copia,e)
fin_si
fin_procedimiento

Universidad Pontificia de Salamanca (Campus


Madrid)
Luis Rodríguez Baena, Escuela
81
Superior de Ingeniería y Arquitectura, 2012
Ejemplo 3.3. (III)

La función Longitud devuelve el número de elementos de


una lista.
entero función Longitud(valor lista : l)
var
entero : conta
inicio
conta 0
mientras no EsListaVacía(l) hacer
conta conta + 1
LSiguiente(l,l)
fin_mientras
devolver(conta)
fin_función

Universidad Pontificia de Salamanca (Campus Madrid)


Luis Rodríguez Baena, Escuela Superior de 82
Ingeniería y Arquitectura, 2012
Ejemplo 3.3. (IV)

La función Pertenece devuelve un valor lógico según el


elemento pertenezca o no a la lista.
lógico función Pertenece(valor lista : l; valor TipoElemento : elem)
//Se supone que sobre el dato TipoElemento se admite
//el operador de igualdad
var
TipoElemento : e
inicio
LPrimero(l,e)
mientras (e <> elem) y no EsListaVacía(l) hacer
LPrimero(l,e)
LSiguiente(l,l)
fin_mientras
devolver(e = elem)
fin_función

Universidad Pontificia de Salamanca (Campus Madrid)


Luis Rodríguez Baena, Escuela Superior de Ingeniería y 83
Arquitectura, 2012
Ejemplo 3.3. (V)

La función Buscar devuelve la dirección del nodo que


contiene la información que pasamos como argumento, en
caso contrario devuelve un valor nulo.
lista función Buscar(valor lista : l; valor TipoElemento : elem)
var
TipoElemento : e
inicio
LPrimero(l,e)
mientras (e <> elem) y no EsListaVacía(l) hacer
LPrimero(l,e)
LSiguiente(l,l)
fin_mientras
si e = elem entonces
devolver(l)
si_no
devolver(nulo)
fin_si
fin_función

Universidad Pontificia de
Salamanca (Campus Madrid) 84
Luis Rodríguez Baena,
Escuela Superior de Ingeniería
y Arquitectura, 2012
Ejemplo 3.3. (VI)

La función UltimoNodo devuelve la dirección del último


nodo de una lista o un puntero nulo si está vacía.
lista función UltimoNodo(valor lista : l)
var
lista : ant
inicio
ant nulo
mientras no EsListaVacía(l) hacer
ant l
LSiguiente(l,l)
fin_mientras
devolver(ant)
fin_función

Universidad Pontificia de Salamanca (Campus Madrid)


Luis Rodríguez Baena, Escuela Superior de 85
Ingeniería y Arquitectura, 2012
Ejemplo 3.3. (VII)

La función UltimoNodo (versión recursiva, se supone


que la lista está implementada con punteros).
lista función UltimoNodo(valor lista : l)
inicio
si l = nulo entonces
devolver(nulo)
si_no
si l↑.sig = nulo entonces
de
v
o
devolver(UltimoNodo(l↑.sig))
l
v
e
r
(
l
)
si_no

fin_si
fin_si 86

fin_funci
ón
Ejemplo 3.3. (VIII)

El procedimiento InvertirLista, devuelve como


argumento una copia de la lista en orden inverso.
● Versión realizando una copia.
procedimiento InvertirLista(ref
lista :l)
var
lista : aux
TipoElemento : e
inicio
ListaVacía(aux)
mientras no EsListaVacía(l)
hacer
LPrimero(l,e)
LInsertar(aux,e)
LBorrar(l)
fin_mientras
l aux
fin_procedimiento

87

Universidad Pontificia de Salamanca (Campus Madrid)


Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012
Ejemplo 3.3. (IX)

Versión sin mover los nodos


de su ubicación en memoria
(suponiendo que está
implementada con
punteros).
procedimiento
act InvertirLista(ref
l↑.sig
lista : l)
var
lista : act,sig,ant
inicio sig act↑.sig
si l <> nulo entonces

ant l
l↑.sig nulo
mientras act <> nulo hacer

act↑.sig
ant ant
act
act 88

sig
Ejercicios con listas

1. Se desea implementar números binarios utilizando listas enlazadas.


Cada nodo de la lista almacenará el dígito binario (un 0 o un 1). El
dígito menos significativo ocupará la primera posición de la lista. Por
ejemplo, si el número n fuera 11010, se almacenaría como:
Ejercicios con listas (II)

2. Se desean implementar cadenas utilizando una lista enlazada. Cada


elemento de la lista será un carácter de la cadena. Codifique los métodos
adecuados (sin utilizar el tipo de dato estándar ) para:
A. Leer una cadena carácter a carácter hasta que el usuario pulse la tecla Intro. B.
Escribir una cadena.
C. Concatenar dos cadenas.
D. Comparar dos cadenas. Devolverá 0 si son iguales, -1 si la primera cadena es
menor que la segunda o 1 si la primera cadena es mayor que la segunda.
E. Realizar un procedimiento subcadena que devuelva una subcadena de una
cadena principal a partir de una posición el número de caracteres indicado. Por
ejemplo, si la cadena cad es “cocodrilo”…

con la llamada subcadena(cad,3,4,scad), scad sería “codr” (una subcadena


formada por los 4 caracteres a partir del carácter 3):

Universidad Pontificia de Salamanca (Campus Madrid) 90


Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012
Listas ordenadas

Si se requiere que los elementos de la lista estén ordenados


por algún criterio, se puede incluir un procedimiento para
insertar un elemento ordenado en la lista y mejorar el
procedimiento de borrar.
Insertar Ordenado.

procedimiento InsertarOrdenado(ref lista : l; valor TipoElemento : e)


var
lista : act,ant
lógico : encontrado
inicio
encontrado falso
act l

Universidad Pontificia de Salamanca (Campus Madrid)


91
Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012
Listas ordenadas (II)

mientras no encontrado y (act <> nulo) hacer


si e <= act↑.info entonces
encontrado
verdad si_no
ant act
act
act↑.sig
fin_si
fin_mientras
si act = l
entonces
LInsertar(l,e)
LInsertar(ant↑.sig,e)
si_no

fin_si
fin_prodedimiento

92

Universidad Pontificia de Salamanca (Campus Madrid)


Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012
Listas ordenadas (III)

Para borrar un elemento…


procedimiento
BorrarElemento(ref lista : l;
valor TipoElemento : e)
var
lista : act,ant
lógico : encontrado
inicio
encontrado falso
act l
mientras no encontrado y (act <> nulo) hacer
si e <= act↑.info entonces
encontrado
verdad si_no
ant act
act
act↑.sig
fin_si
fin_mientras
si e =
act↑.info
entonces
si act =
l
entonces
LBorra
r(l)
si_no 93

LB
or
Ejercicios con listas ordenadas

1. Se desean implementar conjuntos utilizando una lista enlazada. Los elementos


del conjunto estarán ordenados de forma ascendente y no tendrán repeticiones.
Implemente módulos que permitan incluir un elemento en el conjunto,
averiguar si un elemento pertenece a un conjunto, obtener el conjunto unión, el
conjunto intersección y el conjunto diferencia.
Se desea implementar polinomios mediante listas enlazadas. Cada elemento
2. será uno monomio con el grado y el coeficiente. Los elementos
se almacenarán en la lista ordenados de mayor a menor por grado de los
monomios.

Se desea diseñar un módulo que lea un polinomio, otro que lo escriba y


otro que realice la suma de polinomios

Universidad Pontificia de Salamanca (Campus Madrid)


94
Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012
Ejercicios con listas ordenadas (II)

3. Una empresa tiene almacenada en una lista enlazada información se


sobre los productos que guarda en el almacén. Por cada producto
almacena:
● Código de producto (tipo cadena)
● Stock (tipo entero)
● Stock mínimo (tipo entero)
● Código del proveedor que distribuye el producto (tipo cadena).
La información de la lista ya está cargada y está ordenada por el
código de producto.
A. Declare las estructuras de datos necesarias para realizar todas las
operaciones descritas a continuación:
B. Desarrolle un módulo que copie en otra lista todos los artículos cuyo el
stock sea inferior al stock mínimo. La nueva lista estará ordenada por
código de producto.
C. Desarrolle un módulo que elimine de la lista todos los elementos cuyo
código de producto sea mayor que ‘100’.

Universidad Pontificia de Salamanca (Campus Madrid) 95


Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012
Listas circulares

Una lista circular es una lista enlazada en la que el último elemento de


la lista apunta al primer elemento.
miLista

LUIS ANA MANOLO

Universidad Pontificia de Salamanca (Campus Madrid)


96
Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012
Listas circulares (II)

Las primitivas para crear una lista, para ver si está vacía, y para insertar al
principio o inserta y borrar por el centro no varían.
Para insertar al final.

procedimiento
LCInsertarUltimo(ref
lista : l; valor
TipoElemento : e)
//l es la dirección del
final de la lista
circular
aux↑.info e
var
lista :aux↑.sig
aux sig
inicio
reservar(aux)
aux↑.sig l↑.sig

si l = nulo entonces

si_no

l↑.sig aux
fin_si 97
l aux
fin_procedimiento
Listas circulares (III)

Para borrar el primer elemento de la lista


procedimiento LCBorrarPrimero(ref lista : l)
//l es la dirección del final de la lista circular
var
lista : aux
inicio
si l = nulo entonces
//Error lista vacía
si_no
aux l↑.sig
si aux = l entonces
//Sólo hay un elemento
l nulo
si_no
l↑.sig aux↑.sig
fin_si
liberar(aux)
fin_si
fin_procedimiento

Universidad Pontificia de Salamanca (Campus Madrid)


98
Luis Rodríguez Baena, Escuela Superior de
Ingeniería y Arquitectura, 2012
Listas circulares (IV)

Para borrar el último elemento.


● Es necesario también pasar la dirección del nodo anterior, además del
comienzo de la lista, o recorrer la lista para buscar el último elemento.
procedimiento LCBorrarUltimo(ref lista : l; valor lista : ant)
//l es la dirección del final de la lista circular
// ant la dirección del nodo anterior
var
lista : aux
inicio
si l = nulo
entonces
//Error
lista
vacía
si_no
aux l
si
l↑.sig =
l
entonces
//Sólo hay un elemento
l nulo
si_no
ant↑.sig
l↑.sig l ant
fin_si
liberar(aux) 99
fin_si
fin_procedimie
Listas circulares (V)

Si en una lista circular sólo utilizamos


LCInsertarUltimo y LCBorrarPrimero estamos
ante una cola.
● La estructura cola sería una lista.
● CrearCola(ref cola: c), sería ListaVacía(c).
● EsColaVacía(valor cola :c), sería EsListaVacía(c).
● CInsertar(ref cola : c; valor tipoElemento: e),
sería LCInsertarUltimo(c,e).
● CBorrar(ref cola : c), sería LCBorrarPrimero().
● Primero(valor cola : c; ref tipoElemento : e),
sería LPrimero(c↑.sig,e).

Universidad Pontificia de Salamanca (Campus Madrid)


Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012
100
Listas dobles

Cada elemento tiene un puntero al siguiente elemento y un puntero


al anterior, menos el primero que tiene un puntero anterior nulo y el
último que tiene un puntero siguiente nulo.
La estructura del nodo es distinta.


tipos

registro = nodo
TipoElemento : info
ant,sig : lista
fin_registro

Universidad Pontificia de Salamanca (Campus Madrid)


101
Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012
Listas dobles (II)

La creación de la lista no varía.


Para la inserción, si es al final es necesario pasar también la dirección del nodo
anterior, no sólo la variable dinámica con la última lista.
● Si se desea insertar al principio, la dirección del nodo anterior será nulo.

procedimiento LDInsertar(valor lista:anterior;


ref lista:l ; valor TipoElemento:e)
var
lista : aux
inicio
reservar(aux)
aux↑.info e
aux↑.sig l
si l <> nulo
entonces
aux↑.ant l↑.ant
//Existe un
elemento
anterior
aux↑.ant anterior

l↑.ant
aux
si_no

fin_si 102
l aux
fin_procedimiento
Listas dobles (III)

Se puede hacer otra versión pasando


o nulo si se
simplemente quiere insertar
la posición del nodoelanterior
primer nodo de la estructura.

procedimiento LDInsertar(ref lista:anterior; valor


TipoElemento:e)
var
lista : aux
inicio
reservar(aux)
aux↑.info
aux↑.ant
e nulo
si anterior = nulo
entonces //Está
vacía
aux↑.sig anterior
aux↑.sig nulo
anterior↑.ant aux
anterior aux
si_no
si anterior↑.ant = nulo entonces //Queremos insertar al comienzo

aux↑.ant nulo
aux↑.sig↑.ant aux
anterior aux
si_no
aux↑.sig anterior↑.sig
aux↑.ant anterior
si aux↑.sig <> nulo
entonces //no es el
último elemento

fin_si
103
anterior↑.sig aux
fin_si
fin_si
Listas dobles (IV)

Borrar un elemento de la lista


doble.

procedimiento LDBorrar(ref lista:l)


var
lista : aux
inicio
si l = nulo entonces
//Error lista vacía
si_no
aux l
l l↑.sig
aux↑.sig↑.ant aux↑.ant
si l <> nulo entonces

fin_si
disoner(aux)
fin_si
fin_procedimiento

104
Universidad Pontificia de Salamanca (Campus Madrid)
Luis Rodríguez Baena, Escuela Superior de
Ingeniería y Arquitectura, 2012
Listas con cabecera

El primer nodo es un componente cabecera sin


información o con metainformación que apuntaría al
primer elemento
Evitan un tratamiento distinto para el primer nodo de la
estructura, ya que todos los nodos tienen un nodo
anterior.

Universidad Pontificia de Salamanca (Campus Madrid)


105
Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012
Otras realizaciones

Los tres modelos anteriores se


pueden combinar.
● Listas dobles circulares.
● Listas dobles con cabecera.
● Listas dobles circulares con
cabecera.

106
Listas dobles circulares

Permiten evitar la necesidad de pasar la dirección del


nodo anterior, porque todos los elementos tienen un
anterior y un siguiente.
procedimiento LDCInsertar(ref lista:l ; valor TipoElemento:e)
var
lista : aux
inicio
reservar(aux)
aux↑.info e
aux↑.sig l
aux↑.ant
l↑.ant l↑.ant
aux
l aux
fin_procedimiento

107
Universidad Pontificia de Salamanca (Campus Madrid)
Luis Rodríguez Baena, Escuela Superior de
Ingeniería y Arquitectura, 2012
Listas dobles circulares (II)

Para borrar tampoco hay que hacer distinción.

procedimiento LDCBorrar(ref lista:l)


var
lista : aux
inicio
si l = nulo entonces
//Error lista vacía
si_no
aux l
l l↑.sig
l↑.sig↑.ant
l↑.ant disponer(aux)
fin_si
fin_procedimiento

Universidad Pontificia de Salamanca (Campus


Madrid) 108
Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012
Listas dobles circulares (III)

Pero si queremos insertar en la última posición…

procedimiento LDCInsertarUltimo(ref lista:ultimoNodo ;


valor TipoElemento:e)
var
lista : aux
inicio
reservar(aux)
aux↑.info e
si ultimoNodo =
nulo entonces aux
aux↑.sig

aux↑.ant
aux
aux↑.sig ultimoNodo↑.sig
si_no

aux↑.ant ultimoNodo
ultimoNodo↑.sig
aux
fin_si
ultimoNodo aux
fin_procedimiento
109

Universidad Pontificia de Salamanca (Campus Madrid)


Listas dobles circulares (IV)

Pero si queremos borrar en la última posición…


procedimiento LDCInsertarUltimo(ref lista:ultimoNodo ;
valor TipoElemento:e)
var
lista : aux
inicio
si ultimoNodo = nulo entonces
//Error lista vacía
si_no
ultimoNodo aux
si ultimoNodo↑.sig = ultimoNodo entonces
ultimoNodo
nulo si_no
ultimoNodo aux↑.ant //ultimoNodo apunta al anterior
ultimoNodo↑.sig aux↑.sig //El nuevo último apunta al
primero aux↑.sig↑.ant ultimoNodo //El primer nodo apunta al
último
fin_si
disponer(aux)
fin_si
fin_procedimiento
110
Universidad Pontificia de Salamanca (Campus
Madrid)
Luis Rodríguez Baena, Escuela Superior de Ingeniería y Arquitectura, 2012

También podría gustarte