Estructuras Lineales de Datos
Estructuras Lineales de Datos
Estructuras Lineales de Datos
4
Universidad Pontificia de Salamanca (Campus Madrid)
Luis Rodríguez Baena, Escuela Superior de Ingeniería y
Arquitectura, 2012
Tipos abstractos de datos (IV)
● 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)
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
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.
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)
a 5
pt
r1
pt
r2
Datos estáticos y dinámicos (VI)
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
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.
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.
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)
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.
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.
PilaNueva(p)
EsPilaVacía(p) //Devuelve verdad
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).
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 PBorrar
● Elimina el elemento cima de la pila
● Es necesario comprobar si la pila contiene elementos (si cima <> 0).
La pila está definida por la posición del primer elemento que será por
Realización mediante una lista
enlazada (II)
Procedimiento PilaNueva
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.
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)
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)
● Es necesario comprobar si la
pila tiene elementos (p <>
nulo)
aux p
procedimiento PBorrar( ref pila : p)
Realización mediante una lista enlazada
(VII)
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
Versión iterativa.
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
43
Colas
principio final
e0 e1 e2 e3 e4 e5 e6 e7
44
Colas (II)
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
const
MaxCola = …
tipos
… = TipoElemento
registro = cola
entero : p,f
array[1..MaxCola] de TipoElemento : el
fin_registro
ColaNueva(c)
Realizaciones mediante arrays (III)
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
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)
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 Sacar.
● Combina los procedimientos CBorrar y Primero.
c
p f
e
Ejemplo 3.2
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.
miLista
C F M S V
Listas enlazadas simples
● 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.
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)
● 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 LInsertar
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
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
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
LBorrar(l)
aux l
Realizaciones mediante punteros (XIII)
LBorrar(l↑.sig)
aux l
Ejemplo 3.3
Universidad Pontificia de
Salamanca (Campus Madrid) 84
Luis Rodríguez Baena,
Escuela Superior de Ingeniería
y Arquitectura, 2012
Ejemplo 3.3. (VI)
fin_si
fin_si 86
fin_funci
ón
Ejemplo 3.3. (VIII)
87
ant l
l↑.sig nulo
mientras act <> nulo hacer
act↑.sig
ant ant
act
act 88
sig
Ejercicios con listas
fin_si
fin_prodedimiento
92
LB
or
Ejercicios con listas ordenadas
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)
…
tipos
…
registro = nodo
TipoElemento : info
ant,sig : lista
fin_registro
l↑.ant
aux
si_no
fin_si 102
l aux
fin_procedimiento
Listas dobles (III)
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)
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
106
Listas dobles circulares
107
Universidad Pontificia de Salamanca (Campus Madrid)
Luis Rodríguez Baena, Escuela Superior de
Ingeniería y Arquitectura, 2012
Listas dobles circulares (II)
aux↑.ant
aux
aux↑.sig ultimoNodo↑.sig
si_no
aux↑.ant ultimoNodo
ultimoNodo↑.sig
aux
fin_si
ultimoNodo aux
fin_procedimiento
109