Una
lista es una secuencia de elementos, eventualmente vacía, de
un tipo de dato determinado. Son estructuras de datos flexibles ya que
pueden varian su dimensión en tiempo de ejecución a partir
de las operaciones de manipulación de datos que se efectúan
sobre esta.
Las operaciones más comunes que operan sobre Listas aquellas
que permiten insertar, eliminar y acceder a los elementos que esta almacena.
Estas operaciones deben permitir manipular a los elementos sin importar
en la posición dentro de la lista en que se encuentren.
Una
lista puede verse como una suceción E1,E2,..,En de elementos.
De aquí podemos notar varias propiedades de este tipo estructura.
Como primer caso podemos deducir que E1 es el primer elemento y que
En es el último de los elementos de la lista. La longitud de
la lista será n y por consiguiente, si n=0 podremos decir que
estamos ante el caso de la lista vacía. Los elementos de la lista
están ordenados primeramente de acuerdo a su posición
en la lista, es decir Ei antece a Ej, solo si i<j.
Hasta
aquí tenemos una definición matemática de lo que
es una lista. Ahora si queremos implementar el tipo Lista_de_elementos
podremos hacerlo mediante un Tipo Abstracto de Datos (TAD), en Delphi
esto se puede hacer mediante la implementación de una unidad
en la que definamos el tipo lista_de_elementos conjuntamente con todas
las funciones y procedimientos que nos permitan manipularla. Otra opción
es definir un objeto Lista_de_Elementos junto con los métodos
necesarios para el manejo del objeto. De esta forma, estaremos ocultando
la estructura interna que utilizamos para la representación de
la lista.
Algunas
de las estructuras de datos que se pueden considerar para representar
Listas son los arreglos y los punteros. Lo que nos cambiará el
implementar una lista con una estructura u otra es la eficiencia con la
que se ejecutarán cada una de las operaciones que definamos para
manipular la lista.
Implementación de una Lista con Arreglos:
Los
elementos de la lista se almacenarán en las posiciones contiguas
de un arreglo. Esta representación tiene ventajas con respecto
a otras realizaciones pues permite recorrer fácilmente los elementos
de una lista y agregarlos al final. Aunque no siempre es aconsejable este
tipo de estructura para la representación interna de una lista
pues agregar los elementos al medio de la lista trae como consecuencia
el corrimiento de todos los elementos que se encuentren desde esa posición
hasta el final de la lista para poder concederle una posición al
nuevo elemento. Lo mismo ocurre cuando queremos borrar un elemento. Otro
inconveniente de esta realización es que el tamaño de la
lista es fijo por lo que si la hacemos muy pequeña solo podremos
poner unos pocos elementos y si la hacemos muy grande estaremos desperdiciando
mucho lugar en memoria.
Para
poder llevar a cabo esta realización no solo necesitaremos el arreglo
de elementos sino que también una variable para guardar la cantidad
de elementos que tiene la lista y otra que nos indique cual es el número
máximo de elementos que vamos a poder guardar en la lista. Otra
información que debemos guardar es cual es el elemento de la lista
sobre el que estamos posicionados en cada momento.
type
Tlista = TObject
totalElementos
= longint;
elementos
: array [1..totalElementos]
of Tipo_Elemento;
cantElementos
: longint;
elementoActual
: 1..totalElementos;
...
funciones
y procedimientos sobre la lista
...
end;
Implementación de una Lista con Punteros:
Esta
otra forma de realización de Listas es mediante el enlace de los
elementos consecutivos de una lista, utilizando punteros para llevar a
cabo el enlace. Esta implementación tiene ciertas ventajas visibles
con respecto a la otra implementación pues no necesita utilizar
posiciones contiguas en memoria para almacenar los datos de la lista y
por lo tanto se evitan los desplazamientos de elementos a la hora de insertar
o eliminar un elemento de los del medio de la lista. Pero su mayor ventaja
es que el tamaño de la lista es más flexible que con la
realización con arreglos, pues este puede ir aumentando o disminuyendo
a medida que es necesario sin tenen la obligación de guardar el
espacio de memoria para almacenar la lista al principio. Sin embargo estas
facilidades tienen su costo adicional a la hora de recorrer la lista y
el espacio que se requiere para almacenar el puntero que enlaza dos elementos.
Para
poder llevar a cabo esta implementación, por cada elemento de la
lista tenemos que guardar también el enlace al próximo elemento,
es decir si tenemos E1 y E2 entonces existirá un puntero desde
E1 a E2; hay un caso especial para el elemento En en el que el enlace
tendrá el valor nil. Existirá también una variable
de encabezamiento de la lista que será un puntero al primer elemento
de la lista (E1). Al igual que en la representación con arreglos
será necesario guardar el elemento de la lista al que se está
haciendo referencia en cada momento.
type
ElementoLista = TObject
dato
: Tipo_Elemento;
siguiente
: Elemento_Lista;
...
funciones
y procedimientos sobre el elemento de la lista
...
end;
Tlista
= TObject
totalElementos
: longint;
elementos
: ElementoLista;
elementoActual
: ElementoLista;
...
funciones
y procedimientos sobre la lista
...
end;
Otros
tipos de Listas:
En
muchas ocaciones podemos querer recorrer una lista, tanto hacia adelante
como hacia atrás. O bien, dado un elemento cualquiera queremos
conocer de forma rápida y eficiente los elementos anterior y siguiente
al dado. En tales ocaciones lo que se debe hacer es implementar una lista
doblemente enlazada, que es una variación de la anterior.
En
una lista doblemente enlazada cada elemento Ei, 'conoce' los elementos
Ei-1 y Ei+1; si estamos hablando de la implementación con arreglos
son aquellos elementos que se encuentran en la posición anterior
y siguiente de un elemento dado dentro el arreglo, pero si nuestra realización
la hemos llevado a cabo mediante punteros en este caso cada elemento de
la lista debe tener dos enlaces, uno a su antecesory otro su sucesor.
type
ElementoLista = TObject
dato
: Tipo_Elemento;
siguiente : Elemento_Lista;
anterior
: Elemento_Lista;
...
funciones y procedimientos sobre el elemento
de la lista
...
end;
Otras estructuras que son derivaciones de las Listas son
las Pilas y las Colas;