Update PEC6

This commit is contained in:
Manuel Vergara 2024-06-18 20:09:14 +02:00
parent 3333040be4
commit 7a8e9b99f4

View File

@ -7,24 +7,21 @@
- [18. Tipos abstractios de datos](#18-tipos-abstractios-de-datos) - [18. Tipos abstractios de datos](#18-tipos-abstractios-de-datos)
- [18.1. Tipo abstracto de datos (TAD)](#181-tipo-abstracto-de-datos-tad) - [18.1. Tipo abstracto de datos (TAD)](#181-tipo-abstracto-de-datos-tad)
- [18.1.1. Ejemplos de especificación e implementación](#1811-ejemplos-de-especificación-e-implementación) - [18.1.1. Ejemplos de especificación e implementación](#1811-ejemplos-de-especificación-e-implementación)
- [18.1.1.1 Ejemplo con números naturales](#18111-ejemplo-con-números-naturales) - [18.1.1.1. Números naturales](#18111-números-naturales)
- [18.1.1.2 Ejemplo con números binarios](#18112-ejemplo-con-números-binarios) - [18.1.1.2. Números binarios](#18112-números-binarios)
- [18.2 TAD para representar secuencias de elementos](#182-tad-para-representar-secuencias-de-elementos) - [18.2. TAD para representar secuencias de elementos](#182-tad-para-representar-secuencias-de-elementos)
- [18.2.1. El TAD Pila (tStack)](#1821-el-tad-pila-tstack) - [18.2.1. El TAD Pila (tStack)](#1821-el-tad-pila-tstack)
- [18.2.1.1. Definición](#18211-definición) - [18.2.1.1. Lista de operaciones sobre tStack](#18211-lista-de-operaciones-sobre-tstack)
- [18.2.1.2. Operaciones](#18212-operaciones) - [18.2.1.2. Implementación](#18212-implementación)
- [18.2.1.3. Implementación](#18213-implementación) - [18.2.1.3. Ejemplo de uso](#18213-ejemplo-de-uso)
- [18.2.1.4 Ejemplo de uso](#18214-ejemplo-de-uso)
- [18.2.2. El TAD Cola (tQueue)](#1822-el-tad-cola-tqueue) - [18.2.2. El TAD Cola (tQueue)](#1822-el-tad-cola-tqueue)
- [18.2.2.1. Definición](#18221-definición) - [18.2.2.1. Lista de operaciones sobre tQueue](#18221--lista-de-operaciones-sobre-tqueue)
- [18.2.2.2. Operaciones](#18222-operaciones) - [18.2.2.2. Implementación](#18222-implementación)
- [18.2.2.3. Implementación](#18223-implementación) - [18.2.2.3. Ejemplo de uso](#18223-ejemplo-de-uso)
- [18.2.2.4 Ejemplo de uso](#18224-ejemplo-de-uso)
- [18.2.3. El TAD Lista (tList)](#1823-el-tad-lista-tlist) - [18.2.3. El TAD Lista (tList)](#1823-el-tad-lista-tlist)
- [18.2.3.1. Definición](#18231-definición) - [18.2.3.1. Lista de operaciones sobre tList](#18231--lista-de-operaciones-sobre-tlist)
- [18.2.3.2. Operaciones](#18232-operaciones) - [18.2.3.2. Implementación](#18232-implementación)
- [18.2.3.3. Implementación](#18233-implementación) - [18.2.3.3. Ejemplo de uso](#18233-ejemplo-de-uso)
- [18.2.3.4 Ejemplo de uso](#18234-ejemplo-de-uso)
- [18.2.4. Sintaxis para la declaración (Definición de un TAD de tipo pila, cola o lista)](#1824-sintaxis-para-la-declaración-definición-de-un-tad-de-tipo-pila-cola-o-lista) - [18.2.4. Sintaxis para la declaración (Definición de un TAD de tipo pila, cola o lista)](#1824-sintaxis-para-la-declaración-definición-de-un-tad-de-tipo-pila-cola-o-lista)
- [19. Navegación de TAD](#19-navegación-de-tad) - [19. Navegación de TAD](#19-navegación-de-tad)
- [19.1. Ejemplos sobre el TAD pila](#191-ejemplos-sobre-el-tad-pila) - [19.1. Ejemplos sobre el TAD pila](#191-ejemplos-sobre-el-tad-pila)
@ -34,81 +31,896 @@
## 18. Tipos abstractios de datos ## 18. Tipos abstractios de datos
Vamos a ver los tipos abstractos de datos (TAD) y cómo se pueden implementar para representar secuencias de elementos como Listas, Colas y Pilas. Estos TADs emulan conceptos que encontramos fuera del mundo de la programación.
Unos ejemplos son:
- De listas: una lista de la compra, una lista de tareas pendientes, una lista de reproducción de música.
- De colas: una cola de espera en un supermercado, una cola de espera en una llamada telefónica.
- De pilas: una pila de platos, una pila de libros, una pila de cartas.
Todos los TADs tienen una serie de operaciones que se pueden realizar sobre ellos. Por ejemplo, una pila tiene operaciones como `push` y `pop`, una cola tiene operaciones como `enqueue` y `dequeue`, y una lista tiene operaciones como `insert` y `delete`.
### 18.1. Tipo abstracto de datos (TAD) ### 18.1. Tipo abstracto de datos (TAD)
Un TAD consiste en un conjunto de valores (dominio) y el conjunto de operaciones que se pueden aplicar a este conjunto de valores.
El concepto de TAD ya existe en los lenguajes de programación bajo la forma de tipos predefinidos como `int`, `float`, `char`, `string`, etc. Pero también podemos definir nuestros propios TADs. Por ejemplo, en C, el tipo de datos `int` tiene como dominio todos los enteros en el rango `[MININT, MAXINT]` y las operaciones que se pueden aplicar: suma, resta, producto, cociente y módulo.
Implementar una TAD significa elegir una representación para el conjunto de valores del tipo de datos, así como codificar sus operaciones utilizando esa representación en un lenguaje de programación. Es posible tener varias implementaciones para un mismo TAD, pero dada la definición de un TAD, el comportamiento ha de ser siempre el mismo para cualquier implementación.
La utilidad de definir un TAD surge al diseñar nuevos tipos de datos. La idea es que el nuevo TAD solo puede ser manipulado a través de sus operaciones.
#### 18.1.1. Ejemplos de especificación e implementación #### 18.1.1. Ejemplos de especificación e implementación
##### 18.1.1.1. Números naturales
##### 18.1.1.1 Ejemplo con números naturales El conjunto de valores que engloba este TAD son todos los números enteros mayores o iguales a 0. Las operaciones que definiremos para aplicar a este conjunto son la `suma` y la `división`.
```alg
type
natural = integer;
end type
function suma(x: natural, y: natural): natural
return x + y;
end function
function division(x: natural, y: natural): natural
return x / y;
end function
```
```c
#include <stdio.h>
typedef unsigned int natural;
natural suma(natural x, natural y) {
return x + y;
}
natural division(natural x, natural y) {
return x / y;
}
```
En esta definición no se han excluído los números negativos. La responsabilidad del correcto comportamiento del tipo yace en la definición de las operaciones.
##### 18.1.1.2 Ejemplo con números binarios ##### 18.1.1.2. Números binarios
El conjunto de valores que engloba este TAD son todos los números en su representación binaria, es decir, expresados en base 2. Las operaciones que definiremos para aplicar a este conjunto son `desplazamientoIzq` y `complemento`.
```alg
const
MAXBITS: integer:= 64;
end const
type
binario: vector[MAXBITS] of boolean;
end type
action desplazamientoIzq(inout b:binario, in n integer)
var
i: integer;
end var
for i:= n+1 to MAXBITS do
b[i-n]:= b[i];
end for
for i:= MAXBITS-n to MAXBITS do
b[i]:= 0;
end for
end action
action complemento(inout b:binario)
var
i: integer;
end var
for i:= 1 to MAXBITS do
b[i]:= not b[i];
end for
end action
```
```c
#include <stdio.h>
#define MAXBITS 64
typedef int binario[MAXBITS];
void desplazamientoIzq(binario b, int n) {
int i;
for (i = n; i < MAXBITS; i++) {
b[i-n] = b[i];
}
for (i = MAXBITS-n; i < MAXBITS; i++) {
b[i] = 0;
}
}
void complemento(binario b) {
int i;
for (i = 0; i < MAXBITS; i++) {
b[i] = !b[i];
}
}
```
### 18.2. TAD para representar secuencias de elementos
### 18.2 TAD para representar secuencias de elementos Una secuencia lineal es un conjunto de tamaño arbitrario de elementos del mismo tipo. Exceptuando el primero y el último, cada elemento tiene un único predecesor y un único sucesor.
En general, un TAD que representa secuencias de elementos posee las siguientes operaciones:
- Inicializar la secuencia.
- Insertar un elemento en la secuencia.
- Eliminar un elemento de la secuencia.
- Consultar el valor de un elemento en la secuencia.
- Consultar el número de elementos de la secuencia.
¿Dónde insertar un elemento? ¿Qué elemento eliminar? ¿Qué elemento se puede consultar? ¿Cuántos elementos hay? Las respuestas a las anteriores preguntas son las que definen el comportamiento de las operaciones y, por lo tanto, el tipo de secuencia.
#### 18.2.1. El TAD Pila (tStack) #### 18.2.1. El TAD Pila (tStack)
- Una pila es una secuencia lineal de elementos.
- Los elementos se insertan únicamente por un extremo de la secuencia. Por eso se dice que es una estructura LIFO (Last In, First Out).
- La manipulación y acceso a los elementos de la pila se permite solo en un extremo de la secuencia.
Se puede pensar en una pila de libros dentro de una caja.
##### 18.2.1.1. Definición ##### 18.2.1.1. Lista de operaciones sobre tStack
| Operación | Descripción |
| -------------- | ------------------------------------------------------------ |
| `initStack` | Inicializa la pila. |
| `push` | Empila un elemento en la pila. |
| `pop` | Desempila un elemento de la pila. |
| `top` | Devuelve copia del valor del elemento en la cima de la pila. |
| `isEmptyStack` | Consulta si la pila está vacía (true). |
| `isFullStack` | Consulta si la pila está llena (true). |
| `heightStack` | Consulta el número de elementos de la pila. |
##### 18.2.1.2. Operaciones ##### 18.2.1.2. Implementación
Vamos a crear una implementación en un vector, donde tenemos un número máximo de elementos (MAX). Para conocer el espacio disponible de la pila en cada momento se necesita un atributo que indique el número total de elementos y que llamaremos nelem.
Implementación del tipo:
```alg
type
tStack = record
A: vector[MAX] of elem; {elem represents the type of the elements in th tStack}
nelem: integer;
end record
end type
typedef struct {
elem A[MAX];
int nelem;
} tStack;
```
Implementación de las operaciones del tipo:
Tanto la operación de apilar `push` como la de desapilar `pop`, la manipulación de elementos se realiza por el extremo final de la secuencia que es el tope de la pila.
```alg
action initStack(out s: tStack)
s.nelem:= 0;
end action
action push(inout s: tStack, in e: elem)
if s.nelem = MAX then
{error full tStack}
else
s.nelem:= s.nelem + 1;
s.A[s.nelem]:= e;
end if
end action
action pop(inout s: tStack)
if s.nelem = 0 then
{error empty tStack}
else
s.nelem:= s.nelem - 1;
end if
end action
action top(in s: tStack, out e: elem)
if s.nelem = 0 then
{error empty tStack}
else
e:= s.A[s.nelem];
end if
end action
function isEmptyStack(s: tStack): boolean
return s.nelem = 0;
end function
function isFullStack(s: tStack): boolean
return s.nelem = MAX;
end function
function heightStack(s: tStack): integer
return s.nelem;
end function
```
```c
#include <stdio.h>
#include <stdbool.h>
void initStack(tStack *s) {
s->nelem = 0;
}
void push(tStack *s, elem e) {
if (s->nelem == MAX) {
printf("\n Full Stack \n");
} else {
s->A[s->nelem] = e; /* First position in C is 0 */
s->nelem++;
}
}
void pop(tStack *s) {
if (s->nelem == 0) {
printf("\n Empty Stack \n");
} else {
s->nelem--;
}
}
void top(tStack s, elem *e) {
if (s.nelem == 0) {
printf("\n Empty Stack \n");
} else {
*e = s.A[s.nelem-1];
}
}
bool isEmptyStack(tStack s) {
return s.nelem == 0;
}
bool isFullStack(tStack s) {
return s.nelem == MAX;
}
int heightStack(tStack s) {
return (s.nelem);
}
```
##### 18.2.1.3. Implementación ##### 18.2.1.3. Ejemplo de uso
Vamos a suponer un ejemplo de una pila de libros. Cada libro dispone de un código identificador y un nombre. Definimos las estructuras de datos necesarias para modelar el ejemplo:
```alg
type
tBook = record
name: string;
id: integer;
end record
##### 18.2.1.4 Ejemplo de uso tBox = record
A: vector[MAX] of tBook;
nelem: integer;
end record
end type
```
```c
#include <stdio.h>
#define MAX_NAME_LEN = 25
typedef struct {
char[MAX_NAME_LEN] name;
int id;
} tBook;
typedef struct {
tBook A[MAX];
int nelem;
} tBox;
```
Ok. Ahora vamos a implementar una acción que dada una pila de libros y el código de un libro, encuentre este libro en la pila. En caso de encontrarlo, lo retiramos de la pila; en caso contrario, dejamos la pila como estaba.
```alg
action findBook(inout s: tBox, in id: integer)
var
b: tBook;
aux: tBox;
found: boolean;
end var
found:= false;
initStack(aux);
while not isEmptyStack(s) and not found do
top(s, b);
if b.id = id then
push(aux, b);
else
found:= true;
end if
pop(s);
end while
while not isEmptyStack(aux) do
top(aux, b);
push(s, b);
pop(aux);
end while
end action
```
```c
#include <stdio.h>
#include <stdbool.h>
void findBook(tBox *s, int id) {
tBook b;
tBox aux;
bool found;
found = false;
initStack(&aux);
while (!isEmptyStack(*s) && !found) {
top(*s, &b);
if (b.id == id) {
push(&aux, b);
} else {
found = true;
}
pop(s);
}
while (!isEmptyStack(aux)) {
top(aux, &b);
push(s, b);
pop(&aux);
}
}
```
#### 18.2.2. El TAD Cola (tQueue) #### 18.2.2. El TAD Cola (tQueue)
- Una cola es una secuencia lineal de elementos.
- Los elementos se insertan por el final de la cola y se extraen por el principio. Por eso se dice que es una estructura FIFO (First In, First Out).
- La manipulación y el acceso a los elementos de la cola solo se permite en los extremos.
##### 18.2.2.1. Definición Un ejemplo de una cola es una cola de personas esperando para comprar una entrada en la taquilla de un teatro.
##### 18.2.2.1. Lista de operaciones sobre tQueue
| Operación | Descripción |
| -------------- | -------------------------------------------------------------- |
| `initQueue` | Inicializa la cola. |
| `enqueue` | Encola un elemento en la cola. |
| `dequeue` | Desencola un elemento de la cola. |
| `head` | Devuelve copia del valor del elemento en la cabeza de la cola. |
| `isEmptyQueue` | Consulta si la cola está vacía (true). |
| `isFullQueue` | Consulta si la cola está llena (true). |
| `lengthQueue` | Consulta el número de elementos de la cola. |
##### 18.2.2.2. Operaciones ##### 18.2.2.2. Implementación
Vamos a crear una implementación en un vector, donde tenemos un número máximo de elementos (MAX). Para conocer el espacio disponible de la cola en cada momento se necesita un atributo que indique el número total de elementos y que llamaremos nelem.
Implementación del tipo:
```alg
type
tQueue = record
A: vector[MAX] of elem;
nelem: integer;
end record
end type
```
```c
typedef struct {
elem A[MAX];
int nelem;
} tQueue;
```
Implementación de las operaciones:
Los elementos se encolan por el final de la cola y se desencolan por el principio. Tened en cuenta que cada vez que se elemina un elemento se han de desplazar todos los elementos de la cola una posición a la izquierda.
```alg
action initQueue(out q: tQueue)
q.nelem:= 0;
end action
action enqueue(inout q: tQueue, in e: elem)
if q.nelem = MAX then
{error full tQueue}
else
q.nelem:= q.nelem + 1;
q.A[q.nelem]:= e;
end if
end action
action dequeue(inout q: tQueue)
var
i: integer;
end var
if q.nelem = 0 then
{error empty tQueue}
else
for i:= 1 to q.nelem-1 do
q.A[i]:= q.A[i+1];
end for
q.nelem:= q.nelem - 1;
end if
end action
action head(in q: tQueue, out e: elem)
if q.nelem = 0 then
{error empty tQueue}
else
e:= q.A[1];
end if
end action
function isEmptyQueue(q: tQueue): boolean
return q.nelem = 0;
end function
function isFullQueue(q: tQueue): boolean
return q.nelem = MAX;
end function
function lengthQueue(q: tQueue): integer
return q.nelem;
end function
```
```c
#include <stdio.h>
#include <stdbool.h>
void initQueue(tQueue *q) {
q->nelem = 0;
}
void enqueue(tQueue *q, elem e) {
if (q->nelem == MAX) {
printf("\n Full Queue \n");
} else {
q->A[q->nelem] = e; /* first position in C is 0 */
q->nelem++;
}
}
void dequeue(tQueue *q) {
int i;
if (q->nelem == 0) {
printf("\n Empty Queue \n");
} else {
for (i = 0; i < q->nelem-1; i++) {
q->A[i] = q->A[i+1];
}
q->nelem--;
}
}
void head(tQueue q, elem *e) {
if (q.nelem == 0) {
printf("\n Empty Queue \n");
} else {
*e = q.A[0];
}
}
bool isEmptyQueue(tQueue q) {
return (q.nelem == 0);
}
bool isFullQueue(tQueue q) {
return (q.nelem == MAX);
}
int lengthQueue(tQueue q) {
return (q.nelem);
}
```
##### 18.2.2.3. Implementación ##### 18.2.2.3. Ejemplo de uso
Siguiendo el ejemplo de la cola de una taquilla. Cada cliente de la cola tiene asociado el ordinal en la cola desde que abrió la taquilla y la cantidad de entradas que desea adquirir. Definimos las estructuras de datos necesarias para modelar el ejemplo:
```alg
type
tClient = record
num: integer;
quantity: integer;
end record
##### 18.2.2.4 Ejemplo de uso tTicketOffice = record
A: vector[MAX] of tClient;
nelem: integer;
end record
end type
```
```c
typedef struct {
int num;
int quantity;
} tClient;
typedef struct {
tClient A[MAX];
int nelem;
} tTicketOffice;
```
Ahora necesitamos implementar una acción que atienda el primer cliente de la cola en la taquilla. La acción recibe como parámetros la cola `q` de clientes y un número `available` que indica la disponibilidad de entradas. En caso de haber suficientes entradas disponibles, se actualiza la cantidad de entradas disponibles y se devuelve el valor verdadero en el parámetro sold. Una vez el cliente es atendido, se elimina de la cola.
```alg
action serverCliente(inout q: tTicketOffice, in available: integer, out sold: boolean)
var
c: tClient;
end var
sold:= false;
if not isEmptyQueue(q) then
head(q, c);
if c.quantity <= available then
dequeue(q);
available:= available - c.quantity;
sold:= true;
end if
dequeue(q);
end if
end action
```
```c
#include <stdio.h>
#include <stdbool.h>
void serverClient(tTicketOffice *q, int *available, bool *sold) {
tClient c;
*sold = false;
if (!isEmptyQueue(*q)) {
head(*q, &c);
if (c.quantity <= *available) {
*available -= c.quantity;
*sold = true;
}
dequeue(q);
}
}
```
#### 18.2.3. El TAD Lista (tList) #### 18.2.3. El TAD Lista (tList)
- Una lista es una secuencia lineal de elementos.
- Los elementos se insertan, se eliminan y se consultan en cualquier posición de la lista.
##### 18.2.3.1. Definición Para entender mejor el concepto de lista, podemos pensar en una lista de la compra del supermercado.
##### 18.2.3.1. Lista de operaciones sobre tList
| Operación | Descripción |
| ------------- | ----------------------------------------------------------- |
| `initList` | Inicializa la lista. |
| `insert` | Inserta un elemento en la lista. |
| `delete` | Elimina un elemento de la lista. |
| `get` | Devuelve copia del valor del elemento en la posición `i`. |
| `isEnd` | Consulta si la posición `i` es el final de la lista (true). |
| `isEmptyList` | Consulta si la lista está vacía (true). |
| `isFullList` | Consulta si la lista está llena (true). |
| `lengthList` | Consulta el número de elementos de la lista. |
##### 18.2.3.2. Operaciones ##### 18.2.3.2. Implementación
Vamos a crear una implementación en un vector, donde tenemos un número máximo de elementos (MAX). Para conocer el espacio disponible de la lista en cada momento se necesita un atributo que indique el número total de elementos y que llamaremos nelem.
Implementación del tipo:
```alg
type
tList = record
A: vector[MAX] of elem;
nelem: integer;
end record
end type
```
```c
typedef struct {
elem A[MAX];
int nelem;
} tList;
```
Implementación de las operaciones:
Los elementos se insertan en cualquier posición de la lista y se eliminan de la misma forma.
Cada vez que se inserta un elemento en una posición `i`, se han de desplazar todos los elementos de la lista una posición a la derecha. Cada vez que se elimina un elemento de una posición `i`, se han de desplazar todos los elementos de la lista una posición a la izquierda.
```alg
action initList(out l: tList)
l.nelem:= 0;
end action
action insert(inout l: tList, in e: elem, in index: integer)
var
i: integer;
end var
if l.nelem = MAX then
{error full tList}
else
for i:= l.nelem to index step -1 do
l.A[i+1]:= l.A[i];
end for
l.nelem:= l.nelem + 1;
l.A[index]:= e;
end if
end action
action delete(inout l: tList, in index: integer)
var
i: integer;
end var
if l.nelem = 0 then
{error empty tList}
else
for i:= index to l.nelem-1 do
l.A[i]:= l.A[i+1];
end for
l.nelem:= l.nelem - 1;
end if
end action
action get(in l: tList, in index: integer, out e: elem)
if l.nelem = 0 then
{error empty tList}
else
e:= l.A[index];
end if
end action
function isEnd(l: tList, pos: integer): boolean
return pos = l.nelem;
end function
function isEmptyList(l: tList): boolean
return l.nelem = 0;
end function
function isFullList(l: tList): boolean
return l.nelem = MAX;
end function
function lengthList(l: tList): integer
return l.nelem;
end function
```
```c
#include <stdio.h>
#include <stdbool.h>
void initList(tList *l) {
l->nelem = 0;
}
void insert(tList *l, elem e, int index) {
int i;
if (l->nelem == MAX) {
printf("\n Full List \n");
} else {
for (i = l->nelem; i >= index; i--) {
l->A[i+1] = l->A[i];
}
l->nelem++;
l->A[index] = e;
}
}
void delete(tList *l, int index) {
int i;
if (l->nelem == 0) {
printf("\n Empty List \n");
} else {
for (i = index; i < l->nelem-1; i++) {
l->A[i] = l->A[i+1];
}
l->nelem--;
}
}
void get(tList l, int index, elem *e) {
if (l.nelem == 0) {
printf("\n Empty List \n");
} else {
*e = l.A[index];
}
}
bool isEnd(tList l, int pos) {
return pos == l.nelem;
}
bool isEmptyList(tList l) {
return l.nelem == 0;
}
bool isFullList(tList l) {
return l.nelem == MAX;
}
int lengthList(tList l) {
return l.nelem;
}
```
##### 18.2.3.3. Implementación ##### 18.2.3.3. Ejemplo de uso
Siguiendo el ejemplo de la lista de la compra del supermercado. Cada artículo tiene asociado un nombre, el tipo de artículo clasificado según sea de panadería, frescos, bebidas, congelados, belleza o desayuno, y la cantidad de este artículo. Definimos las estructuras de datos necesarias para modelar el ejemplo:
```alg
type
tArticleType = {BAKERY, FRESH, DRINKS, FROZEN, BEAUTY, BREAKFAST}
tArticle = record
type: tArticleType;
quantity: real;
end record
##### 18.2.3.4 Ejemplo de uso tBuyList = record
A: vector[MAX] of tArticle;
nelem: integer;
end record
end type
```
```c
#include <stdio.h>
typedef enum {BAKERY, FRESH, DRINKS, FROZEN, BEAUTY, BREAKFAST} tArticleType;
typedef struct {
tArticleType type;
float quantity;
} tArticle;
typedef struct {
tArticle A[MAX];
int nelem;
} tBuyList;
```
Necesitamos implementar una acción que elimine de la lista de la compra `l`, todos los artículos de un tipo dado (filter) que se recibe como parámetro.
```alg
action filterArticleType(inout l: tBuyList, in filter: tArticleType)
var
a: tArticle;
pos: integer;
end var
pos := 1;
while not isEnd(l, pos) do
get(l, pos, a);
if a.type = filter then
delete(l, pos);
else
pos := pos + 1;
end if
end while
end action
```
```c
#include <stdio.h>
void filterArticleType(tBuyList *l, tArticleType filter) {
elem a;
int pos;
pos = 0;
while (!isEnd(*l, pos)) {
get(*l, pos, &a);
if (a.type == filter) {
delete(l, pos);
} else {
pos = pos + 1;
}
}
}
```
#### 18.2.4. Sintaxis para la declaración (Definición de un TAD de tipo pila, cola o lista) #### 18.2.4. Sintaxis para la declaración (Definición de un TAD de tipo pila, cola o lista)
Para declarar un tipo pila dentro de un algoritmo, acción o función, se utiliza la siguiente sintaxis:
```alg
nombreTipoPila = tStack(tipoElemento)
```
por ejemplo, `tBinaryStack = tStack(tBit)` permite declarar el tipo tBinaryStack como un tipo de pila de elementos de tipo tBit. A partir de aquí, se le pueden aplicar todas las operaciones que se han definido para las pilas.
Como véis, en lenguaje algorítmico, la declaración queda como un tipo abstracto (su implementación es "oculta") pero en cambio, en lenguaje C, sí que se "ve" su implementación interna:
```c
typedef struct{
tBit A[MAXBITS];
int nelem;
} tBinaryStack;
```
A partir de aquí, solo se debe utilizar con las funciones y acciones predefinidas para este tipo. De este modo, realmente lo estamos utilizando como un tipo abstracto pila.
De forma similar se puede declarar una cola o una lista:
```alg
nombreTipoCola = tQueue(tipoElemento)
nombreTipoLista = tList(tipolemento)
```
## 19. Navegación de TAD ## 19. Navegación de TAD