Está en la página 1de 68

Universidad de Valladolid

Departamento de informática
Campus de Segovia

Estructura de datos
Tema 3:
El TAD Lista lineal

Prof. Montserrat Serrano Montero


ÍNDICE

• El TAD lista lineal


• Implementación con estructuras estáticas
• Implementación con variables dinámicas
• El TAD lista enlazada
• Operaciones para lista enlazada ordenada
EL TAD LISTA LINEAL

• Conjunto de valores:

- Una lista es una secuencia elementos de un


determinado tipo ⇒ la lista es homogénea.

(a1, a2, a3, ..., an) donde n ≥ 0,


si n = 0, la lista es vacía.

- Los elementos de una lista tienen la


propiedad de estar ordenados de forma
lineal, según las posiciones que ocupan.

ai precede a ai+1 para i = 1, 2, 3, ..., n-


1
ai sucede a ai-1 para i = 2, 3, 4, ..., n

(significa que cada elemento tiene un


único predecesor, excepto el primero, y
un único sucesor, excepto el último)
EL TAD LISTA LINEAL
• Observaciones:

- La lista es una estructura dinámica desde


el punto de vista lógico, ya que su longitud
dependerá del número de elementos que
tenga, aumentará al insertar y se reducirá al
suprimir.

- El TAD lista puede implementarse de


formas estática o dinámica.

- Igualmente, considerar las operaciones


básicas depende de:
a) La implementación elegida para las listas
b) El problema que se va a resolver.
EL TAD LISTA LINEAL
• Especificación informal: Sintaxis Semántica

TAD lista (VALORES: secuencia de elementos;


OPERACIONES: Inicia, Localiza, Recupera, Inserta,
SuprimeDir, Modifica)
Inicia (Lista) → Lista
Efecto: Devuelve una lista vacía.
Localiza (Lista, Elemento) → Posicion
Efecto: Devuelve la posición donde está el Elemento de la
Lista. Si no está, devuelve nulo.
Recupera (Lista, Posición) → Elemento
Efecto: Devuelve el Elemento que está en la Posición.
Excepción: Que la posición no sea un índice de la Lista.
Inserta (Lista, Posición, Elemento) → Lista
Efecto: Devuelve la Lista después de añadir el Elemento en la
Posición.
Excepciones: Que la posición no sea un índice de la Lista, que
la Lista esté llena.
SuprimeDir (Lista, Posicion) → Lista
Efecto: Devuelve la lista sin el elemento de la Posición
especificada.
Excepciones: Que la posición no sea un índice de la Lista, que
la Lista sea vacía.
Modifica (Lista, Posicion, Elemento) → Lista
Efecto: Devuelve la lista con el nuevo Elemento en la Posición
especificada.
Excepciones: Que la Posición no sea un índice de la Lista, que
la Lista sea vacía.
EL TAD LISTA LINEAL

• Especificación formal:

TAD lista (VALORES: secuencia de elementos;


OPERACIONES:Inicia, Localiza, Recupera, Inserta,
SuprimeDir, Modifica)
Sintaxis:
*Inicia (Lista ) → Lista
Localiza (Lista, Elemento) → Posicion
Recupera (Lista, Posicion) → Elemento
*Inserta (Lista, Posicion, Elemento) → Lista
SuprimeDir (Lista, Posicion) → Lista
Modifica (Lista, Posicion, Elemento) → Lista
Semántica:
SuprimeDir (Inicia (Lista )) ⇒ error
SuprimeDir (Inserta (L, P, E), P) ⇒ L
Modifica (Inicia (Lista ), P, E) ⇒ error
Modifica (Inserta (L, P, E), P, E1) ⇒Inserta (L,P,E1)
* Constructores
TAD E IMPLEMENTACIÓN

• En este punto hay que marcar la distinción


entre un TAD y la naturaleza de su
implementación.
• Ambos conceptos pueden considerarse de
forma estática o dinámica.
Ej: 1. Una variable de tipo array es una
estructura estática, pero puede almacenarse
en memoria de forma estática (declarada en
la zona de declaración de variables) o de
forma dinámica (variables dinámicas).
2. Una pila o una lista son por naturaleza
dinámicas pero pueden implementarse con
asignación de memoria estática (dentro de
un array) o con asignación de memoria
dinámica (variables dinámicas y punteros).
IMPLEMENTACIÓN ESTÁTICA

unit LEstatic;
interface
const Max = ...; {especifica tamaño máximo lista}
type
tInfo = ...;{tipo de campo de información lista}
Lista = record
Elementos: array [1..Max] of tInfo;
Ultimo: integer
end;
Posicion = 0 .. Max;
procedure Inicia (var L: Lista);
function Localiza (L: Lista; E: tInfo): Posicion;
procedure Recupera (L: Lista; P:Posicion; var E: tInfo);
procedure Inserta (var L: Lista; P:Posicion; E: tInfo);
procedure SuprimeDir (var L: Lista; P: Posicion);
procedure Modifica (var L: Lista; P: Posicion; E: tInfo);
IMPLEMENTACIÓN ESTÁTICA
implementation
procedure Inicia;
begin
L.Ultimo := 0
end;
function Localiza;
var Q: Posicion; Lc: boolean;
begin
Q := 1; Lc := false;
while (Q <= L.Ultimo) and not Lc do
begin
Lc := L.Elementos [Q] = E;
if not Lc then Q := Q + 1
end;
if Lc then Localiza := Q
else Localiza := 0
end;
IMPLEMENTACIÓN ESTÁTICA
implementation (continúa...)

procedure Error (n: integer);


{procedimiento oculto que sólo se ve en el módulo}
begin
case n of
1: writeln (‘Error: posición no existe’);
2: writeln (‘Error: lista llena. No se pueden
añadir elementos);
3: writeln (‘Error: lista vacía. No se pueden
suprimir o modificar elementos’);
end; {case}
readln {Pausa}
end;
procedure Recupera;
begin
if (P > L.Ultimo) or (P < 1) then Error (1)
else E := L.Elementos [P]
end;
IMPLEMENTACIÓN ESTÁTICA
implementation (continúa...)
procedure Inserta;
var Q: Posicion;
begin
if L.Ultimo = Max then Error (2)
else if (P > L.Ultimo) or (P < 1) then Error (1)
else begin
for Q := L.Ultimo downto P do
L.Elementos [Q + 1] := L.Elementos [Q] ;
L.Ultimo := L.Ultimo + 1;
L.Elementos [P] := E
end
end;
procedure Suprime;
var Q: Posicion;
begin
if L.Ultimo = 0 then Error (3)
else if (P > L.Ultimo) or (P < 1) then Error (1)
else begin
L.Ultimo := L.Ultimo – 1;
for Q := P to L.Ultimo do
L.Elementos [Q] := L.Elementos [Q+1]
end
end;
IMPLEMENTACIÓN ESTÁTICA
implementation (continúa...)

procedure Modifica;
begin
if L.Ultimo = 0 then Error (3)
else if (P > L.Ultimo) or (P < 1) then Error (1)
else
L.Elementos [P] := E
end;
end.
IMPLEMENTACIÓN DINÁMICA

• Las desventajas de la implementación anterior


son:
a) Estructura rígida. Inserción y supresión
desplazando el resto del array.
b) No se utiliza de forma óptima la memoria.
Hay que reservar espacio en memoria para
toda la estructura durante toda la ejecución.

• Estos inconvenientes pueden solucionarse


utilizando variables dinámicas.

• Los elementos de la lista dinámica se definen


como datos de tipo registro con, al menos, dos
componentes:
1. Almacén del dato de la lista.
2. Puntero, que almacena la posición de
memoria del siguiente elemento de la lista o
nil si es el último elemento.
EL TAD LISTA ENLAZADA

• Una lista dinámica simple se llama lista


enlazada. Cada uno de los elementos de una
lista dinámica se llaman nodos.

• El número de nodos puede variar rápidamente


en un proceso, aumentando por inserción de
nodos o disminuyendo por supresión de nodos.

• Una lista enlazada es aquella en la que el orden


de las componentes se determina mediante un
campo enlace explícito en cada nodo.

• Las operaciones sobre una lista enlazada


permiten acceder a la misma mediante un
puntero externo, que contiene la dirección del
primer nodo de la lista.
TAD LISTA IMPLEMENTADO CON
LISTAS ENLAZADAS
unit LDinami;
interface
type
tInfo = ...;{tipo de campo de información lista}
Ptr = ^Nodo; {Excepción a la regla de que los
Nodo = record identificadores deben definirse
antes de usarse. El tipo Ptr se
Info: tInfo; define como un puntero a un
Sig: Ptr registro del tipo Nodo, el cual no
ha sido aún definido.}
end;

procedure Inicia (var L: Ptr);


function Localiza (L: Ptr; E: tInfo): Ptr;
procedure Recupera (L: Ptr; P: Ptr; var E: tInfo);
procedure Inserta (var L: Ptr; P: Ptr; E: tInfo);
procedure SuprimeDir (var L: Ptr; P: Ptr);
procedure Modifica (L: Ptr; P: Ptr; E: tInfo);
TAD LISTA IMPLEMENTADO CON
LISTAS ENLAZADAS
implementation

procedure Inicia;
L
begin
L := nil
end;

function Localiza;
begin
while (L^.Sig < > nil) and (L^.Info < > E) do
L := L^.Sig;
if L^.Info < > E then Localiza := nil
else Localiza := L
end;
L^.Sig

E
L
TAD LISTA IMPLEMENTADO CON
LISTAS ENLAZADAS
implementation (continúa ...)
procedure Recupera;
begin
if not (L=nil) then
if (P < > nil) then E := P^.Info
end;
function Anterior (P: Ptr; L: Ptr): Ptr;
{El anterior de lista vacía, de dirección no
existente y del primer nodo de la lista,
devuelve nil}
begin
if (L = nil) or (P = nil) or (L = P) then
Anterior := nil
else begin
while (L^.Sig<>P) and (L^.Sig<>nil) do
L := L^.Sig;
if L^.Sig = P then Anterior := L
else Anterior := nil L L^.Sig = P
end {else}
end;
TAD LISTA IMPLEMENTADO CON
LISTAS ENLAZADAS
L
implementation (continúa ...)
procedure Inserta; {Inserta en L un nodo con el
var A: Ptrnodo; campo E, delante del nodo de
begin dirección P} A^.Sig = nil
new (A); L=A
A^.Info := E;
E
a) if (L = nil) then L := A {si L vacía}
else if P = L then {si P primer nodo}
begin L=P
b) A^.Sig := P; A
L := A
end E A^.Sig = P
c) else begin {si P es oto nodo, A entre anterior y P}
Anterior (P, L)^.Sig := A;
A^.Sig := P
end
end;

Anterior (P, L)^.Sig


TAD LISTA IMPLEMENTADO CON
LISTAS ENLAZADAS
implementation (continúa ...)
procedure SuprimeDir;
begin
if P = L then {Primer nodo}
begin
L := L^.Sig; P=L
dispose (P)
end ????
else if Anterior (P, L) < > nil then
begin
{Enlaza anterior con siguiente}
Anterior (P, L)^.Sig := P^.Sig
dispose (P) L P
end
????
end;
Anterior (P,L)^.Sig:=P^.Sig
procedure Modifica;
begin
if not (L = nil) then
if (P < > nil) then P^.Info := E
end;
end.
CLASIFICACIÓN OPERACIONES DE
TAD LISTA ENLAZADA
• Iniciar una lista enlazada:
- Inicia (L)
- EsVacia(L)
• Búsqueda en una lista:
- Localiza (E, L)
- Existe (E, L)
• Operaciones de dirección:
- Siguiente (P, L)
- Anterior (P, L)
- Último (L)
• Inserción de un elemento en la lista:
- Inserprim (E, L)
- Inserta (E, P, L)
- Inserfin (E, L)
• Supresión de un elemento de una lista:
- Suprime (E, L)
- SuprimeDir (P, L)
- Anula (L)
• Recorrido de una lista:
- Visualiza (L)
ALGUNAS OPERACIONES
DEL TAD LISTA ENLAZADA
• EsVacia (L): Función que determina si L es vacía o
no.
• Existe (E, L): Función que determina si el elemento
E se encuentra en L o no.
• Inserprim (E, L): Inserta un nodo con la información
E como primer nodo de la lista.
• Inserfin (E, L): Inserta un nodo con el campo E
como último nodo de la lista L.
• Suprime (E, L): Elimina el nodo de la lista que
contiene E
• Siguiente (P, L): Función que devuelve la dirección
del nodo siguiente a P.
• Anterior (P, L): Función que devuelve la dirección
del nodo anterior a P.
• Primero (L): Función que devuelve la dirección del
primer nodo de la lista L.
• Último (L): Función que devuelve la dirección del
último nodo de la lista L.
• Anula (L): Esta operación vacía la lista L.
• Visualiza (L): Visualiza el campo de información de
todos los elementos de la lista.
IMPLEMENTACIÓN DEL TAD
LISTA ENLAZADA
unit LEnlaza;
interface
type
tInfo = ...;{tipo de campo de información lista}
Ptr = ^Nodo;
Nodo = record
Info: tInfo;
Sig: Ptr
end;
procedure Inicia ( var L: Ptr);
function Esvacia (L: Ptr): boolean;
function Localiza (E: tInfo; L: Ptr): Ptr;
function Existe (E: tInfo; L: Ptr): boolean;
function Anterior (P, L: Ptr): Ptr;
function Siguiente (P, L: Ptr):Ptr;
function Ultimo (L: Ptr): Ptr;
procedure Inserprim (E: tInfo; var L: Ptr);
procedure Inserta (E:tInfo; P:Ptr; var L:Ptr);
procedure Inserfin (E: tInfo; var L: Ptr);
procedure Suprime (E: tInfo; var L: Ptr);
procedure Suprimedir (P: Ptr; var L: Ptr);
procedure Anula (var L: Ptr);
procedure Visualiza (L: Ptr);
IMPLEMENTACIÓN DEL TAD
LISTA ENLAZADA

implementation

function EsVacia;
begin
EsVacia:= L=nil
end;

function Existe;
begin
if not EsVacia (L) then
begin
while (L^.Sig<>nil) and (L^.Info<>E) do
L := L^.Sig;
Existe := (L^.Info = E)
end;
else Existe := false
end;
IMPLEMENTACIÓN DEL TAD
LISTA ENLAZADA
implementation (continúa...)
function Siguiente;
begin
if EsVacia (L) or (P = nil) then
P P^.Sig
Siguiente := nil
else
Siguiente := P^.Sig
end;

function Ultimo;
begin
if EsVacia(L) then Ultimo := nil
else
begin
while (L^.Sig<>nil) do
L := L^.Sig;
L L^.Sig = nil
Ultimo := L;
end
end;
IMPLEMENTACIÓN DEL TAD
LISTA ENLAZADA
implementation (continúa...)
function Crea (E: tInfo): Ptr;
var N: Ptr;
begin N^.Sig = nil
N
new (N);
N^.Info := E; E
N^.Sig := nil;
Crea := N
end;
procedure Inserprim;
var A: Ptr; L
begin
A := Crea (E); A E
A^.Sig := L; L
L := A A
end;
E A^.Sig = L
IMPLEMENTACIÓN DEL TAD
LISTA ENLAZADA
implementation (continúa...)
procedure Inserfin;
var A: Ptr; L

begin
A := Crea (E); L
if EsVacia (L) then
L := A Ultimo(L)^.Sig=A E
else
Ultimo(L)^.Sig := A;
end;
procedure Suprime; L
var A: Ptr;
???
begin
L
A := Localiza(E, L);
if A<>nil then begin ???
if A = L then L := L^.Sig {primer nodo}
else Anterior (A, L)^.Sig := A^.Sig;
dispose(A)
end {if}
end;
IMPLEMENTACIÓN DEL TAD
LISTA ENLAZADA
implementation (continúa...)

procedure Anula;
begin
while not EsVacia (L) do
SuprimeDir (Ultimo(L), L)
end;

procedure Visualiza;
begin
while L< > nil do
begin
write(L^.Info,’ ’);
L := L^.Sig
end
end;

end.
TAD LISTA ORDENADA

• En las listas vistas anteriormente los elementos


están ordenados con respecto a la posición que
ocupan dentro de la lista.

• Si el tipo de información que representa cada


elemento es un tipo ordinal se puede mantener
la lista ordenada respecto a dicho campo.

• La formación de una lista ordenada se basa en


dos operaciones:
– Posinser (E, L): Devuelve la dirección del
nodo anterior al que contiene el campo E
según la ordenación dada y nil si es el
anterior al primero.
– Inserorden (E, L): Si la lista está vacía el
nodo se inserta como el primero de la lista,
si no se inserta en la posición que le
corresponde.
IMPLEMENTACIÓN DE
OPERACIONES LISTA ORDENADA

function Posinser (E: tInfo; L: Ptr): Ptr;


var T: Ptr;
begin
T := nil;
if not EsVacia (L) then
begin
while (E >= L^.Info) and (L^.Sig <> nil) do
begin
T := L;
L := L^.Sig
end;
if E >= L^.Info then T := L
end;
Posinser := T
end;
L L^.Sig
T
E
IMPLEMENTACIÓN DE
OPERACIONES LISTA ORDENADA
procedure Inserorden (E: tInfo; var L: Ptr);
var A, N: Ptr;
L
begin 12 29 36
N := Crea (E); 15
if EsVacia(L) then L := N N

else begin
A := Posinser (E, L);
if A = nil then begin{primera posición}
N^.Sig := L;
L := N
end;
else begin {posición intermedia}
L
N^.Sig := A^.Sig;
A
A^.Sig := N 12 29 36
A^.Sig
end 15 N^.Sig
end {else} N
end;
IMPLEMENTACIÓN DE
OPERACIONES LISTA ORDENADA
• Ahora la operación de búsqueda es más eficiente,
ya que para decidir si un elemento está o no en la
lista, basta con encontrar un elemento mayor.

– Buscorden (E, L): Devuelve la dirección del nodo que


contiene el campo e o nil si no se encuentra en la lista.

function Buscorden (E: tInfo; L: Ptr): Ptr;


begin
while (L^.Sig <> nil) and (L^.Info < E) do
L := L^.Sig;
if L^.Info = E then Buscorden := L
else Buscorden := nil
end;
El resto de operaciones son iguales a las listas no
ordenadas. Cambiar las llamadas a Localiza por
Buscorden.
Universidad de Valladolid
Departamento de informática
Campus de Segovia

Estructura de datos
Tema 3: TAD Pila

Prof. Montserrat Serrano Montero


ÍNDICE

• Definición
• Especificación TAD Pila
• Implementación estática
• Implementación dinámica
• Aplicaciones de pilas
• Esquema recursivo
EL TAD PILA

- Una pila es una lista (estructura


dinámica) de elementos en la que todas
las inserciones y supresiones se realizan
por el mismo extremo de la lista.

- La característica de esta estructura


de datos es que el primer elemento
obtenido es el último que se ha
introducido; motivo por el que se
conoce como estructura Lifo (Last in
first out).

- Se utiliza siempre que se quiere


recuperar una serie de elementos en
orden inverso a como se introdujeron.

- Ejs.: pila de platos, de libros, etc.


EL TAD PILA
• Especificación informal:

TAD pila (VALORES: pila de elementos;


OPERACIONES: Inicia, EsVacia, Apilar, Desapilar,
Cima)
Inicia ( ) → Pila
Efecto: Devuelve una pila vacía.
EsVacia (Pila) → Boolean
Efecto: Devuelve true si la pila está vacía y false en caso
contrario.
Apilar (Pila, Elemento) → Pila
Efecto: Devuelve una pila resultado de poner el elemento
en la cima de la pila.
Excepción: Que la pila esté llena.
Desapilar (Pila) → Pila
Efecto: Devuelve la Pila sin el elemento de la cima.
Excepción: Si la Pila está vacía produce error.
Cima (Pila) → Elemento
Efecto: Devuelve el Elemento cima de la Pila.
Excepción: Si la Pila está vacía produce error.
EL TAD PILA

• Especificación formal:

TAD pila (VALORES: pila de elementos;


OPERACIONES: Inicia, EsVacia, Apilar, Desapilar,
Cima)
Sintaxis:
*Inicia ( ) → Pila
EsVacia (Pila) → Boolean
*Apilar (Pila, Elemento) → Pila
Desapilar (Pila) → Pila
Cima (Pila) → Elemento
Semántica:
EsVacia (Inicia ( )) ⇒ true
EsVacia (Apilar (P, E)) ⇒ false
Cima (Inicia ( )) ⇒ error
Cima (Apilar (P, E)) ⇒ Ε
Desapilar (Inicia ( )) ⇒ error
Desapilar (Apilar (P, E)) ⇒ P

* Constructores
IMPLEMENTACIÓN ESTÁTICA

unit PEstatic;
interface
const Max = ...; {especifica tamaño máximo lista}
type
tInfo = ...;{tipo de campo de información lista}
Pila = record
Elementos: array [1..Max] of tInfo;
ultimo: integer
end;
procedure Inicia (var P: Pila);
function EsVacia (P: Pila): Boolean;
procedure Apilar (var P: Pila; E: tInfo);
procedure Desapilar (var P: Pila);
procedure Cima (P: Pila; var E: tInfo);
IMPLEMENTACIÓN ESTÁTICA
implementation
procedure Inicia;
begin
P.ultimo := 0
end;
function EsVacia;
begin
EsVacia:= P.ultimo = 0;
end;
procedure Error (n: integer);
{procedimiento oculto que sólo se ve en el
módulo}
begin
case n of
1: writeln (‘Error: Pila llena.’);
2: writeln (‘Error: Pila vacía.’);
end; {case}
readln
end;
IMPLEMENTACIÓN ESTÁTICA
implementation (continúa...)
procedure Apilar;
begin
if P.ultimo = Max then Error (1)
else
begin
P.ultimo := P.ultimo +1;
P.Elementos [P.ultimo] := E
end
end;
procedure Desapilar;
begin
if EsVacia (P) then Error (2)
else P.ultimo := P.ultimo - 1;
end;
procedure Cima;
begin
if EsVacia (P) then Error (2)
else E := P.Elementos [P.ultimo]
end;
IMPLEMENTACIÓN DINÁMICA

• La pila será un puntero a un nodo,


puntero que señala el extremo de una
lista enlazada por el que se efectúan las
operaciones de manejo de la pila:

P
TAD PILA IMPLEMENTADO CON
LISTAS ENLAZADAS
unit PDinami;
interface
type
tInfo = ...; {tipo de campo de información lista}
Ptr = ^Nodo;
Nodo = record
Info: tInfo;
Sig: Ptr
end;

procedure Inicia (var P: Ptr);


function EsVacia (P: Ptr): boolean;
procedure Apilar (var P: Ptr; E: tInfo);
procedure Desapilar (var P: Ptr);
procedure Cima (P: Ptr; var E: tInfo);
TAD PILA IMPLEMENTADO CON
LISTAS ENLAZADAS
implementation
procedure Inicia;
begin
P := nil
end;
function EsVacia;
begin
EsVacia := P = nil
end;
procedure Apilar;
var aux: ptrnodo;
begin aux
new (aux); aux

with aux^ do P
1 (1)
begin P

(1) Info := E; (3) (2)


(2) Sig := P; 15 15
end;
(3) P := aux 8 8
end;
TAD PILA IMPLEMENTADO CON
LISTAS ENLAZADAS
implementation (continúa ...)

procedure Desapilar;
var aux: Ptr; aux aux
begin P
Pila (3)
if not EsVacia(P) then (1)
begin 15 ????
(1) aux := P; (2)

(2) P := P^.Sig; 8 8
(3) dispose(aux);
end
else writeln (‘Error: Pila vacía’)
end;
procedure Cima; P
begin 3
if not EsVacia(P) then
E := P^.Info 15
else writeln (‘Error: Pila vacía’) 8
end;
APLICACIONES DE LAS PILAS

a) Eliminar la recursividad.

b) Transformar expresiones aritméticas de unas


notaciones a otras:

1. Infija: es la empleada normalmente y


requiere el uso de paréntesis para modificar
la prioridad de los operadores.
2. Prefija o polaca: es aquella en la que el
operador se coloca delante de los dos
operandos. En ella, no es necesario el uso de
paréntesis.
3. Postfija o polaca inversa: coloca el
operador a continuación de sus dos
operandos. La ventaja que ofrece es que la
expresión puede evaluarse de izquierda a
derecha recorriéndola una sola vez.
A) ELIMINAR LA
RECURSIVIDAD
• En cada llamada se añade una tabla
de activación en una pila
denominada recursiva. En esta pila
se almacenan los argumentos y
objetos locales con su valor en el
momento de producirse la llamada.

• La recursividad se puede
implementar mediante una unidad
pila. Bajo esta perspectiva la
recursividad se convierte en un par
de bucles. El primero apila, el
segundo desapila y evalúa.
EJEMPLO: FACTORIAL DE n
function factorial (n: word): real;
var
pila: Ptr;
i: word; fac: real;
begin
Inicia (pila);
{primer bucle: apila las distintas llamadas}
for i := n downto 1 do Apilar (i, pila);
{Segundo bucle: resuelve las llamadas}
fac:=1 {caso base}
while pila < > nil do
begin
fac := Cima(pila) * fac;
Desapilar(pila)
end; function factorial (n: word): real;
begin
factorial := fac
if n = 0 then factorial :=1
end; else factorial := n*factorial (n-1)
end;
B) EVALUAR EXPRESIONES
ARITMÉTICAS
• Pasos que sigue el ordenador:
a) Transformar la expresión de infija
a postfija.
b) Evaluar la expresión postfija.

• Ejemplo inverso:
a) Postfija a infija:
Postfija: AB+CD*AB-/-
Infija: ((A+B)-((C*D)/(A-B)))

B (A+B) D (C*D)
A C (A+B)
(A+B)
B) EVALUAR EXPRESIONES
ARITMÉTICAS
B (A-B) ((C*D)/(A-B))
A (C*D) (A+B)
(C*D) (A+B)
(A+B)

((A+B)-((C*D) /(A-B)))

b) Se calcularía el valor expresión


sustituyendo los correspondientes valores,
respetando el orden de operación.
ESQUEMAS RECURSIVOS
CON PILAS
uses Upila;
...
procedure X (var P);
var elem: tElem;
begin
if not EsVacia(P) then
begin
Cima (P, elem);
Desapilar (P, elem);
Desapilar (P);
Operación (elem);
X (P);
Apilar (P, elem);
end
end;
IMPLEMENTACIÓN PILAS

procedure Desapilar (var P: Ptr; var E: tInfo);


var aux: Ptr;
begin
if not EsVacia (P) then
begin
E := P^.Info;
aux := P;
P:= P^.Sig;
dispose (aux);
end
else writeln (‘Error: Pila vacía’)
end;
EJ. ESQUEMA RECURSIVO
Implementar un algoritmo en Pascal que
cuente el número de elementos de una pila de
forma recursiva sin utilizar ninguna
estructura de datos auxiliar.
a) Escribir la sección interface de la unidad Pila.
b)
function Contar (var P: Ptr): integer;
var long, elem: integer;
begin
if not EsVacia (P) then
begin
Desapilar (P, elem);
long := Contar (P) + 1;
Apilar (P, elem);
Contar := long;
end
else Contar := 0
end;
Universidad de Valladolid
Departamento de informática
Campus de Segovia

Estructura de datos
Tema 3:TAD cola

Prof. Montserrat Serrano Montero


ÍNDICE

• Definición
• Especificación del TAD
• Implementaciones estáticas
• Implementación dinámica
• Esquemas recursivos
EL TAD COLA
- Una cola es una lista de elementos, en la
cual las eliminaciones se realizan por el
frente o principio de la cola, y los nuevos
elementos son añadidos por el otro
extremo, llamado fondo o final de la cola.

- En esta estructura el primer elemento


que entra es el primero en salir, por
eso se les llama listas Fifo (First in, first
out).

- Ejs.: espectadores esperando en la


taquilla de un cine, tareas a realizar por
una impresora, etc.

- Las colas son estructuras de datos


dinámicas.
EL TAD COLA
• Especificación informal:

TAD cola (VALORES: cola de elementos;


OPERACIONES: Inicia, EsVacia, Primero, Encolar,
Desencolar);
Inicia ( ) → Cola
Efecto: Devuelve una cola vacía.
EsVacia (Cola) → Boolean
Efecto: Devuelve true si la cola está vacía y false en caso
contrario.
Primero (Cola) → Elemento
Efecto: Devuelve el Elemento Frente de la cola.
Excepción: Si la Cola está vacía produce error.
Encolar (Cola, Elemento) → Cola
Efecto: Añade un nuevo Elemento a la Cola por el Final.
Excepción: Que la cola esté llena.
Desencolar (Cola) → Cola
Efecto: Elimina el elemento Frente de la cola.
Excepción: Si la Cola está vacía produce error.
EL TAD COLA
• Especificación formal:

TAD cola (VALORES: cola de elementos;


OPERACIONES: Inicia, EsVacia, Primero, Encolar,
Desencolar)
Sintaxis:
*Inicia ( ) → Cola
EsVacia (Cola) → Boolean
Primero (Cola, Elemento) → Cola
*Encolar (Cola) → Cola
Desencolar (Cola) → Cola
Semántica:
EsVacia (Inicia ( )) ⇒ true
EsVacia (Poner (Cola, E)) ⇒ false
Primero (Inicia ( )) ⇒ error
Primero (Encolar (Cola, E)) ⇒ si EsVacia (Cola)
entonces E
si_no Primero (Cola)
Desencolar (Inicia ( )) ⇒ error
Desencolar (Encolar (Cola, E)) ⇒ si EsVacia (Cola)
then Inicia ( )
si_no Encolar (Desencolar (Cola), E)
IMPLEMENTACIÓN ESTÁTICA

unit CEstatic;
interface
const Max = ...; {especifica tamaño máximo lista}
type
Posicion = 0..Max;
tInfo = ...; {tipo de campo de información lista}
Cola = record
Elementos: array [1..Max] of tInfo;
frente, final: Posicion
end;
procedure Inicia (var C: Cola);
function EsVacia (C: Cola): boolean;
procedure Primero (C: Cola; var E: tInfo);
procedure Encolar (var C: Cola; E: tInfo);
procedure Desencolar (var C: Cola);
IMPLEMENTACIÓN ESTÁTICA
implementation

procedure Inicia;
begin
C.frente := 1;
C.final := 0
end;

function EsVacia;
begin
EsVacia := C.final < C.frente
end;

function EsLlena (C: Cola): boolean;


begin
EsLlena := C.final = Max
end;

procedure Primero;
begin
if not EsVacia (C) then
E := C.Elementos [C.frente]
end;
IMPLEMENTACIÓN ESTÁTICA
implementation (continúa...)

procedure Encolar;
begin
if not EsLlena (C) then
with C do
begin
final := final +1;
Elementos [final] := E
end
end;
procedure Desencolar;
begin
if not EsVacia (C) then
begin
for i:= 1 to C.final-1 do
C.Elementos [i] := C.Elementos [i+1];
C.final:=C.final-1;
end
end;
end.
IMPLEMENTACIÓN CIRCULAR
unit CCEstatic;
interface
const long = ...; {especifica tamaño máximo lista}
type
Posicion = 0..long;
tInfo = ...; {tipo de campo de información lista}
Cola = record
Elementos: array [1..long] of tInfo;
frente, final: Posicion
end;
procedure Inicia (var C: Cola);
function EsVacia (C: Cola): boolean;
function Primero (C: Cola): tInfo;
procedure Encolar (E: tInfo; var C: Cola);
procedure Desencolar (var C: Cola);

Es preferible esta implementación porque no se


desplazan los elementos del array, al suprimir el
primer elemento de la cola, como ocurre en la
implementación lineal.
TAD COLA IMPLEMENTADO CON
ARRAY CIRCULAR
implementation
function Siguiente (P: integer): integer;
begin
Siguiente := (P mod long) + 1
end;
procedure Inicia;
begin
C.frente := 1;
C.final := long;
end;
function EsVacia;
begin
EsVacia := Siguiente (C.final) = C.frente
end;
function EsLlena(C: Cola): boolean;
begin
EsLlena :=
Siguiente(Siguiente(C.final)) = C.frente
end;
TAD COLA IMPLEMENTADO CON
ARRAY CIRCULAR
implementation (continúa...)
function Primero;
begin
if not EsVacia (C) then
Primero := C.Elementos[C.frente]
end;
procedure Encolar;
begin
if not EsLlena (C) then
with C do
begin
final := Siguiente (final);
Elementos [final] := E
end
end;
procedure Desencolar;
begin
if not EsVacia (C) then
C.frente := C.frente + 1
end;
end.
IMPLEMENTACIÓN DEL TAD
COLA CON LISTAS ENLAZADAS
unit CDinamic;
interface
type
tInfo = ...; {tipo de campo de información lista}
Ptr = ^Nodoc;
Nodoc = record Frente Final
Info: tInfo;
Sig: Ptr
end;
Cola = record
frente, final: Ptr
end;
procedure Inicia (var C: Cola);
function EsVacia (C: Cola): boolean;
procedure Primero (C: Cola; var E: tInfo);
procedure Desencolar (var C: Cola);
procedure Encolar (var C: Cola; E: tInfo);
TAD COLA IMPLEMENTADO CON
LISTAS ENLAZADAS
implementation

procedure Inicia;
begin
C.frente := nil;
C.final := nil
end;

function EsVacia;
begin
EsVacia := C.frente = nil
end;

procedure Primero;
begin
if not EsVacia (C) then
E := C.frente^.Info
end;
TAD COLA IMPLEMENTADO CON
LISTAS ENLAZADAS
implementation (continúa...)

procedure Desencolar;
var A: ptr;
begin
if not EsVacia (C) then
with C do
begin
A:= frente;
frente := frente^.Sig;
if frente = nil then final := nil;
dispose (A);
end
end;
TAD COLA IMPLEMENTADO CON
LISTAS ENLAZADAS
implementation (continúa...)
function Crea (E: tInfo): Ptr;
var A: ptr;
begin
new (A);
A^.Info:= E;
A^.Sig := nil;
Crea := A
end;
procedure Encolar;
var N: ptr;
begin
N := Crea (E)
with C do
begin
if EsVacia (C) then frente := N
else final^.Sig := N;
final := N;
end
end;
end.
ESQUEMAS RECURSIVOS CON
COLAS
uses Ucola;
...
procedure X (var C);
var elem: tInfo;
begin
if not EsVacia (C) then
begin
elem := Primero (C);
Desencolar (C, elem)
Desencolar (C);
Operación (elem);
X (C);
Encolar (C, elem);
end
end;
ESQUEMAS RECURSIVOS CON
COLAS
Ejemplo:
Dado el TAD Cola de enteros se pide
implementar una operación que invierta el
contenido de una Cola.
a) Escribir la sección interface de la unidad
cola.
b)
procedure Invertir (var C: Cola);
var elem: integer;
begin
if not EsVacia (C) then
begin
Desencolar (C, elem);
Invertir (C);
Encolar (C, elem)
end
end;

También podría gustarte