32
 ALGORITMOS Y ESTRUCTURAS DE DATOS - 92 - CAPÍTULO 8  E  STRUCTURAS  D  INÁMICAS  L  INEALES  INTRODUCCIÓN En capítulos anteriores se han desarrollado las estructuras de datos estáticas. Éstas permiten el manejo de un gran volumen de datos bajo un solo identificador, pero están limitadas a la declaración inicial en cuanto a su tamaño. A partir de este capítulo se comenzarán a estudiar las estructuras de datos dinámicas, comen- zando por aquellas de organización lineal. Estas estructuras de datos permiten manejar en forma diná- mica (de allí su nombre) al conjunto de datos, por lo que no requieren la definición del espacio de me- moria al momento de programar. El uso dinámico de la memoria permite crear estructuras de datos que se adapten a las necesi- dades reales de los programas. Como veremos, estas estructuras de datos son muy flexibles, ya sea en cuanto al orden, la estructura interna o las relaciones entre los elementos que las componen. Para su construcción, se requiere el uso de apuntadores : un tipo de dato que permite almacenar la ubicación de otro dato; una estructura de datos llamada registro: una colección de datos que constitu- yen un nuevo tipo de datos y la implementación física de un tipo abstracto de datos. Estos elementos son necesarios para la implementación de las estructuras dinámicas. En cuanto a la clasificación de las estructuras de datos dinámicas , las hay lineales y no lineales. Esta clasificación hace referencia al orden de acceso a los elementos que la constituyen. En este capítulo, se tratarán exclusivamente las lineales  pilas, colas  y distintos tipos de listas. Comenzaremos por los conceptos de registro, tipo abstracto de datos y puntero, necesarios és- tos para la implementación de cualquier estructura dinámica.

estructuras dinamicas lineales

Embed Size (px)

Citation preview

5/8/2018 estructuras dinamicas lineales - slidepdf.com

http://slidepdf.com/reader/full/estructuras-dinamicas-lineales 1/32

 

ALGORITMOS Y ESTRUCTURAS DE DATOS 

- 92 -

CAPÍTULO 8 

 E  STRUCTURAS  D INÁMICAS  L INEALES  

INTRODUCCIÓN 

En capítulos anteriores se han desarrollado las estructuras de datos estáticas. Éstas permiten elmanejo de un gran volumen de datos bajo un solo identificador, pero están limitadas a la declaracióninicial en cuanto a su tamaño.

A partir de este capítulo se comenzarán a estudiar las estructuras de datos dinámicas, comen-zando por aquellas de organización lineal. Estas estructuras de datos permiten manejar en forma diná-mica (de allí su nombre) al conjunto de datos, por lo que no requieren la definición del espacio de me-moria al momento de programar.

El uso dinámico de la memoria permite crear estructuras de datos que se adapten a las necesi-

dades reales de los programas. Como veremos, estas estructuras de datos son muy flexibles, ya sea encuanto al orden, la estructura interna o las relaciones entre los elementos que las componen.

Para su construcción, se requiere el uso de apuntadores: un tipo de dato que permite almacenar la ubicación de otro dato; una estructura de datos llamada registro: una colección de datos que constitu-yen un nuevo tipo de datos y la implementación física de un tipo abstracto de datos. Estos elementosson necesarios para la implementación de las estructuras dinámicas.

En cuanto a la clasificación de las estructuras de datos dinámicas, las hay lineales y no lineales.Esta clasificación hace referencia al orden de acceso a los elementos que la constituyen.

En este capítulo, se tratarán exclusivamente las lineales pilas, colas y distintos tipos de listas.

Comenzaremos por los conceptos de registro, tipo abstracto de datos y puntero, necesarios és-

tos para la implementación de cualquier estructura dinámica.

5/8/2018 estructuras dinamicas lineales - slidepdf.com

http://slidepdf.com/reader/full/estructuras-dinamicas-lineales 2/32

 

ALGORITMOS Y ESTRUCTURAS DE DATOS 

- 93 -

8.1  ESTRUCTURAS DINÁMICAS 

Una limitación que se presenta con las estructuras de datos estáticas es la necesidad de conocer la cantidad de datos a procesar al momento de programar, para asignar el espacio de memoria. Esto raravez sucede y además, para distintas ejecuciones la cantidad de datos puede variar. Ante esta dificultad,las estructuras dinámicas no requieren la definición del espacio de memoria, a éstas se asigna el espaciodurante la ejecución del programa.

Una estructura de datos es dinámica cuando la asignación del espacio de memoria requerido se realiza durante la ejecución del programa. Esto permite que la estructura ocupe más o menos espa-cio de memoria de acuerdo a la necesidad de datos durante la ejecución del programa.

Existen diferencias claras respecto de los arreglos:

-  En la declaración no se indica una cantidad máxima de elementos, puesto que esto varía du-

rante la ejecución del programa.-  El conjunto de elementos que constituye la estructura, no necesita de un espacio contiguo dememoria.

-  No se utiliza un índice para referenciar a los elementos, sino un puntero.-  Existen limitaciones en cuanto al acceso a los datos: el acceso a los elementos de las estruc-

turas dinámicas lineales es únicamente secuencial .

Para la implementación de estas estructuras es necesario conocer previamente algunos concep-tos no vistos hasta el momento: registro (un tipo de datos definido por el programador), tipo abstractode datos (una herramienta con la que se especifican datos y operaciones válidas con ellos) y  punteros (un tipo de datos especial que se utiliza para almacenar direcciones de memoria).

Estos serán los temas a tratar previo a la construcción de estructuras de datos dinámicas.

8.2  LA ESTRUCTURA R EGISTRO 

Constituye uno de los tipos de datos estructurados más utilizados. Permite agrupar datos de dis-tintos tipos con cierta conexión lógica bajo una estructura única. Por ejemplo, los datos correspondien-tes a un alumno pueden consistir de una matrícula, un número de documento, su nombre, su domicilio,su fecha de nacimiento, una dirección de correo electrónico y un promedio de notas. Esto puede involu-crar datos de distintos tipos (cadenas de caracteres, números enteros, números reales). Este tipo de datoslo debe definir el programador según las necesidades del algoritmo (de hecho, el registro es un tipo dedatos definido por el programador).

Definiremos Registro, como una estructura compuesta de un conjunto de valores con las si-guientes características:

-  Los valores pueden ser de distintos tipos, es decir, es una estructura heterogénea.

-  Los valores almacenados en un registro se llaman campos y cada uno tiene un identificador (un nombre, similar a una variable).

-  El espacio de memoria ocupado por un registro es fijo, esto lo convierte en una estructuraestática.

En el apartado 3.2 (Partes de un programa) se vio que la primera parte está reservada para la de-claración de tipos de datos no estándares. El registro constituye un tipo de datos no estándar, por lo quedeberá declararse en este espacio.

8.2.1  DECLARACIÓN DE R EGISTROS Para la declaración utilizaremos la palabra reservada tipo en nuestro pseudocódigo. La decla-

5/8/2018 estructuras dinamicas lineales - slidepdf.com

http://slidepdf.com/reader/full/estructuras-dinamicas-lineales 3/32

 

ALGORITMOS Y ESTRUCTURAS DE DATOS 

- 94 -

ración requiere un identificador (nombre para el tipo) y un cierre con la indicación fintipo.

Entre el encabezado de la declaración y el cierre se declaran los campos que lo constituyen, ca-da uno como una declaración de variables. Tomemos como ejemplo el dado para un tipo llamado alum-

no, mencionado anteriormente:tipo alumno

real matricula

caracter documento[8]

caracter nombre[20]

caracter domicilio[25]

caracter fecha_nac[10]

caracter e_mail[25]

real promedio

fintipo

Una vez que se declaró al nuevo tipo de datos, éste se agrega a los ya conocidos tipos simplesestándar, por lo que la declaración de una variable (llamémosla alum) de tipo alumno, se hará:

variables

alumno alu

Podemos ver a esta estructura de la siguiente forma:alu

Cuando sea necesario hacer referencia a un componente (campo) de la estructura alumno enla variable alu es necesario nombrar a la variable, y para hacer referencia al campo se usa un punto y elnombre del campo. Por ejemplo, para asignar datos de un alumno a la estructura haremos:

alu.matricula ← ‘94879’

alu.documento ← ‘12345678’

alu.nombre ← ‘Juan Gomez’

alu.domicilio ← ‘9 de Julio 1245’

alu.fecha_nac ← ‘10/12/1940’

alu.e_mail ← ‘[email protected]

alu.promedio ← 8,75

Una vez que los datos se han almacenado, podemos imaginar que esta estructura puede verseasí:alu 94879 12345678 Juan Gomez 9 de Julio 1245 10/12/1940 [email protected] 8,75

Donde toda la estructura se almacena bajo el nombre alu. Cuando se quiere utilizar uno de los

componentes se deberá hacer referencia al nombre de la variable (alu) y al del campo correspondiente,como cuando se almacenaron los datos. Esta estructura no es un arreglo.

Finalmente, la fecha de nacimiento de los alumnos, también pueden considerarse como estruc-turas compuestas por día, mes y año. En este caso, declararemos primero la estructura fecha y lue-go la utilizaremos en la declaración de la estructura alumno:

tipo fecha

entero dia

entero mes

entero año

fintipo

tipo alumno

real matricula

caracter documento[8]

5/8/2018 estructuras dinamicas lineales - slidepdf.com

http://slidepdf.com/reader/full/estructuras-dinamicas-lineales 4/32

 

ALGORITMOS Y ESTRUCTURAS DE DATOS 

- 95 -

caracter nombre[20]

caracter domicilio[25]

fecha fecha_nac

caracter e_mail[25]

real promedio

fintipo

Obsérvese que es necesario declararlas en el orden indicado: primero el tipo fecha y luego eltipo alumno ya que la estructura fecha se utiliza en la estructura alumno.

8.3  TIPO ABSTRACTO DE DATOS

Una de las tareas de todo programador es la abstracción de datos. Esto implica caracterizar ob- jetos del mundo real de tal forma que puedan ser implementados en un programa. En la programaciónestructurada, esta abstracción se logra identificando atributos mensurables que pueden ser representados

a través de datos y atributos funcionales que caracterizan a su comportamiento.Un objeto del mundo real no puede ser representado por datos de tipo simple. Por ejemplo, el

tipo alumno del ejemplo anterior requiere una estructura de datos. Pero la estructura declarada no essuficiente, también se debe programar las operaciones que un alumno real puede realizar, como ser matricularse, rendir exámenes, calcular su promedio. Es evidente que la estructura de datos y las opera-ciones programadas forman un conjunto.

Así, la representación de un objeto del mundo real en un algoritmo requiere un tipo de datos de-finido por el programador más la programación de las operaciones que el objeto puede realizar. Esteconjunto se denomina tipo abstracto de datos.

Luego, un tipo abstracto de datos incluye:

-  La especificación de la estructura de datos que representa a los elementos del tipo.-  La especificación de las operaciones permitidas sobre el tipo.-  El tratamiento de ambos elementos como una unidad.

Entonces, definimos tipo abstracto de datos como un conjunto conformado por un tipo de datosdefinido por el programador más un conjunto de operaciones definidas sobre ese tipo que le otorgan

una funcionalidad . Lo define el programador según las necesidades del programa.

 No debe confundirse los conceptos de tipo de datos, tipo abstracto de datos y estructura de da-tos. Son tres conceptos distintos.

Un tipo de datos es un conjunto de datos con características similares vinculados a un conjuntode operaciones para manipularlos que tienen una representación interna en la máquina.

Un tipo abstracto de datos es un modelo conceptual conformado por un tipo de datos definido por el programador más un conjunto de operaciones definidas sobre ese tipo a través de módulos decódigo.

Una estructura de datos  , es la implementación física de un tipo abstracto de datos utilizandouna colección de datos de tipo simple u otra estructura. 

Como puede deducirse, un tipo abstracto de datos constituye el resultado de una abstracción delmundo real que debe implementarse con una estructura de datos. Puede decirse que es un concepto quedebe ser implementado en su totalidad: los almacenes de datos y la funcionalidad requerida.

Las pilas, colas, listas y los árboles constituyen tipos abstractos de datos que serán tratados a partir de este capítulo.

La máxima expresión de este concepto se encuentra en la programación orientada a objetos. Enella los objetos del mundo real se modelan a través de tipos abstractos de datos constituidos por atribu-

5/8/2018 estructuras dinamicas lineales - slidepdf.com

http://slidepdf.com/reader/full/estructuras-dinamicas-lineales 5/32

 

ALGORITMOS Y ESTRUCTURAS DE DATOS 

- 96 -

tos de los objetos reales (elementos de datos) y funciones que los manipulan (código de control), encap-sulados en unidades llamadas clases. Durante la ejecución del programa, los objetos se generan dinámi-camente en base a las clases.

8.4  PUNTEROS 

Como los elementos de las estructuras dinámicas de datos no necesariamente se almacenan enforma contigua en la memoria, se necesita conocer su ubicación. Esta ubicación está dada por una di-rección numérica especial en la memoria de la máquina. Las direcciones de memoria no están constitui-das por números enteros ni reales, tienen un tratamiento especial (tema no contemplado en este mate-rial). Cada celda de memoria posee su propia dirección de memoria.

Así, almacenado un dato en la memoria, éste puede ser ubicado a través de su dirección de me-moria. De hecho, una variable es una representación simbólica de la ubicación de memoria donde seguardan datos. La dirección de memoria a su vez, puede ser almacenada en una variable especial: un

 puntero.Un puntero es un tipo de variable, en la que se almacena la dirección de memoria de otra va-

riable o el valor especial  Null que indica que el puntero no tiene almacenado ninguna dirección válidade memoria.

Por ser una variable, debe ser declarado en el espacio de declaraciones de variables; pero a dife-rencia de éstas, en su declaración se antepondrá una ↑ al nombre dado. Todo puntero contiene ademásinformación sobre el tipo de datos al cual apunta, por lo tanto, se lo declara de un cierto tipo de datos.El puntero solo podrá apuntar a datos del tipo indicado en su declaración. La siguiente es una declara-ción válida para un puntero que apunta a datos de tipo entero:

entero ↑p

Que indica la declaración de un puntero de nombre p que podrá apuntar a datos de tipo entero.Sin embargo, el puntero p no puede recibir datos, solo direcciones de memoria.

Cómo se logra una dirección válida de memoria para almacenar datos. Los lenguajes de pro-gramación que soportan la asignación dinámica de memoria proveen de una acción específica para ello.En nuestro pseudocódigo, esta operación se hará con la palabra reservada nuevo, una función que re-quiere la indicación del tipo de datos a almacenar y cuyo resultado es una dirección de memoria libre oel valor  Null si no se encuentra:

p ← nuevo(entero)

El resultado de esta operación es la asignación al puntero p de una dirección de memoria libreen la que podrá almacenarse números enteros, o bien el valor  Null que indica que no se encontró un

espacio libre para datos.Gráficamente, esta situación se representa de la siguiente forma:

p

El esquema representa a un puntero p apuntando a un espacio de memoria asignado por la fun-ción nuevo en el que se podrá almacenar los datos, estos últimos deben ser del mismo tipo al indicadoen la declaración del puntero y en la solicitud de memoria (en el ejemplo el tipo es entero). Decimosque este espacio de memoria fue asignado dinámicamente durante la ejecución del programa, mientrasque el puntero ocupa un espacio estático de memoria.

Un puntero que no tiene asignado una dirección de memoria, no puede ser utilizado para alma-

cenar datos.

5/8/2018 estructuras dinamicas lineales - slidepdf.com

http://slidepdf.com/reader/full/estructuras-dinamicas-lineales 6/32

 

ALGORITMOS Y ESTRUCTURAS DE DATOS 

- 97 -

8.4.1  OPERACIONES CON PUNTEROS 

Supongamos las siguientes declaraciones de punteros:entero ↑p, ↑q 

Es válida la operación de solicitud de memoria para datos de tipo entero y asignar la direcciónde memoria devuelta a uno de ellos:

p ← nuevo(entero) 

a partir de esta operación, es válida la siguiente:

q ← p 

ésta indica que también el punteo q apuntará al espacio de memoria asignado en la operación anterior, podemos graficarlo de la siguiente manera:

p

q

Es válido tener varios punteros señalando al mismo dato.

Otra acción válida es asignar el valor  Null a un puntero, sin embargo será necesario que otro  puntero posea almacenada la dirección de memoria asignada dinámicamente, caso contrario el datoalmacenado se perderá:

q ← Null 

el resultado de esta operación lo podemos graficar de la siguiente manera:

p

q

donde p apunta al espacio de memoria asignado dinámicamente, mientras q no posee una direcciónválida de memoria (representada con la en el puntero), es decir, su valor es Null . No debe asignarse aambos punteros el valor  Null , ya que en ese caso se perderá el espacio de memoria asignado dinámica-mente.

Pero NO será válida la siguiente acción:

p ← 4 

Para almacenar un dato en el espacio de memoria asignado dinámicamente, se deberá utilizar eloperador de direccionamiento: ↑. Luego, para asignar un valor a la celda de memoria apuntada por p sedeberá escribir la siguiente acción:

p↑ ← 4 

esto dará el siguiente resultado:p

Finalmente, el espacio asignado dinámicamente con la función nuevo deberá ser liberado an-tes de la finalización de la ejecución del programa. La función nuevo, es una interacción entre el pro-grama que realiza la solicitud de espacio de memoria y el sistema operativo. El espacio de memoriaasignado dinámicamente queda indicado en tablas del sistema operativo como espacio de memoria ocu- pado, por lo que antes de finalizar la ejecución del programa que realizó la solicitud, éste deberá liberar-lo, así el sistema operativo lo señalará en sus tablas como espacio libre. Si el programa finaliza y elespacio asignado dinámicamente no se libera, el sistema operativo lo seguirá registrando como espacioocupado aunque ningún programa lo esté usando: el resultado es espacio de memoria que no se puede

utilizar. Para liberar el espacio de memoria asignado dinámicamente utilizaremos la acción libe-

rar(puntero), una interacción entre el programa que utiliza la asignación dinámica y el sistema

5/8/2018 estructuras dinamicas lineales - slidepdf.com

http://slidepdf.com/reader/full/estructuras-dinamicas-lineales 7/32

 

ALGORITMOS Y ESTRUCTURAS DE DATOS 

- 98 -

operativo, para que este último actualice sus tablas indicando que el espacio de memoria señalado por el puntero se encuentra ahora disponible.

La acción liberar(puntero), asigna al puntero el valor  Null y se escribe:

liberar(p) Si bien el puntero asume el valor  Null después de liberarse el espacio de memoria asignado di-

námicamente, el resultado obtenido no es el mismo que se obtiene asignando este valor al puntero. En el primer caso, se libera el espacio de memoria dinámico y se asigna el valor  Null al puntero, en el segun-do caso solo se asigna el valor  Null al puntero, pero el espacio de memoria asignado dinámicamente nose ha liberado (se pierde su dirección de memoria).

Con lo que se ha desarrollado hasta el momento sobre el uso de punteros y asignación dinámicade memoria, puede observarse que no se obtienen ventajas respecto del uso de variables estáticas, yaque además del espacio asignado dinámicamente para el dato es necesario un espacio para el puntero. Sinecesitáramos almacenar diez datos, sería necesario declarar diez punteros, ya que cada puntero puedealmacenar a lo sumo una dirección de memoria y no se estaría haciendo uso eficiente de esta.

Como el puntero solo puede apuntar a un dato, se necesita un mecanismo capaz de crearlos di-námicamente junto al espacio para almacenar datos. Esto significa que, al solicitar espacio de memoria para almacenar datos, también se debe solicitar espacio para un nuevo puntero. De esta forma siemprehabrá un puntero libre al cual se podrá asignar otra dirección de memoria. De todas formas será necesa-rio declarar al menos un puntero en forma estática al cual asignar la dirección de memoria del primer  bloque. Esto lo podemos representar de la siguiente forma:

p

donde la parte en gris junto a los datos representa a un puntero. De esta forma es posible solicitar otroespacio de memoria similar y asignar su dirección a este puntero, representado de la siguiente forma:

p

El puntero p apunta a un espacio de memoria compuesto por datos y un puntero, este últimotambién apunta a otra estructura similar. El último puntero posee el valor  Null , aquí representado con la indicando el final de la estructura. Obsérvese que enlazando de esta forma estructuras compuestas por datos y punteros obtenidos dinámicamente, la única limitación es el total de espacio de memoriadisponible (espacio libre de memoria). El último esquema representa a la estructura lista enlazada sim-

 ple, una de las estructuras dinámicas lineales que estudiaremos en este capítulo.

8.4.2  NODO 

Para la construcción de las estructuras dinámicas, durante la ejecución del programa es necesa-rio solicitar espacios de memoria para datos y punteros, y enlazarlos como en el esquema anterior. Cadacomponente de la estructura completa es, a su vez, una estructura compuesta por un espacio para datosy uno o más punteros. A los elementos componentes de las estructuras dinámicas los llamamos nodos.

Entonces, definimos nodo a cada elemento de una estructura dinámica que se construye en ba- se a una estructura de registro formada por campos de datos y uno o más punteros. Estos elementos se

 generan dinámicamente durante la ejecución del programa.p

  puntero nodo 

Para su creación, será necesario declarar un nuevo tipo de datos: un registro formado por datos

(de cualquiera de los tipos conocidos) y al menos un puntero a otro nodo. Supongamos que se necesitauna estructura para almacenar datos de alumnos tal como se ejemplificó antes en este capítulo en elapartado registros. Al tipo alumno se deberá agregar un puntero (de tipo alumno):

5/8/2018 estructuras dinamicas lineales - slidepdf.com

http://slidepdf.com/reader/full/estructuras-dinamicas-lineales 8/32

 

ALGORITMOS Y ESTRUCTURAS DE DATOS 

- 99 -

tipo fecha

entero dia

entero mes

entero año

fintipo

tipo alumno

real matricula

caracter documento[8]

caracter nombre[20]

caracter domicilio[25]

fecha fecha_nac

caracter e_mail[25]

real promedio

alumno ↑sgte

fintipo

Para almacenar datos de un alumno, se necesita un espacio de memoria de tipo alumno y paraalmacenar su dirección será necesario un puntero (también de tipo alumno):

variables

alumno ↑alu

En el cuerpo principal del algoritmo, se solicita espacio de memoria para almacenar datos de unalumno. Si la solicitud de espacio de memoria no falló, ahora se puede almacenar datos en el nodo:

Inicio

alu ← nuevo(alumno)

si (alu <> Null) entonces

leer(alu↑matricula) leer(alu↑documento) leer(alu↑nombre) leer(alu↑domicilio) leer(alu↑fecha_nac.dia, alu↑fecha_nac.mes, alu↑fecha_nac.año) leer(alu↑e_mail) leer(alu↑promedio)alu↑sgte ← Null

finsi

… // continúa el código 

liberar(alu) // esto cuando ya no se necesiten los datos del alumno y antes del fin

Fin // fin del algoritmo

Obsérvese la necesidad de utilizar el operador de direccionamiento ↑, como también el . entre elnombre del campo fecha_nac y sus componentes día, mes y año.

Ahora poseemos los conocimientos necesarios de las herramientas básicas para comenzar a es-tudiar las estructuras dinámicas lineales. En primer lugar, estudiaremos los TAD (tipos abstractos dedatos) pila, cola y lista, para luego implementarlos con listas enlazadas simples.

8.4.3  COMPARACIONES ENTRE PUNTEROS 

Supongamos las siguientes declaraciones de punteros:entero ↑p, ↑q 

Es válida la operación de comparación por  igualdad (verifica si ambos punteros apuntan a lamisma dirección de memoria) o por desigualdad (verifica si los punteros apuntan a distintas direcciones

5/8/2018 estructuras dinamicas lineales - slidepdf.com

http://slidepdf.com/reader/full/estructuras-dinamicas-lineales 9/32

 

ALGORITMOS Y ESTRUCTURAS DE DATOS 

- 100 -

de memoria). También es posible verificar si un puntero posee (o no) el valor  Null .

 No es válido otro tipo de comparación (por ejemplo, no es válido verificar si un puntero poseealmacenado una dirección de memoria superior a otro, es decir, no es válido la comparación por mayor 

o menor).Entonces, solo son válidas las siguientes comparaciones:

si (p = q) entonces

… // operaciones cuando p y q apuntan al mismo espacio de memoria finsi

si (p <> q) entonces

… // operaciones cuando p y q no apuntan al mismo espacio de memoria finsi

si (p = Null) entonces

… // operaciones cuando p no apunta a un espacio de memoria válido 

finsi

8.5  TAD PILA 

La pila es una de las formas más simples de organizar elementos en el mundo real. Por ejemplo,apilamos platos, libros, camisas. Constituye una superposición de objetos en la que cada nuevo elemen-to se ubica sobre todos los anteriores y en todo momento es además el primero que se puede recuperar.En la vida cotidiana decimos que el último objeto que colocamos en la pila se encuentra en su tope, esel último que se ubicó allí y el primero que retiramos.

En informática, este concepto se implementa a través del TAD Pila y su aplicación es muy am- plia. Por ejemplo, en un programa los retornos desde los módulos se realizan en el orden inverso al

efectuado en los llamados, esto se logra apilando las direcciones de memoria de las líneas de código queesperan continuar la ejecución y desapilándolas cuando finaliza el módulo (la implementación de esta pila es tarea de los compiladores). También el Sistema Operativo utiliza pilas durante la ejecución delos programas. Si bien estos ejemplos no requieren la intervención del programador, resultan útiles pararesaltar su importancia.

Definimos Tipo Abstracto de Datos Pila a una colección dinámica de elementos homogéneosen la que el último en entrar es el primero en salir . Por este motivo se las denomina  LIFO, siglas eninglés de “último en entrar, primero en salir” (Last In, First Out).

Una pila es un TAD dinámico homogéneo al que sólo se tiene acceso al elemento que se en-cuentra en su tope. Sus operadores básicos son apilar, desapilar y pila_vacía, aunque paraeste TAD, también se pueden definir otros operadores auxiliares.

Las características del TAD Pila son:

-  Los elementos son del mismo tipo, esto la convierte en una estructura homogénea.-  Los elementos se recuperan en el orden inverso al que fueron almacenados. Por eso su forma

de acceso se denomina LIFO (Last In, First Out).-  La cantidad de elementos que contiene la pila puede variar a lo largo de la ejecución del pro-

grama. Por esta razón, es una estructura dinámica.

El TAD Pila puede ser implementado con arreglos o con listas enlazadas simples. En esta cáte-dra se utilizará la última opción. Debido a esto, cada elemento que constituye la pila será un nodo cons-truido en base a una estructura de registro formada por datos (según el caso particular del problema aresolver) y un puntero para enlazarlos.

5/8/2018 estructuras dinamicas lineales - slidepdf.com

http://slidepdf.com/reader/full/estructuras-dinamicas-lineales 10/32

 

ALGORITMOS Y ESTRUCTURAS DE DATOS 

- 101 -

8.5.1  EL CONCEPTO PILA 

Para comprender el concepto se utilizará un ejemplo.

Supongamos que es necesario apilar paquetes de arroz en un almacén. Como estos paquetes tie-nen formas irregulares, es conveniente colocarlos previamente en cajas y apilar estas últimas. El proce-dimiento a seguir lo podemos sintetizar con los siguientes pasos:

-  Buscar una caja vacía.-  Llenar la caja con paquetes de arroz.-  Cerrar la caja.-  Apilarla.

Estos pasos se repiten hasta que no queden paquetes de arroz o no se consiga una caja vacía.Cuando se necesitan paquetes de arroz, los pasos a seguir son:

-  Bajar la caja que se encuentra en el tope de la pila.-  Abrirla y tomar los paquetes de arroz

-  Descartar la caja.

Análogamente, en la programación las cajas están representadas por nodos vacíos y los paque-tes a introducir en ellas por datos. Luego, los pasos a seguir en el proceso de pilas serán:

-  Solicitar espacio de memoria para un nodo nuevo.-  Cargar datos en el nodo.-  Asignar el valor  Null al puntero incluido en el nodo.-  Apilar el nodo.

Estas operaciones sólo podrán llevarse a cabo si la primera acción no falló, es decir, si hay es- pacio libre de memoria para albergar un nodo nuevo.

Cuando se necesite procesar los datos que se encuentran en la pila, los pasos serán:

-  Desapilar el nodo que se encuentra en el tope de la pila.-  Procesar sus datos.-  Liberar el espacio de memoria, o introducir el nodo en otra estructura.

Estas operaciones se podrán realizar mientras haya nodos apilados, cuando ya no los haya, di-remos que la pila está vacía.

Algorítmicamente podemos imaginarnos a este TAD de la siguiente forma:

En el esquema, se observa una pila cuyo tope está señalado por el puntero Tp, y un nodo que no pertenece a ninguna estructura apuntado por p. Este último puede ser apilado.

8.5.2  CREACIÓN DE PILAS 

Los lenguajes de programación no disponen de un tipo de datos simple para implementar elconcepto de Pilas. Esta es la razón por la que es necesario programar el TAD Pila para implementarlo.

5/8/2018 estructuras dinamicas lineales - slidepdf.com

http://slidepdf.com/reader/full/estructuras-dinamicas-lineales 11/32

 

ALGORITMOS Y ESTRUCTURAS DE DATOS 

- 102 -

Como lo implementaremos utilizando listas enlazadas, la creación de Pilas implica la declara-ción de un tipo de datos para los nodos y la posterior programación de las operaciones apilar, des-apilar y pila _ vacia.

Podemos decir entonces que en la pila se estarán almacenando nodos de un tipo declarado paratal fin. En la sección 8.4.2 vimos un ejemplo de la creación de nodos. Estos nodos constituyen las es-tructuras de datos de los elementos del TAD. Junto a las operaciones propias de un TAD, permitirán laconstrucción de estructuras de datos que respondan al concepto del TAD particular.

8.5.3  OPERADORES DEL TAD PILA 

Como se mencionó, cada tipo abstracto de datos requiere la definición de las operaciones per-mitidas con él, esto se refiere a la necesidad de escribir el código para implementarlas.

Para el TAD Pila son tres los operadores básicos: apilar (colocar un nodo en el tope de la pila),desapilar (sacar el nodo del tope de la pila) y vacía (para verificar si existen nodos apilados).

LA OPERACIÓN APILAR  La operación apilar coloca nodos en el tope de una pila. Para ello, es necesario pasarle la di-

rección de memoria del nodo a apilar y la dirección del tope de pila sobre la que se apilará el nodo men-cionado.

Tomando el esquema anterior, la operación apilar ubicará el nodo señalado por el puntero p sobre el actual tope de la pila apuntada por Tp.

Situación antes de apilar el nodo señalado por  p en la pila apuntada por Tp  

Como resultado, el nodo apuntado por p se almacena en la pila siendo su nuevo tope (apuntado por Tp) y el puntero p queda en Null: 

Resultado después de apilar el nodo señalado por  p en la pila apuntada por Tp  

Ahora la pila se compone de cuatro nodos, y el puntero p puede utilizarse para otra operación,ya que se encuentra libre.

 Apilar , puede ser implementado como una función o como un procedimiento. Recordemos quelas variables que serán modificadas dentro del módulo deben ser pasadas por referencia. Como son dos

los valores a modificar por la operación (el puntero al nodo y el puntero al tope de la pila), convieneimplementarlo como procedimiento pasando los punteros por referencia. La sintaxis de su encabezadoserá:

5/8/2018 estructuras dinamicas lineales - slidepdf.com

http://slidepdf.com/reader/full/estructuras-dinamicas-lineales 12/32

 

ALGORITMOS Y ESTRUCTURAS DE DATOS 

- 103 -

procedimiento apilar(tipoPila ref ↑nodo, tipoPila ref ↑tope)

Por lo que el llamado a apilar el nodo apuntado por p deberá realizarse de la siguiente forma:

apilar(p, Tp)

Si lo implementamos como función, su encabezado será:

↑tipoPila funcion apilar(tipoPila ref ↑nodo, tipoPila ↑tope)

Y el llamado a apilar se hará de la siguiente forma:

Tp ← apilar(p, Tp)

Volviendo al ejemplo de alumnos presentado anteriormente, supóngase que es necesario apilar  los nodos para su posterior procesamiento. El algoritmo requiere un puntero para el tope de la pila: lla-memos a este punteo TpAlu. Asumiendo que se ha declarado el tipo alumno como se vio anteriormen-te, el código para apilar un nodo con datos de un alumno en la pila apuntada por TpAlu será:

variables

alumno ↑alu, ↑TpAlu

Inicio

alu ← nuevo(alumno)

si (alu <> Null) entonces

leer(alu↑matricula) leer(alu↑documento) leer(alu↑nombre) leer(alu↑domicilio) leer(alu↑fecha_nac.dia, alu↑fecha_nac.mes, alu↑fecha_nac.año) leer(alu↑e_mail) leer(alu↑promedio)

apilar(alu, TpAlu)

finsi

… // continúa el código 

Fin // fin del algoritmo

Antes del final de la ejecución de este algoritmo, es necesario liberar cada uno de los nodos dela pila (no incluido en el ejemplo aún).

LA OPERACIÓN DESAPILAR  

La operación desapilar toma el nodo del tope de la pila, se lo pasa a un puntero auxiliar (enlos esquemas es el puntero p) y actualiza el puntero que apunta al tope de la pila (representado por Tp).

Como resultado, el nodo que se encuentra en el tope de la pila antes de ejecutarse esta operación, ya no pertenecerá a ella; pero no será eliminado de la memoria de la máquina, estará señalado por el punteroauxiliar. Para esta operación, es necesario que el puntero auxiliar previamente se encuentre en  Null , yaque tomará la dirección del nodo desapilado. Tomemos el siguiente esquema previo a desapilar:

Estado previo a la ejecución de desapilar  

5/8/2018 estructuras dinamicas lineales - slidepdf.com

http://slidepdf.com/reader/full/estructuras-dinamicas-lineales 13/32

 

ALGORITMOS Y ESTRUCTURAS DE DATOS 

- 104 -

Después de desapilar, el resultado será:

Estado posterior a la ejecución de desapilar  

Ahora la pila se compone de dos nodos, y el puntero p señala al nodo desapilado. Obsérveseque el puntero que enlazaba al nodo desapilado con el siguiente nodo de la pila (componente interno delnodo) ya no apunta a este, su valor fue reemplazado por  Null . Esto también debe realizar la operación

desapilar.También desapilar puede ser implementado como una función o como un procedimiento.

 Nuevamente, como son dos los valores a ser modificados por esta operación (el puntero al nodo y el puntero al tope de la pila), conviene implementarlo como procedimiento pasando los punteros por refe-rencia. La sintaxis de su encabezado será:

procedimiento desapilar(tipoPila ref ↑nodo, tipoPila ref ↑tope)

Por lo que al realizar el llamado para desapilar un nodo será:

desapilar(p, Tp)

Si lo implementamos como función, su encabezado será:↑tipoPila funcion desapilar(tipoPila ref ↑tope)

Y el llamado a desapilar se hará de la siguiente forma:

p ← desapilar(Tp)

Tomando nuevamente el ejemplo de alumnos, supóngase que se debe procesar los datos de unode ellos. Ahora será necesario desapilar el nodo que se encuentra en el tope de la pila. Con las declara-ciones ya vistas, la operación será:

Inicio

… // código de creación de la pila, presentado anteriormente si (not vacia(TpAlu)) entonces

desapilar(alu, TpAlu)

procesar(alu)

… // aquí se debe hacer algo con el nodo desapilado finsi

… // el código continúa 

Fin // fin del algoritmo

Antes del final de la ejecución de este algoritmo, es necesario liberar cada uno de los nodos dela pila (no incluido en el ejemplo aún). Obsérvese que la operación desapilar está condicionada a

que la pila no se encuentre vacía, este control lo realizamos con la operación vacia que se tratará acontinuación. Con respecto al nodo desapilado, hay una observación que se debe realizar: después de

5/8/2018 estructuras dinamicas lineales - slidepdf.com

http://slidepdf.com/reader/full/estructuras-dinamicas-lineales 14/32

 

ALGORITMOS Y ESTRUCTURAS DE DATOS 

- 105 -

 procesar sus datos, o bien se lo libera o bien se lo coloca en otra estructura basada en el mismo tipo.

LA VERIFICACIÓN DE PILA VACÍA 

Obsérvese que es imposible desapilar nodos cuando la pila se encuentra vacía, por lo tanto, an-tes de ejecutar el procedimiento desapilar es necesario verificar si hay nodos apilados. Esto lo reali-za la función vacia.

Vacia, es una función que requiere como parámetro de entrada la indicación del tope de la pilaque se desea verificar, y devuelve verdadero o falso según se encuentre o no vacía. Luego, la sintaxis desu encabezado es:

logico funcion vacia(tipoPila ↑Tp)

Volviendo al ejemplo de la pila de alumnos: Antes de finalizar la ejecución del algoritmo que lacreó, es necesario destruirla. Destruirla significa liberar todos los nodos que la componen (uno a uno).Esto lo hacemos con un bucle hasta que no queden nodos en la pila:

variables

alumno ↑alu, ↑TpAlu

Inicio

… // código de creación de la pila, presentado anteriormente 

… // aquí representa al proceso de los datosmientras (not vacia(TpAlu)) entonces

desapilar(alu, TpAlu)

liberar(alu)

finmientras

… // el código continua 

Fin // fin del algoritmo

El código contenido en el bucle mientras, desapila y libera todos los nodos que componen la pila hasta que no haya más nodos en ella.

8.6  TAD COLA 

La cola es otra forma de organizar elementos en el mundo real. Por ejemplo: para poder acceder a los servicios de un cajero, primero se debe esperar a que éste atienda a todas las personas que llegaron previamente, es necesario esperar para ser atendido.

La cola está constituida por un conjunto de objetos en la que cada nuevo elemento se ubica alfinal de los anteriores (constituyéndose en el último) y en todo momento solo el primero puede ser aten-dido. De esta manera, los objetos que constituyen la cola se atienden en el mismo orden en que fueronllegando.

Es particularmente útil en informática, y su ejemplo más visible es la impresión de documentos.Cuando se envían varios documentos a imprimir, se crea una cola de espera para ser atendidos según elorden de envío. También los procesos durante su ejecución deben respetar colas.

Definimos Tipo Abstracto de Datos Cola a una colección dinámica de elementos homogéneosen la que el primero en entrar es el primero en ser atendido. Por este motivo se las denomina  FIFO,siglas en inglés de “primero en entrar, primero en salir” (First In, First Out).

Una cola es un TAD dinámico homogéneo al que sólo se tiene acceso a un elemento: el que seencuentra al principio de ella. Sus operadores básicos son encolar, desencolar y cola_vacía,aunque (al igual que en Pilas), para este TAD también se pueden definir otros operadores auxiliares.

5/8/2018 estructuras dinamicas lineales - slidepdf.com

http://slidepdf.com/reader/full/estructuras-dinamicas-lineales 15/32

 

ALGORITMOS Y ESTRUCTURAS DE DATOS 

- 106 -

Las características del TAD Cola son:

-  Los elementos son del mismo tipo, esto la convierte en una estructura homogénea.-  Los elementos solo se pueden recuperan en el orden en que fueron almacenados. Por eso su

forma de acceso se denomina FIFO (First In, First Out).-  La cantidad de elementos que contiene la cola puede variar a lo largo de la ejecución del

 programa. Por esta razón, es una estructura dinámica.

El TAD Cola puede ser implementado con arreglos o con listas enlazadas simples. Al igual que para el TAD Pilas se utilizará la última opción.

8.6.1  EL CONCEPTO DE COLA 

Para comprender el concepto se utilizará un ejemplo.

Supongamos que estamos en un supermercado haciendo compras. Para pagarlas, debemos espe-rar en la cola a ser atendidos. Básicamente los pasos son:

-  Ubicarnos al final de una cola de espera correspondiente a una caja.-  Esperar hasta que se desocupe el cajero.-  Acceder a la caja a pagar los productos.-  Retirarnos.

Llevando este ejemplo a la informática, los productos comprados serían los datos a procesar, elcanasto que los contiene sería el nodo, la cola de espera de personas con productos estaría representada por otros nodos conteniendo datos y el paso por caja para pagar sería el proceso a efectuar.

Los pasos a seguir en el proceso de encolar nodos serán:

-  Solicitar espacio de memoria para un nodo nuevo.-  Cargar datos en el nodo.

-  Asignar el valor  Null al puntero incluido en el nodo.-  Encolar al nodo.

Al igual que en pilas, estas operaciones sólo podrán llevarse a cabo si la primera acción no fa-lló, es decir, si hay espacio libre de memoria para albergar un nodo nuevo.

Cuando se necesite procesar los datos que se encuentran en la cola, los pasos serán:

-  Desencolar el nodo que se encuentra en la salida de la cola (próximo a ser atendido).-  Procesar sus datos.-  Liberar el espacio de memoria, o introducir el nodo en otra estructura.

Algorítmicamente podemos imaginarnos a este TAD de la siguiente forma:

Tres nodos en una cola de espera

Donde el puntero E (entrada, final o último nodo de la cola) señala al último nodo ingresado enla cola, y el puntero S (salida, inicio o primer nodo de la cola) el próximo a ser atendido.

Como puede observarse, el TAD Cola requiere dos punteros para su implementación, y al igualque en el caso de las pilas, para los nuevos nodos será necesario un puntero auxiliar.

8.6.2  CREACIÓN DE COLAS 

Los lenguajes de programación tampoco disponen de un tipo de datos simple para implementar Colas. Por esta razón es necesario programar el TAD Cola e implementarlo sobre estructuras conocidas.

5/8/2018 estructuras dinamicas lineales - slidepdf.com

http://slidepdf.com/reader/full/estructuras-dinamicas-lineales 16/32

 

ALGORITMOS Y ESTRUCTURAS DE DATOS 

- 107 -

Como lo implementaremos utilizando listas enlazadas, la creación de Colas implica la declara-ción de un tipo de datos para los nodos y la posterior programación de las operaciones encolar, de-sencolar y cola _ vacia.

Como ejemplo, consideremos la cola de una caja en un supermercado. Para representarla po-dríamos crear una estructura de datos para los nodos compuesta por la cantidad y la descripción de losartículos comprados y el importe total a obtener en el proceso (por el cual se espera). La estructura delos nodos sería:

tipo carrito

entero cantidad

caracter descripcion[100]

real importe

carrito ↑sgte

fintipo

Esto implica que también en las colas se almacenan nodos de un tipo declarado para tal fin. Es-to se realiza con punteros que deberán ser declarados en el espacio de declaración de variables.

A continuación se presentan las operaciones propias del TAD Cola que permitirán la construc-ción de estructuras de datos que respondan al concepto cola.

8.6.3  OPERADORES DEL TAD COLA 

Las operaciones básicas permitidas sobre el TAD Cola son tres: encolar (colocar un nuevo nodoal final de la cola), desencolar (sacar el nodo del inicio de la cola) y vacía (para verificar si existen no-dos en la cola).

LA OPERACIÓN ENCOLAR  

La operación encolar ubica nuevos nodos al final de la cola de espera. Para ello, es necesario pasarle la dirección de memoria del nodo a encolar (puntero al nuevo nodo) y las direcciones de entraday salida de la cola (punteros de entrada y de salida).

Tomando el esquema anterior con tres nodos en la cola de espera, la operación encolar con-siste en ubicar un nuevo nodo (aquí señalado por el puntero p) al final de la cola (apuntada por E).

Estado previo a encolar el nodo señalado por  p al final de la cola señalada por E  

Como resultado, el nodo apuntado por p se almacena al final de la cola (apuntado por E) y el puntero p queda en Null: 

Estado de la cola después de encolar el nodo

Después de ejecutarse la operación encolar, la cola se compone de cuatro nodos, y el punterop puede utilizarse para otra operación, ya que se encuentra libre.

Una vez más, esta operación se puede implementar como función o como procedimiento. Im- plementada como procedimiento, la sintaxis de su encabezado será:

procedimiento encolar(tipoCola ref ↑nodo, tipoCola ref↑entrada, tipoCola ref ↑salida)

5/8/2018 estructuras dinamicas lineales - slidepdf.com

http://slidepdf.com/reader/full/estructuras-dinamicas-lineales 17/32

 

ALGORITMOS Y ESTRUCTURAS DE DATOS 

- 108 -

Por lo que el llamado a encolar el nodo apuntado por p a la entrada de la cola apuntada por E  deberá realizarse de la siguiente forma:

encolar(p, E, S)

Si lo implementamos como función, su encabezado será:

↑tipoCola funcion encolar(tipoCola ref ↑nodo, tipoCola ref↑entrada, tipoCola ↑salida) 

Y en este caso el llamado a encolar se hará de la siguiente forma:

E ← encolar(p, E, S)

Siguiendo con el ejemplo de la cola de espera de la caja del supermercado, para encolar los ca-rritos necesitaremos al menos tres punteros: uno para representar carritos nuevos (nodos nuevos): crr ydos para la propia cola: Entrada y Salida. El código para encolar un nodo con datos de los artícu-los contenidos en un carrito será:

variables

carrito ↑crr, ↑Entrada, ↑Salida

Inicio

… // líneas de código previas a la creación de un nodo

crr ← nuevo(carrito)

si (crr <> Null) entonces

leer(crr↑cantidad) leer(crr↑descripcion)crr↑importe ← 0 // el importe se obtiene cuando se atiende al carrito

encolar(crr, Entrada, Salida)

finsi

… // continúa el código 

Fin // fin del algoritmo

LA OPERACIÓN DESENCOLAR  

La operación desencolar consiste en tomar el nodo que se encuentra a la salida de la cola(en el ejemplo señalado por el puntero de salida S), asignar su dirección a un puntero auxiliar que debeestar en Null (en el ejemplo es p) y eliminar el enlace entre este nodo y la cola. Internamente, será nece-sario trabajar con los punteros de entrada y salida de la cola, todos parámetros necesarios en esta opera-ción.

Tomando el esquema de tres nodos presentado anteriormente, el único nodo que puede salir dela cola es el que se encuentra señalado por S:

Estado previo a desencolar el nodo señalado por S (inicio de la cola)

Como resultado de desencolar, el nodo que se encontraba apuntado por S estará señalado por el puntero auxiliar p: 

Estado de la cola después de desencolar el nodo

5/8/2018 estructuras dinamicas lineales - slidepdf.com

http://slidepdf.com/reader/full/estructuras-dinamicas-lineales 18/32

 

ALGORITMOS Y ESTRUCTURAS DE DATOS 

- 109 -

Después de ejecutar la operación desencolar, la cola se compone solo de dos nodos, y el puntero p señala al nodo desencolado.

Una vez más, esta operación se puede implementar como función o como procedimiento. Im-

 plementada como procedimiento, la sintaxis de su encabezado será:

procedimiento desencolar(tipoCola ref ↑nodo, tipoCola ref↑entrada, tipoCola ref ↑salida)

Por lo que el llamado a desencolar el nodo de la salida se deberá realizar de la siguiente forma:

desencolar(p, E, S)

Si lo implementamos como función, su encabezado será:

↑tipoCola funcion desencolar(tipoCola ref ↑entrada, tipoColaref ↑salida) 

Y en este caso el llamado a desencolar se hará de la siguiente forma:p ← desencolar(E, S)

Para desencolar un nodo de la cola de espera del ejemplo (la cola de la caja del supermercado)una opción es:

variables

carrito ↑crr, ↑Entrada, ↑Salida

Inicio

… // código de creación de la cola, presentado anteriormente 

si (not vacia(Salida)) entonces

desencolar(crr, Salida, Entrada)procesar(crr)

… // aquí se debe hacer algo con el nodo desencolar (podría ser liberarlo) finsi

… // el código continua 

Fin // fin del algoritmo

En este ejemplo, procesar(crr) podría ser asignarle un importe a los artículos comprados(almacenados en el nodo) y acumular ese importe al total que la cajera deberá rendir al final de su turno.Una vez que se realizó el proceso de los datos, el nodo podrá ser liberado o bien se lo deberá ubicar enotra estructura.

LA VERIFICACIÓN DE COLA VACÍA 

Evidentemente es imposible desencolar nodos cuando la cola está vacía; por lo tanto, antes deejecutar el procedimiento desencolar es necesario verificar si hay nodos en ella. Esto lo realiza lafunción vacia.

Vacia, es una función que requiere como parámetro de entrada el puntero de salida de la colaque se desea verificar, y devuelve verdadero o falso según esta se encuentre o no vacía. Luego, la sin-taxis de su encabezado es:

logico funcion vacia(tipoCola ↑salida)

Volviendo al ejemplo de la cola de carritos del supermercado: Antes de finalizar la ejecución

del algoritmo que la creó, es necesario procesar todos sus nodos y destruirla. Destruirla significa liberar  todos sus nodos (uno a uno) hasta que quede vacia:

5/8/2018 estructuras dinamicas lineales - slidepdf.com

http://slidepdf.com/reader/full/estructuras-dinamicas-lineales 19/32

 

ALGORITMOS Y ESTRUCTURAS DE DATOS 

- 110 -

variables

carrito ↑crr, ↑Entrada, ↑Salida

Inicio

… // código de creación de la pila, presentado anteriormente 

… // otras líneas de código previas a la destrucción de la cola mientras (not vacia(Salida)) entonces

desencolar(crr, Salida, Entrada)

procesar(crr)

liberar(crr)

finmientras

… // el código continua 

Fin // fin del algoritmo

El código contenido en el bucle mientras, desencola, procesa y libera todos los nodos que

componen la cola hasta que no haya más nodos en ella antes de finalizar la ejecución del programa.

8.7  TAD LISTA 

La lista es otro TAD lineal. Se deriva del concepto de listas del mundo real, como por ejemplouna lista de alumnos. Se constituye de un conjunto de objetos vinculados de tal forma que cada uno posee un predecesor (excepto el primero) y un sucesor (excepto el último).

Considerando las operaciones que se pueden realizar sobre este TAD, resulta ser el más versátilde los TAD lineales.

Definimos Tipo Abstracto de Datos Lista a una colección dinámica de elementos homogéneos

con un orden lógico en ella, tal que cada elemento tiene un único predecesor (excepto el primero) y unúnico sucesor (excepto el último).

En informática, este TAD se implementa a través de la estructura dinámica lista enlazada, quese tratará más adelante en este capítulo.

Las características del TAD Lista son:

-  Los elementos son del mismo tipo, esto la convierte en una estructura homogénea.-  Los elementos se recuperan a partir de uno que constituye el inicio de la lista.-  La cantidad de elementos que contiene la lista puede variar a lo largo de la ejecución del

 programa. Por esta razón, es una estructura dinámica.-  Es de acceso secuencial, es decir, para acceder a un elemento es necesario acceder a todos

los elementos previos.Las operaciones típicas del TAD Lista son insertar un nuevo nodo, recorrer la lista para

 procesar sus datos, buscar un nodo que cumpla con un criterio dado, borrar un nodo de la lista yborrar la lista completamente; pero también se pueden definir otras operaciones adicionales de acuer-do a las necesidades del caso donde se la utiliza.

Como el TAD Lista se implementa con listas enlazadas, sus operaciones serán desarrolladasconjuntamente con la estructura lista enlazada simple.

8.8  LISTAS ENLAZADAS 

Las listas enlazadas son estructuras de datos dinámicas que se constituyen con nodos. Recor-demos que un nodo es una estructura generada dinámicamente en base a un tipo registro definido por el programador que se constituye con dos o más campos: un puntero de enlace y uno o más campos de

5/8/2018 estructuras dinamicas lineales - slidepdf.com

http://slidepdf.com/reader/full/estructuras-dinamicas-lineales 20/32

 

ALGORITMOS Y ESTRUCTURAS DE DATOS 

- 111 -

datos. La estructura del registro se crea para representar a un objeto del mundo real de acuerdo a la abs-tracción que de éste se realice.

Definimos entonces: Una Lista Enlazada es una estructura de datos dinámica lineal formada

 por un conjunto de elementos homogéneos denominados nodos , donde estos no necesariamente ocupan posiciones contiguas en memoria, pero mantienen un orden lógico entre ellos. Cada elemento de laestructura posee un único predecesor (excepto el primero) y un único sucesor (excepto el último). 

Decimos que el orden de los elementos que constituyen la lista (los nodos) es lógico puesto queestá señalado por punteros que los enlazan. Al no ocupar necesariamente ubicaciones contiguas enmemoria (es decir, sus componentes pueden aparecer físicamente dispersos en la memoria), se necesita

el uso de punteros para mantener la estructura.

Posee las mismas características del TAD Lista, del cual deriva.

Existen distintas implementaciones para esta estructura, la más utilizada es la lista enlazada simple. Otras implementaciones son la lista doblemente enlazada, la lista circular  y la lista circular 

doblemente enlazada. Como se verá más adelante, los TAD Pilas y Colas se pueden implementar utili-zando listas enlazadas simples, con restricciones en cuanto a las operaciones permitidas (solo se permi-ten las operaciones propias de cada TAD).

8.8.1  LISTAS ENLAZADAS SIMPLES 

Las listas enlazadas simples constituyen un caso particular de listas enlazadas, donde cada nodo posee un único puntero de enlace: un puntero al nodo sucesor.

Definimos lista enlazada simple a una colección de nodos con un orden lógico dado por la po- sición dentro de la estructura, tal que a cada uno de ellos se accede mediante el puntero de enlace del nodo anterior .

Este concepto la hace una estructura de acceso secuencial unidireccional (solo se puede recorrer en un sentido, el indicado por los punteros de enlace). Como cada nodo posee un puntero al nodo si-guiente, podemos graficar a esta estructura de la siguiente manera:

Una lista de datos con cuatro nodos

Donde el puntero L siempre debe estar indicando al primer nodo, y el sentido de recorrido estádado por los punteros. El último nodo de la estructura almacena el valor  Null en su puntero de enlace alnodo siguiente puesto que no lo posee, este valor  Null indica además el final de la lista. Para ejecutar lasdistintas operaciones sobre esta estructura, será necesario utilizar punteros auxiliares.

8.8.2  IMPLEMENTACIÓN DEL TAD LISTA 

Para la implementación del TAD Lista utilizaremos listas enlazadas simples.

Como todo TAD, el TAD Lista requiere la especificación de tipo de datos que represente a loselementos de datos que constituirán la lista. Esto nos lleva nuevamente a la creación de un tipo de datosregistro definido por el programador.

8.8.2.1 ESPECIFICACIÓN DE LOS DATOS Tomemos como ejemplo simplemente una lista de números (los algoritmos no difieren si se tra-

ta de otro objeto, como puede ser una lista de alumnos).

Para crear una lista, es necesario crear una estructura de datos para los nodos:

5/8/2018 estructuras dinamicas lineales - slidepdf.com

http://slidepdf.com/reader/full/estructuras-dinamicas-lineales 21/32

 

ALGORITMOS Y ESTRUCTURAS DE DATOS 

- 112 -

tipo numeros

entero numero

numeros ↑sgtefintipo

Creadas las estructuras de datos para representar a los números, a continuación se crean las va-riables necesarias para la construcción y mantenimiento de la estructura de la lista de números:

variables

numeros ↑num, ↑aux, ↑ant, ↑L

Donde num será utilizado como un puntero auxiliar para señalar nodos en la lista y L será el puntero a su nodo inicial. Tanto aux como ant serán utilizados como auxiliares en los procesos.

A continuación se deberán implementar los módulos correspondientes a las operaciones propiasdel TAD Lista: insertar un nuevo nodo, recorrer la lista para procesar sus datos, buscar unnodo que cumpla con un criterio dado, borrar un nodo de la lista y borrar la lista completa.

8.8.2.2 DESARROLLO DE OPERADORES 

Cabe aclarar una vez más que los operadores que se desarrollarán a continuación, no son losúnicos que se pueden definir sobre el TAD Lista, como tampoco es única su implementación. En cadacaso se desarrollará un solo algoritmo. Recuerde que todos los operadores se pueden implementar como procedimiento o como función según resulte más conveniente.

Comenzaremos con el proceso de recorrido (acceder sucesivamente a todos los nodos de la lista para procesar sus datos).

LA OPERACIÓN R ECORRER  

Es la operación más simple sobre listas. Consiste en utilizar un puntero auxiliar que comienzaapuntando al nodo cabecera de la lista y desde allí, acceder secuencialmente a todos los demás para procesar los datos. Lo desarrollaremos como un procedimiento (también puede ser implementado comouna función). El encabezado del procedimiento es:

procedimiento recorrer(tipoLista ↑inicio)

El procedimiento recorrer necesita como parámetro la dirección del nodo cabecera (según el al-goritmo particular, pudiera requerir otros parámetros). Si se implementa como función, el valor de re-torno dependerá de cada situación particular.

tipoDato funcion recorrer(tipoLista ↑inicio)

Para el ejemplo planteado e implementándola como procedimiento tenemos:

variables

numeros ↑num, ↑L

Inicio

… // acciones previas a la inserción de nuevo nodo recorrer(L) // llamado al procedimiento de recorrido … // continúa el código 

Fin // fin del algoritmo principal

procedimiento recorrer (numeros ↑rc)

inicio

mientras (rc <>  Null )

procesar (rc) // acá se procesa el nodo (o se llama a un procedimiento) rc ← rc↑sgte // y se avanza al siguiente nodo 

5/8/2018 estructuras dinamicas lineales - slidepdf.com

http://slidepdf.com/reader/full/estructuras-dinamicas-lineales 22/32

 

ALGORITMOS Y ESTRUCTURAS DE DATOS 

- 113 -

finmientras

finprocedimiento

El procedimiento recorrer necesita como parámetro la dirección del nodo cabecera. Desde él, se procesa los datos del nodo y se avanza al siguiente hasta acceder a todos los que componen la lista.

LA OPERACIÓN BUSCAR  

El único método de búsqueda sobre listas la búsqueda lineal. No se puede realizar búsqueda bi-nario puesto que para aplicar este método se necesita un medio de almacenamiento con direccionamien-to directo a sus elementos. Con arreglos se tiene acceso a cualquier celda a través del índice. Sobre lis-tas no se puede hallar el nodo central sin recorrer toda la estructura.

Buscar podrá ser implementado en una función o en un procedimiento según convenga.

variables

numeros ↑num, ↑L

entero n

Inicio

… // acciones previas a la inserción de nuevo nodo leer (n) // se lee el dato a buscar  buscar(n, L) // llamado al procedimiento de búsqueda … // continúa el código 

Fin // fin del algoritmo principal

procedimiento buscar (entero dato, numeros ↑rc)

inicio

mientras (rc <>  Null )

si (rc↑numero = dato) entoncesprocesar (rc) // acá se procesa el nodo o se llama a un procedimiento rc ←  Null  // se procesó el nodo buscado, se puede salir del bucle

sino

rc ← rc↑sgte // no es el nodo buscado, se avanza al siguiente finsi

finmientras

finprocedimiento

Como parámetros, buscar necesita el dato a buscar y la dirección de inicio de la lista.

LA OPERACIÓN INSERTAR  

 Insertar se implementará asumiendo que previamente se ha creado el nodo y almacenado datosen él. La operación insertar tan solo hará que este pase a pertenecer a la estructura. La sintaxis de suencabezado si se la implementa como un procedimiento será:

procedimiento insertar(tipoLista ref ↑nodo, tipoLista ref ↑inicio)

Por lo que en el ejemplo, el llamado a insertar el nodo apuntado por num deberá realizarse de lasiguiente forma:

insertar(num, L)

Si lo implementamos como función, su encabezado será:↑tipoLista funcion insertar(tipoLista ref ↑nodo, tipoLista ↑inicio)

Y el llamado a insertar utilizando las variables del ejemplo de números se hará de la siguienteforma:

5/8/2018 estructuras dinamicas lineales - slidepdf.com

http://slidepdf.com/reader/full/estructuras-dinamicas-lineales 23/32

 

ALGORITMOS Y ESTRUCTURAS DE DATOS 

- 114 -

L ← insertar(num, L)

Para implementar la operación, asumamos que la lista de números debe estar ordenada ascen-dentemente por número. El método de ordenamiento que se aplica sobre listas enlazadas es el ordena-

miento por inserción directa.Esto significa que la lista ha de construirse ordenadamente (no ordenarla posteriormente), por lo

que antes de insertar un nuevo nodo se deberá realizar una búsqueda para hallar su ubicación. Para estoes necesaria una función de búsqueda auxiliar que devuelva la dirección del nodo detrás del cual sedeberá insertar el nuevo (su anterior): buscarAnterior. Esto es necesario puesto que el punterosgte de este nodo deberá apuntar al nuevo.

Veamos la siguiente situación:

Nuevo nodo a insertar en la lista

Para poder insertar el nodo conteniendo el 12, es necesario posicionar un punteo sobre el nodoque posee el 10 (será el anterior del nuevo nodo), ya que su puntero siguiente deberá señalar al nuevonodo (usaremos el puntero local auxiliar ant). Para la inserción, se deberá reemplazar el valor  Null del puntero siguiente del nuevo nodo por la dirección del nodo que almacena el 15 y en el siguiente delanterior la dirección del nuevo nodo. Esto lo podemos ver en el siguiente gráfico, representado por pun-teros graficados en líneas punteadas.

Punteros a modificar para insertar el nuevo nodo en la lista

Luego, el procedimiento inserta necesita la dirección del nodo detrás del que se deberá insertar el nuevo. Esta dirección se obtiene con la función buscarAterior.

Asumiendo que se declararon los punteros como se vio en el parágrafo anterior,

Inicio

… // acciones previas a la inserción de nuevo nodo 

num ← nuevo(numeros)si (num <>  Null ) entonces

leer(num↑numero) num↑sgte ←  Null  

insertar(num, L)

finsi

… // continúa el código 

Fin // fin del algoritmo principal

// En el procedimiento, L estará representado por ini y num por nv.

5/8/2018 estructuras dinamicas lineales - slidepdf.com

http://slidepdf.com/reader/full/estructuras-dinamicas-lineales 24/32

 

ALGORITMOS Y ESTRUCTURAS DE DATOS 

- 115 -

procedimiento insertar(numeros ref ↑nv, numeros ref ↑ini)numeros ↑ant

inicio

ant ← buscarAnterior(nv↑numero, ini)

si (ant <>  Null ) entoncesnv↑sgte ← ant↑sgte // el sgte del nuevo apunta al nodo del 12 ant↑sgte ← nv // el sgte del anterior apunta al nuevo nodo

sino // no hay anterior, se inserta nueva cabecera nv↑sgte ← ini // el sgte del nuevo apunta a la cabecera ini ← nv // el nuevo nodo es la nueva cabecera de la lista

finsi

nv ←  Null  // hacemos que el puntero de nuevos nodos sea Null

finprocedimiento

↑numeros funcion buscarAnterior (entero dato, numeros ↑rc)numeros ↑ant

inicio

ant ←  Null  

mientras (rc <>  Null )

si (rc↑numero > dato) entoncesrc ←  Null  // encontró la ubicación, se puede salir del bucle

sino

ant ← rc // se guarda la dirección del nodo actualrc ← rc↑sgte // y se verifica el siguiente 

finsi

finmientras

retornar(ant) // se retorna la dirección del nodo anterior  

finfuncion

La función buscarAnterior recibe como parámetros el número contenido en el nodo a in-sertar y la dirección del nodo cabecera. Realiza un recorrido sobre la lista con el puntero rc buscandola ubicación donde se debe insertar el nuevo nodo, cuando la encuentra retorna la dirección del nodoanterior (almacenada en el puntero ant). Obsérvese las diferencias entre esta búsqueda y la presentadaanteriormente: en esta, interesa la dirección del nodo anterior , en la que se presentó anteriormente inte-

resaba hallar el nodo que contiene los datos a procesar.Después de ejecutar el procedimiento insertar, el resultado es el siguiente:

Resultado de insertar el nuevo nodo en la lista

LA OPERACIÓN BORRAR NODO 

Antes de eliminar un nodo de la lista es necesario redireccionar los punteros que la mantienenunida de forma tal que los demás nodos puedan ser recorridos. Si no se redireccionan correctamenteestos punteros se pierde parte de la lista (situación no deseada).

5/8/2018 estructuras dinamicas lineales - slidepdf.com

http://slidepdf.com/reader/full/estructuras-dinamicas-lineales 25/32

 

ALGORITMOS Y ESTRUCTURAS DE DATOS 

- 116 -

Tomemos como ejemplo la siguiente lista ordenada de datos y digamos que se necesita buscar ysacar de ella el nodo que contiene el 15:

Lista que tomaremos como ejemplo

Para sacar este nodo de la lista también será necesario trabajar con su anterior, puesto que sedeberá redireccionar el puntero siguiente de este nodo al siguiente del que se borrará. Una vez que sehizo esto, el nodo a borrar queda fuera de la lista y el espacio de memoria que ocupa puede ser liberado(o se lo puede insertar en otra estructura). De hecho, borrar un nodo de la lista implica previamentesacarlo de ella.

Luego, nuevamente necesitamos un proceso auxiliar buscarAnterior, pero hay diferenciasrespecto de la función que se presentó anteriormente: en este caso se debe buscar el dato por igualdad yretornar dos direcciones: la dirección de su nodo anterior (o  Null si es el nodo a borrar es el primero dela lista) y la dirección del nodo a borrar (o  Null si no se encuentra). Obsérvese que son tres las situacio-nes que se pueden presentar:

1-  el nodo buscado no se encuentra en la lista (nada para borrar),2-  el nodo buscado para borrar es el primero: se debe actualizar el puntero de inicio a la lista

(no existe un anterior),3-  se está por borrar cualquier otro nodo (se debe actualizar el puntero siguiente del nodo ante-

rior al que se borrará).

Como hay dos valores de retorno, la búsqueda para borrar el nodo se implementará como un procedimiento al cual se pasan parámetros por referencia (los punteros ant –que señala al nodo ante-rior– y bor –puntero que señala el nodo a borrar–), además del dato a buscar en la lista.

Al iniciar el proceso de búsqueda del nodo a borrar y su anterior, el puntero que señalará al no-do a borrar (puntero bor) se debe posicionar apuntando al primer nodo y el que señalará al anterior (puntero ant) en Null :

Estado inicial del proceso de búsqueda

Después de la búsqueda, la situación es la siguiente: el puntero bor señala el nodo a borrar, y el puntero ant al anterior.

Punteros señalando los nodos que intervienen en el borrado 

Se observa en el gráfico un lazo desde el nodo apuntado por ant al siguiente del nodo que seha de borrar. Este lazo se logra con la operación ant↑sgte ← bor↑sgte 

variables

numeros ↑num, ↑Lentero n

5/8/2018 estructuras dinamicas lineales - slidepdf.com

http://slidepdf.com/reader/full/estructuras-dinamicas-lineales 26/32

 

ALGORITMOS Y ESTRUCTURAS DE DATOS 

- 117 -

Inicio

…  // acciones previas al llamado a borrar  leer (n) // se lee el dato a buscar en el nodo 

borrarNodo(n, L) // llamado al procedimiento de borrar el nodo con el dato n … // continúa el código 

Fin // fin del algoritmo principal

procedimiento borrarNodo(entero num, numeros ref ↑ini)

numeros ↑ant, ↑bor //  punteros locales 

inicio

bor ← ini

buscarAnterior(num, bor, ant)

si (bor <>  Null ) entonces

si (ant =  Null ) entonces // el nodo a borrar no tiene anterior: es el primero ini ← ini↑sgte // se borra primer nodo, hay una nueva cabecera bor↑sgte ←  Null  // el nodo a borrar no pertenece más a la lista

sino // el nodo a borrar está entre otros nodos. ant↑sgte ← bor↑sgte // el sgte del anterior, pasa a ser el sgte del nodo a borrar  bor↑sgte ←  Null  // el nodo a borrar no pertenece más a la lista

finsi sino // no se encontró el nodo buscado (bor = Null )

Escribir (“El dato (nodo) buscado no está en la lista”)

finsi

liberar(bor) // liberamos el espacio de memoria del nodo

finprocedimiento

procedimiento buscarBorrar (entero dato, numeros ref ↑rc,numeros ref ↑ant)

logico encontrado // variable lógica que se utilizará para salir del bucle 

inicio

ant ←  Null  

encontrado ←  falso 

mientras ((rc <>  Null ) and (not  encontrado))si (rc↑numero = dato) entonces

encontrado ← verdadero // encontró el nodo, se puede salir del bucle

sinoant ← rc // se guarda la dirección del nodo actualrc ← rc↑sgte // y se avanza al siguiente 

finsi

finmientras

// se sale del procedimiento: si el dato está, entonces rc indica su dirección

// si no se encontró, rc y ant son Null  

finprocedimiento

El nuevo lazo entre el nodo que contiene al 10 y el nodo que contiene al 20, es necesario parano perder parte de la estructura.

5/8/2018 estructuras dinamicas lineales - slidepdf.com

http://slidepdf.com/reader/full/estructuras-dinamicas-lineales 27/32

 

ALGORITMOS Y ESTRUCTURAS DE DATOS 

- 118 -

LA OPERACIÓN BORRAR LA LISTA 

Esta es una operación que se debe ejecutar antes de finalizar la ejecución del algoritmo. Consis-te en eliminar toda la lista, es decir, todos sus nodos. Después de ejecutar esta operación, el puntero de

inicio a la lista (puntero L) estará en Null , por lo que no podrá realizarse ninguna operación con él, ex-cepto crearla nuevamente.

El algoritmo más simple para esta operación es utilizar un puntero auxiliar que señale al primer nodo de la lista, hacer que el puntero al inicio señale el siguiente y poner el valor  Null en el siguientedel señalado por el auxiliar:

Puntero auxiliar señalando el nodo a borrar 

A continuación se libera el espacio de memoria del nodo apuntado por el auxiliar. Estas opera-ciones se repetirán hasta que no haya nodos.

Se implementará con una función a la que se pasa la dirección del primer nodo y se retorna elvalor  Null para almacenar en el puntero al inicio de la lista (puntero L), señalando que la lista está vacía.

variables

numeros ↑num, ↑L

Inicio

…  // acciones previas a la inserción de nuevo nodo L ← borrarLista(L) // llamado a la función para borrar la lista … // continúa el código 

Fin // fin del algoritmo principal

↑numeros funcion borrarLista (numeros ↑ini)

numeros ↑aux, ↑bor //  punteros auxiliar  

inicio

mientras (ini <>  Null )aux ← ini // el puntero auxiliar señala el primer nodo ini ← ini↑sgte // el puntero de inicio pasa al siguiente nodo aux↑sgte ←  Null  // se desenlaza el primer nodo de la lista liberar (aux) // se libera el espacio de memoria ocupado por el nodo

finmientras

retornar( Null )

finfuncion

Existen otras operaciones sobre listas, como ser combinar dos listas, localizar últimonodo, etc.

8.8.3  IMPLEMENTACIÓN DEL TAD PILA 

La implementación de la pila utilizando listas enlazadas simples, requerirá definir un formato para los nodos, es decir, definir un tipo registro compuesto por los datos a procesar y un puntero.

Luego será necesario declarar al menos dos punteros: uno para la manipulación de nodos noapilados (que no forman parte de la pila) y el otro para indicar, en todo momento, el tope de la pila.

Como ya se sabe, para la implementación de las estructuras que responden a un Tipo Abstracto

5/8/2018 estructuras dinamicas lineales - slidepdf.com

http://slidepdf.com/reader/full/estructuras-dinamicas-lineales 28/32

 

ALGORITMOS Y ESTRUCTURAS DE DATOS 

- 119 -

de Datos, se necesita crear una estructura para los nodos. Este tema ya fue tratado con anterioridad,cuando se desarrolló el TAD Pilas. Solo resta la implementación de las operaciones apilar, des-apilar y vacía presentadas en su momento.

8.8.3.1 DESARROLLO DE OPERADORES 

Como se vio anteriormente, son tres los operadores básicos para la implementación de Pilas:

LA OPERACIÓN APILAR  

Como la implementación de pilas se hace a través de listas enlazadas simples, la operaciónapilar consiste en un caso especial de inserción: el nuevo nodo siempre se inserta al inicio de la lista.De acuerdo a lo desarrollado anteriormente, apilar se implementará en un procedimiento cuyo enca- bezado es:

procedimiento apilar(tipoPila ref ↑nodo, tipoPila ref ↑tope)

En su desarrollo, simplemente se deberá hacer que el puntero siguiente del nuevo nodo (el pun-tero al nodo nuevo es nv) señale al tope de la pila, que este nuevo nodo pase a ser el tope y finalmenteasignar el valor  Null al puntero del nuevo nodo:

procedimiento apilar(tipoPila ref ↑nv, tipoPila ref ↑tope)

inicio 

nv↑sgte ← tope // el nuevo nodo apunta al actual tope de la pila tope ← nv // el nuevo nodo pasa a ser el tope de la pila nv ←  Null  // el nuevo nodo ya no está señalado por el puntero auxiliar  

finprocedimiento

LA OPERACIÓN DESAPILAR  

La operación desapilar consiste en sacar únicamente el nodo que se encuentra en la cabece-ra de la lista y sin liberar el espacio de memoria que este ocupa. De acuerdo a lo desarrollado anterior-mente, se implementará el procedimientodesapilar, cuyo encabezado es:

procedimiento desapilar(tipoPila ref ↑nodo, tipoPila ref ↑tope)

Para su desarrollo, simplemente se deberá hacer que el puntero auxiliar (en el desarrollo llama-do ds) señale al tope de la pila, el tope apuntará al siguiente y finalmente asignar el valor  Null al punte-ro siguiente del nodo desapilado (señalado por el puntero auxiliar ds):

procedimiento desapilar(tipoPila ref ↑ds, tipoPila ref ↑tope)inicio 

ds ← tope // el puntero auxiliar señala al tope de la pila tope ← tope↑sgte // el tope de la pila pasa a ser el siguiente nodo ds↑sgte ←  Null  // el nodo desapilado no tiene siguiente 

finprocedimiento

Observe que no es necesario verificar dentro del procedimiento si existen nodos apilados antesde desapilar, puesto que, como se vio anteriormente en el desarrollo del TAD Cola, esto se realiza antesdel llamado a la función.

LA VERIFICACIÓN DE PILA VACIA La operación vacia consiste en verificar el tope de la pila (puntero a la cabecera de la lista). Si

5/8/2018 estructuras dinamicas lineales - slidepdf.com

http://slidepdf.com/reader/full/estructuras-dinamicas-lineales 29/32

 

ALGORITMOS Y ESTRUCTURAS DE DATOS 

- 120 -

este puntero es Null (pila vacía) se devuelve verdadero; si apunta a un nodo (pila no vacía), se devuelve falso. Su encabezado es:

logico funcion vacia(tipoPila ↑Tp)

Para el desarrollo de esta función se necesita una variable auxiliar de tipo lógica. Como estafunción no modifica valores, el parámetro no se pasa por referencia:

logico funcion vacia(tipoPila ↑Tp)logico vac  // variable auxiliar que indicará si está o no vacía 

inicio si (Tp =  Null ) entonces

vac ← Verdadero // la pila está vacía: se devolverá verdadero sino

vac ← Falso // la pila no está vacía: se devolverá falso finsi

retornar(vac)

finfuncion

8.8.4  IMPLEMENTACIÓN DEL TAD COLA 

La implementación de colas utilizando listas enlazadas simples también requiere definir unformato para los nodos, es decir, definir un tipo registro compuesto por los datos a procesar más un puntero. Considerando que este tema ya fue desarrollado con anterioridad, simplemente se desarrollaránlos algoritmos que implementan las operaciones encolar, desencolar y vacía.

Recordemos que una cola necesita dos punteros: uno de entrada (último nodo encolado) y uno ala salida (primer nodo de la cola). Los llamaremos E y S respectivamente.

8.8.4.1 DESARROLLO DE OPERADORES 

Son tres los operadores básicos para el procesamiento de colas:

LA OPERACIÓN ENCOLAR  

La operación encolar consiste en ubicar nuevos nodos al final de la cola de espera. Para ello,es necesario pasarle la dirección de memoria del nodo a encolar (puntero al nuevo nodo) y las direccio-nes de entrada y salida de la cola (punteros de entrada y de salida). Implementada como procedimiento,su encabezado es:

procedimiento encolar(tipoCola ref ↑nodo, tipoCola ref ↑entrada,tipoCola ref ↑salida)

En el desarrollo del procedimiento encolar se deberá hacer que el puntero siguiente del últimonodo de la cola apunte al nuevo nodo, que éste sea señalado como último nodo y que el puntero al nue-vo nodo sea Null . Como caso especial, cuando la cola está vacía tanto el puntero de entrada como el desalida deben señalar al nodo a encolar (por este motivo es necesario que el procedimiento reciba ambos punteros por referencia):

5/8/2018 estructuras dinamicas lineales - slidepdf.com

http://slidepdf.com/reader/full/estructuras-dinamicas-lineales 30/32

 

ALGORITMOS Y ESTRUCTURAS DE DATOS 

- 121 -

procedimiento encolar(tipoCola ref ↑nv, tipoCola ref ↑E,tipoCola ref ↑S)

inicio si (E =  Null ) entonces // la cola está vacía, se inserta el primer nodo 

S ← nv // el puntero de salida señala al único nodo encolado sino

E↑sgte ← nv // el nuevo nodo se ubica detrás del último nodo de la cola finsi

E ← nv // el nuevo nodo encolado pasa a ser el último de la cola nv ←  Null  // el nodo pertenece a la cola, ya no está señalado por el

//  puntero auxiliar  finprocedimiento

LA OPERACIÓN DESENCOLAR  

La operación desencolar posee similitudes con desapilar: consiste en sacar únicamenteel nodo que se encuentra en la cabecera de la lista sin liberar el espacio de memoria que este ocupa. Sinembargo, existe un caso especial no presente en Pilas: cuando la cola posee un único nodo éste a su vezes también el último; al desencolarlo, también se debe poner el valor  Null en el puntero de entrada, nosolamente en el puntero de salida. Por esta razón, se necesita pasar ambos punteros por referencia.

De acuerdo a lo desarrollado anteriormente, desencolar se implementará como un procedi-miento, cuyo encabezado es:

procedimiento desencolar(tipoCola ref ↑nodo, tipoCola ref↑entrada, tipoCola ref ↑salida)

Para su desarrollo, se deberá hacer que el puntero auxiliar (en el desarrollo llamado ds) señaleal primer nodo de la cola, el puntero de entrada señale al siguiente y asignar el valor  Null al punterosiguiente del nodo desencolado (señalado por el puntero auxiliar ds). En el caso especial en que la cola posee un único nodo, al desencolarlo también se asignará el valor  Null al puntero de entrada (por estarazón es necesario pasar tanto el puntero de entrada como el de salida por referencia).

procedimiento desencolar(tipoCola ref ↑ds, tipoCola ref ↑E,tipoCola ref ↑S)

inicio 

ds ← S // el puntero auxiliar apunta a la salida de la cola S ← S↑sgte // la nueva salida de la cola es el nodo siguiente 

ds↑sgte ←  Null  // el nodo desencolado no tiene siguiente si (S =  Null ) entonces // se verifica si la cola quedó vacía 

E ← Null  // cola quedó vacía: también el puntero de entrada es Null finsi

finprocedimiento

LA VERIFICACIÓN DE COLA VACIA 

Consiste en verificar si el puntero de salida señala un nodo o es  Null . Si este puntero es  Null  significa que la cola está vacía y se devuelve verdadero; si apunta a un nodo (cola no vacía), se devuel-ve falso. Su encabezado es:

logico funcion vacia(tipoCola ↑salida)

El desarrollo de esta función es muy similar al desarrollo de la verificación de Pila vacía:

5/8/2018 estructuras dinamicas lineales - slidepdf.com

http://slidepdf.com/reader/full/estructuras-dinamicas-lineales 31/32

 

ALGORITMOS Y ESTRUCTURAS DE DATOS 

- 122 -

logico funcion vacia(tipoCola ↑S)

logico vc  // variable auxiliar que indicará si está o no vacía 

inicio si (S =  Null ) entonces

vc ← Verdadero // la cola está vacía, se devolverá verdadero sino

vc ← Falso // la cola no está vacía, se devolverá falso finsi

retornar(vc)

finfuncion

8.8.5  LISTAS CIRCULARES 

Las listas enlazadas simples no permiten acceder directamente a cualquier nodo a partir de una posición dada, siempre es necesario iniciar la búsqueda desde el primer nodo. En lugar de almacenar un puntero con el valor  Null en el último nodo, se hace que éste apunte al primero.

Lista circular

Presentan las siguientes ventajas respectos de listas enlazadas simples:

Cada nodo es accesible desde cualquier otro nodo.-  No es necesario mantener un puntero señalando siempre a un nodo particular, debido a esto-  No existe un primer nodo bien definido, ya que el puntero puede señalar cualquier nodo.-  Se puede recorrer la estructura sin uso de punteros auxiliares.-  La inserción ordenada no presenta casos especiales.

Presenta el siguiente inconveniente:

-  Si no se cuida en el recorrido, se pueden producir bucles infinitos.

8.8.6  LISTAS DOBLEMENTE ENLAZADAS 

Para todos los casos presentados anteriormente, solo es posible recorrer las estructuras en unsentido. Existen casos donde es conveniente recorrer la estructura en ambos sentidos. Para poder reco-

rrerlas en ambos sentidos se necesita un puntero al nodo anterior. Estas listas son llamadas listas doble-mente enlazadas.

En la definición del tipo de datos para estas listas, además de los datos propios del caso, se debeincluir dos punteros: uno para señalar el nodo siguiente (al igual que en listas enlazadas simples) y uno para señalar al anterior. Los extremos almacenan el valor  Null señalando que no existe un siguiente alúltimo nodo ni un anterior al primer nodo.

Lista doblemente enlazada

Presentan las siguientes ventajas respectos de listas enlazadas simples:-  Cada nodo es accesible desde cualquier otro nodo.

5/8/2018 estructuras dinamicas lineales - slidepdf.com

http://slidepdf.com/reader/full/estructuras-dinamicas-lineales 32/32

 

ALGORITMOS Y ESTRUCTURAS DE DATOS 

- 123 -

-  No es necesario mantener un puntero señalando siempre a un nodo particular.-  Se puede recorrer la estructura en ambos sentidos.

Presenta el siguiente inconveniente:

-  Los algoritmos de inserción y borrado son más largos.-  Ocupan más espacio de memoria (por el puntero adicional).