Está en la página 1de 30

Unidad 2 / Escenario 3

Lectura fundamental

Las listas como estructuras de datos

Contenido

1 Definición

2 Aplicabilidad

3 Conceptos básicos

4 Operaciones básicas

5 Listas en lenguaje Java

6 Implementaciones de listas

Palabras clave: estructura lineal, lista, representación, operación.


1. Definición

Una lista es una secuencia finita de elementos del mismo tipo. Por medio de la notación:

〈x0, x1, x2, … ,xn-1 〉

se representa una lista cuyos elementos son x0, x1, x2, … , x n-1, en ese orden. Para denotar la lista
vacía, que no tiene ningún elemento, es usada la expresión:

〈 〉

Es importante tener en cuenta que en toda lista importa el orden en el que se encuentran sus
elementos.

2. Aplicabilidad

Las listas tienen gran aplicabilidad como estructuras de datos porque permiten almacenar elementos
en secuencia, un elemento seguido de otro. En la cotidianidad existen listas por doquier, por ejemplo:

• La lista de alumnos registrados en una asignatura.

• La lista de asistencia a clase.

• La lista de personas que asisten a un evento.

• La lista de actividades a realizar en el día.

• La lista de los artículos que hay que comprar en el supermercado.

• La lista de los artículos comprados en la tienda, en el orden en que aparecen en el recibo de


compra.

POLITÉCNICO GRANCOLOMBIANO 2
3. Conceptos básicos

3.1. Posición

Todos los elementos de una lista se pueden acceder por medio de suposición. En la lista:

〈x0, x1, x2, … ,xn-1 〉

el elemento de la posición 0 es x0, el elemento de la posición 1 es x1, el elemento de la posición x2 es ,


y así sucesivamente. En general, el elemento que se encuentra ubicado en la posición i de la lista sería x1.

Por notación en este y otros documentos que se hable de listas, se colocarán números en azul encima
de los elementos de las listas, mostrando explícitamente las posiciones de cada uno.

0 1 2 n-1
〈x0,x1,x2, … , xn-1〉

3.2. Tamaño

El tamaño o longitud de la lista se define como el número de elementos que almacena. Así pues, la
lista 〈x0, x1, x2, … ,xn-1 〉 tendría n elementos, y la lista vacía tendría 〈 〉 elementos.

3.3. Ordinales

Un número ordinal es un número que representa la posición de un elemento dentro de una lista.
Siendo n el tamaño de la lista:

• El primer elemento de la lista es el que se encuentra en la posición 0, el segundo elemento es el


que se encuentra en la posición 1, el tercer elemento es el que se encuentra en la posición 2, etc.

• El último elemento de la lista es el que se encuentra en la posición n-1, el penúltimo elemento


es el que se encuentra en la posición n-2, el antepenúltimo elemento es el que se encuentra en
la posición n-3, etc.

POLITÉCNICO GRANCOLOMBIANO 3
Nótese que el primer elemento de la lista se encuentra en la posición cero y que el último elemento
se encuentra en la posición correspondiente al tamaño de la lista menos uno.

3.4. Siguiente

Cada elemento de la lista, excepto el último, tiene un siguiente elemento. Por ejemplo, el siguiente
del primero es el segundo, el siguiente del segundo es el tercero, etc. En general, el siguiente
elemento del que está en la posición i es el que está en la posición i +1.

3.5. Anterior

Cada elemento de la lista, excepto el primero, tiene un anterior elemento. Por ejemplo, el anterior del
segundo es el primero, el anterior del tercero es el segundo, etc. En general, el anterior elemento del
que está en la posición i es el que está en la posición i - 1.

3.6. Recorridos

Un recorrido de una lista es una forma de visitar todos los elementos de la lista. Dos posibles
recorridos de una lista son:

• Recorrido al derecho, visita los elementos de la lista en el orden que aparecen, comenzando por
el primer elemento y terminando en el último.

• Recorrido al revés, visita los elementos de la lista en el orden contrario al que aparecen,
comenzando por el último elemento y terminando en el primero.

POLITÉCNICO GRANCOLOMBIANO 4
3.7. Igualdad

Dos listas son iguales si y solo si tienen el mismo tamaño y almacenan los mismos elementos en las
mismas posiciones.

3.8. Contenencia

Una lista está contenida dentro de otra si y solo si todo elemento de la primera está presente dentro
de la segunda, así sea en distinto orden.

3.9. Sub-listas

Una lista es sub-lista de otra si y solo si todos los elementos de la primera aparecen en el mismo orden
a partir de alguna posición de la segunda.

3.10. Ejemplos

Las tablas 1 y 2 presentan ejemplos sobre todos los conceptos básicos presentados hasta ahora.

Tabla 1. Ejemplos sobre posición, tamaño, ordinales, siguiente, anterior y recorridos

Concepto Lista Ejemplo


El elemento de la posición —1 de la lista está indefinido,
porque esta posición se encuentra por fuera de la lista.
El elemento de la posición O de la lista es 18.
0 1 El elemento de la posición 1 de la lista es 12.
Posición
El elemento de la posición 2 de la lista está indefinido,
〈18, 12〉
porque esta posición se encuentra por fuera de la lista.
El elemento de la posición 3 de la lista está indefinido,
porque esta posición se encuentra por fuera de la lista.

POLITÉCNICO GRANCOLOMBIANO 5
Concepto Lista Ejemplo
El elemento de la posición O de la lista es 79.
El elemento de la posición 1 de la lista es 35.
El elemento de la posición 2 de la lista es 58.
0 1 2 3 4 5 El elemento de la posición 3 de la lista es 21.
Posición
El elemento de la posición 4 de la lista es 10.
〈79, 35, 58, 21, 10, 39〉
El elemento de la posición 5 de la lista es 39.
El elemento de la posición 6 de la lista está indefinido,
porque esta posición se encuentra por fuera de la lista.
Tamaño 〈〉 El tamaño de la lista es O porque la lista está vacía.
Tamaño 〈 90〉 El tamaño de la lista es 1.
Tamaño 〈18, 12〉 El tamaño de la lista es 2.
Tamaño 〈 79, 35, 58, 21, 10, 39 〉 El tamaño de la lista es 6.
El primer elemento de la lista es el 18
0 1 (es también el penúltimo).
Ordinales
El segundo elemento de la lista es el 12
〈18, 12〉
(es también el último).
El primer elemento de la lista es el 79.
El segundo elemento de la lista es el 35.
El tercer elemento de la lista es el 58.

0 1 2 3 4 5 El cuarto elemento de la lista es el 21


Ordinales (es también el antepenúltimo).
〈79, 35, 58, 21, 10, 39〉 El quinto elemento de la lista es el 10
(es también el penúltimo).
El sexto elemento de la lista es el 39
(es también el último).
El siguiente del elemento 51 es el elemento 39.
0 1 2
Siguiente El siguiente del elemento 39 es el elemento 60.
〈 51, 39, 60 〉
El elemento 60 no tiene siguiente porque es el último.
0 1 2 3 4 El siguiente del elemento 39 no está definido porque
Siguiente
〈51, 39, 60, 39, 45〉 el valor 39 aparece dos veces dentro de la lista.
El elemento 51 no tiene anterior porque es el primero.
0 1 2
Anterior El anterior del elemento 39 es el elemento 51.
〈 51, 39, 60 〉
El anterior del elemento 60 es el elemento 39.
0 1 2 3 4 El anterior del elemento 39 no está definido porque el
Anterior
〈51, 39, 60, 39, 45〉 valor 39 aparece dos veces dentro de la lista.

POLITÉCNICO GRANCOLOMBIANO 6
Concepto Lista Ejemplo
0 1 Al derecho: visita los elementos en el orden 18, 12.
Recorridos
Al revés: visita los elementos en el orden 12, 18.
〈18, 12〉
Al derecho: visita los elementos en el orden 79, 35,

0 1 2 3 4 5 58, 21, 10, 39.


Recorridos Al revés: visita los elementos en el orden 39, 10, 21,
〈79, 35, 58, 21, 10, 39〉 58, 35, 79.

Fuente: Sotelo (s.f.)

Tabla 2. Ejemplos sobre igualdad, contenencia y sub-listas

¿La lista 1 ¿La lista 1 ¿La lista 1


Lista 1 Lista 2 es igual a está contenida es sublista
la lista 2? en la lista 2? de la lista 2?
〈15, 30, 11, 28 〉 〈15, 30, 11, 28 〉 SI SI SI
〈15, 30, 11, 28 〉 〈27, 30, 11, 28 〉 NO NO NO
〈27, 30, 11, 28 〉 〈15, 30, 11, 28 〉 NO NO NO
〈11, 11, 15, 15, 11〉 〈15, 30, 11, 28 〉 NO SI NO
〈 30, 11 〉 〈15, 30, 11, 28 〉 NO SI SI
〈15, 30, 11, 28 〉 〈 30, 11 〉 NO NO NO
〈 30, 11, 28 〉 〈15, 30, 11, 28 〉 NO SI SI
〈 15 〉 〈15, 30, 11, 28 〉 NO SI SI
〈 〉 〈15, 30, 11, 28 〉 NO SI SI
〈15, 30, 11, 28 〉 〈 〉 NO NO NO
〈 〉 〈 〉 SI SI SI
〈11, 15, 28, 30 〉 〈15, 30, 11, 28 〉 NO SI NO

Fuente: Sotelo (s.f.)

POLITÉCNICO GRANCOLOMBIANO 7
4. Operaciones básicas

Para administrar el contenido de una lista, existen cuatro operaciones básicas:

A. Consulta, que sirve para obtener el valor presente en una posición dada.

B. Modificación, para cambiar el valor presente en una posición dada.

C. Inserción, para añadir un nuevo elemento en cierta posición de la lista.

D. Eliminación, para quitar de la lista el elemento que está en cierta posición.

Nótese que todas las operaciones básicas se definen en términos de posiciones. Por medio de la tabla
3 se ejemplifica la aplicación de las operaciones básicas; donde en cada paso se resaltan en amarillo
los elementos consultados, se resaltan en azul los elementos modificados, se resaltan en verde los
elementos insertados y se resaltan en rojo los elementos que van a ser eliminados en el siguiente paso.

Tabla 3. Ejemplos de operaciones básicas sobre listas

Lista Operación Descripción de la operación realizada

〈 〉 Creación Creación de una lista vacía.

0 Inserción del elemento 53 en la posición 0.


Inserción
〈 53〉 (inserción al final)
0 1 Inserción del elemento 39 en la posición 1.
Inserción
〈 53, 39 〉 (inserción al final)
0 1 2 Inserción del elemento 47 en la posición 2.
Inserción
〈 53, 39, 47〉 (inserción al final)
0 1 2 3 Inserción del elemento 40 en la posición 0.
Inserción
〈 40, 53, 39, 47〉 (inserción al principio)
0 1 2 3 4 Inserción del elemento 58 en la posición O.
Inserción
〈 58, 40, 53, 39, 47〉 (inserción al principio)
0 1 2 3 4 5 Inserción del elemento 29 en la posición O.
Inserción
〈 29, 58, 40, 53, 39, 47〉 (inserción al principio)

POLITÉCNICO GRANCOLOMBIANO 8
Lista Operación Descripción de la operación realizada
0 1 2 3 4 5 6
Inserción Inserción del elemento 25 en la posición 4.
〈29, 58, 40, 53, 25,39, 47〉
0 1 2 3 4 5
Eliminación Eliminación del elemento de la posición 2.
〈29, 58, 53, 25, 39, 47〉
0 1 2 3 4 Eliminación del elemento de la posición 5.
Eliminación
〈 29, 58, 53, 25, 39〉 (eliminación al final)
0 1 2 3 Eliminación del elemento de la posición O.
Eliminación
〈58, 53, 25, 39〉 (eliminación al principio)
0 1 2 Eliminación del elemento de la posición O.
Eliminación
〈53, 25, 39〉 (eliminación al principio)
0 1 2 3
Inserción Inserción del elemento 31 en la posición 2.
〈53, 25, 31, 39〉
0 1 2 3 4
Inserción Inserción del elemento 58 en la posición 2.
〈53, 25, 58, 31, 39〉
0 1 2 3 4 5
Inserción Inserción del elemento 30 en la posición 1.
〈53, 30, 25, 58, 31, 39〉
0 1 2 3 4 5 Modificación del elemento de la posición 4 con el
Modificación
〈53, 30, 25, 58, 97, 39〉 valor 97.
0 1 2 3 4 5 Modificación del elemento de la posición O con el
Modificación
〈38, 30, 25, 58, 97, 39〉 valor 38.
0 1 2 3 4 5 Modificación del elemento de la posición 5 con el
Modificación
〈38, 30, 25, 58, 97, 51〉 valor 51.
0 1 2 3 4 5 Consulta del elemento de la posición 0: nos entrega
Consulta
〈38, 30, 25, 58, 97, 51〉 el valor 38.
0 1 2 3 4 5 Consulta del elemento de la posición 5: nos entrega
Consulta
〈38, 30, 25, 58, 97, 51〉 el valor 51.
0 1 2 3 4 5 Consulta del elemento de la posición 3: nos entrega
Consulta
〈38, 30, 25, 58, 97, 51〉 el valor 58.

Fuente: Sotelo (s.f.)

POLITÉCNICO GRANCOLOMBIANO 9
5. Listas en lenguaje Java

5.1. Interfaz List<E>

En el área de la programación orientada a objetos, una interfaz es un conjunto de métodos definidos


sin implementación. List<E> es una interfaz de Java que representa una lista de elementos de tipo E1.

El tipo E es genérico, es decir, puede ser cualquier clase en Java. Por ejemplo, List<Integer>
representa una lista de números enteros, List<Double> representa una lista de números flotantes,
List<String> representa una lista de cadenas de texto, List<Persona> representa una lista de personas,
List<Circulo> representa una lista de círculos, etc.

5.2. Implementaciones suministradas por Java para la interfaz List<E>

En este documento, se introducen dos implementaciones de Java para la interfaz List<E>:

• ArrayList<E>. Implementa listas a través de vectores (arreglos dinámicos de tamaño variable).


La figura 1 muestra una representación gráfica de la forma en que se disponen los datos en
esta implementación.

• LinkedList<E>: implementa listas a través de nodos doblemente encadenados en anillo con


encabezado. La figura 2 muestra una representación gráfica de la forma en que se disponen
los datos en esta implementación.

Figura 1. Representación de la lista 〈x0, x1, x2, … ,xn-1 〉 con la clase ArrayList<E> de Java
Fuente: Sotelo (s.f.)

La interfaz List<E> se encuentra ubicada en el paquete java.util, y su documentación está disponible en el API de Java en la página https://docs.oracle.
com/javase/8/docs/api/java/util/List.html

POLITÉCNICO GRANCOLOMBIANO 10
Figura 2. Representación de la lista 〈x0, x1, x2, … ,xn-1 〉 con la clase LinkedList<E> de Java
Fuente: Sotelo (s.f.)

5.3. Servicios provistos por la interfaz LIST<E>

La tabla 4, es un listado de los veinticinco métodos ofrecidos por la interfaz LIST<E>.

Tabla 4. Métodos incluidos en LIST<E>

Método Descripción

Operaciones de consulta sobre lista

int size ( ) Retoma el tamaño de la lista.

Retoma true si la lista está vacía; retona false si


boolean isEmpty ( )
no.

E get (int index) Retorna el elemento de la posición index de la lista.

POLITÉCNICO GRANCOLOMBIANO 11
Método Descripción

Operaciones de modificación sobre lista


Modifica el elemento de la posición index de la
lista por el valor element.
E get (int index, E element) Retorna como resultado el valor que se
encontraba en la posición index antes de
realizar la modificación.
Operaciones de búsqueda sobre la lista
Retorna true si el objeto obj está dentro de la
boolean contains (Object obj)
lista; retorna false si no.
Retorna true si todos los objetos de la
boolean containsALL (Collection<?> coll) colección coll están dentro de la lista; retorna
false si no.
Retorna el índice de la primera aparición del
int indexOf(Object obj) objeto obj dentro de la lista. En caso de que el
objeto obj no esté en la lista, retorna -1.
Retorna el índice de la última aparición del
int lastIndexOf(Object obj) objeto obj dentro de la lista. En caso de que el
objeto obj no esté en la lista, retorna -1.
Operaciones de inserción sobre la lista
Inserta el elemento element al final de la lista.
boolean add (E element)
Retorna true en todo caso.
Inserta el elemento element en la posición
void add (int index, E element)
index de la lista.
Inserta todos los elementos de la colección coll al
final de la lista.
boolean addALL(Collection<? extends E> coll)
Retorna true si la lista fue modificada por la
operación; retorna false si no.
Inserta todos los elementos de la colección coll
boolean addALL(int index Collection<? a partir de la posición index de la lista.
extends E> coll) Retorna true si la lista fue modificada por la
operación; retorna false si no.

POLITÉCNICO GRANCOLOMBIANO 12
Método Descripción

Operaciones de eliminación sobre la lista

void clear () Elimina todos los elementos de la lista.


Elimina el elemento de la posición index de la lista.
E remove (int index)
Retorna el valor que precisamente fue eliminado.
Elimina la primera aparición del objeto obj dentro
de la lista. En caso de que el objeto obj no
aparezca, no se hace nada. En caso de que el objeto
boolean remover (Object obj) obj aparezca más de una vez, sólo se elimina su
primera aparición.
Retorna true si la lista fue modificada por la
operación; retorna false si no.
Elimina de la lista todos los elementos que
aparezcan dentro de la colección coll.
boolean removeALL (Collection<?> coll)
Retorna true si la lista fue modificada por la
operación; retorna false si no.
Retiene en la lista sólo los elementos que
aparezcan dentro de la colección coll. En otras
palabras, elimina de la lista todos los elementos
boolean retainALL (Collection<?> coll)
que no aparezcan dentro de la colección coll.
Retorna true si la lista fue modificada por la
operación; retorna false si no.
Métodos que entregan iteradores sobre la lista
Retorna un iterador capaz de visitar todos los
Iteratoz<E> iterator ( )
elementos de la lista.
Retorna un iterador capaz de visitar todos los
ListIterator<E> listIterator ( )
elementos de la lista.
Retorna un iterador capaz de visitar los elementos
ListIterator<E> listIterator (int index)
de la lista, iniciando en la posición index.

POLITÉCNICO GRANCOLOMBIANO 13
Método Descripción

Métodos que entregan un arreglo con el contenido de la lista


Retorna un arreglo de obj contiendo todos
Object [] toArray ()
los elementos de la lista.
Retorna un arreglo de objetos contiendo todos
los elementos de la lista. Si el tamaño del
<T> T [] toArray (T[] array) arreglo array es mayor o igual que el tamaño
de la lista, se usa array para guardar los
elementos de la lista.
Métodos de comparación
Retorna true si obj es una lista igual a esta
boolean equals (Object obj)
lista; retorna false si no.
Métodos de hashing
Dejaremos la descripción de este método hasta
int hashCode ()
cuando estemos estudiando Tablas de Hashing.

Métodos que entregan vista de la lista

Retorna la sublista de esta lista que va desde la


posición fromlndex hasta la posición to:ndex-
1. La sublista retornada es una vista de la lista
List<E> subListI (int fromIndex, int toIndex)
original, es decir, cualquier modificación sobre
la sublista retornada también tiene efecto
sobre la lista original.

Fuente: Sotelo (s.f.)

POLITÉCNICO GRANCOLOMBIANO 14
6. Implementaciones de listas

Cada vez que se requiera utilizar una lista como estructura de datos, se deberá elegir entre una
implementación con vectores (ArrayList<E>) o una implementación con nodos encadenados
(LinkedList<E>), dependiendo de cuál proporciona una mayor eficiencia en la resolución del
problema particular que se está considerando. Para tener criterio en la elección, es necesario conocer
perfectamente la estructura interna de ambas implementaciones y la complejidad temporal asociada a sus métodos.

6.1. Declaración de una interfaz para la representación de listas

Con el objetivo de conocer la estructura interna detallada de las distintas implementaciones de listas,
se presenta a continuación el desarrollo desde cero de una librería sobre listas con una funcionalidad
similar a la de las clases ArrayList<E> y LinkedList<E> de Java. Adicionalmente, se harán cuatro
implementaciones de la interfaz. La interfaz se llamará versión especialmente diseñada para el módulo
de Estructuras de datos, VED.

¿Sabía que...?
En Java toda variable de tipo primitivo (byte, short, int, long, float,
double, char, boolean) se administra por valor, es decir, se trata como un
registro que almacena un valor.

Figura 3. Las variables de tipo primitivo se administran por valor


Fuente: Sotelo (s.f.)

POLITÉCNICO GRANCOLOMBIANO 15
¿Sabía que...?

Por otro lado, toda variable cuyo tipo sea una clase (String, Persona,
ArrayList, etc.) se administra por referencia, es decir, se trata como
un apuntador que referencia a un objeto, almacenando la dirección en
memoria donde este se encuentra.

Figura 4. Las variables cuyo tipo es una clase se administran por referencia
Fuente: Sotelo (s.f.)

La constante null, que representaremos con el símbolo , actúa


en Java como un apuntador a la nada. Asignándole a un apuntador
la constante null, se puede dejar de referenciar el objeto apuntado.

Figura 5. La constante null como apuntador a la nada


Fuente: Sotelo (s.f.)

En Java, existe un proceso muy importante que se llama el Recolector


de Basura (en inglés: Garbage Collector), cuyo propósito consiste en
liberar la memoria ocupada por aquellos objetos que se han dejado de
referenciar por un programa.

POLITÉCNICO GRANCOLOMBIANO 16
¿Sabía que...?
El Recolector de Basura se ejecuta cada vez que el uso de
memoria sobrepase cierto umbral de porcentaje, o cada vez que la
implementación de la máquina virtual lo decida. Por esta razón, no
nos debemos preocupar en Java por liberar explícitamente la memoria
reservada: apenas dejemos de referenciar uno o más objetos, éstos se
convierten en basura, cuya memoria será liberada por el Recolector de
Basura cuando se ejecute la próxima vez.

6.2. Implementación con vectores

La clase VEDArrayList<E> implementa listas con arreglos dinámicos de tamaño variable, exhibiendo
la estructura interna de la clase ArrayList<E> de Java. Formalmente hablando, en Java no existen los
arreglos de tamaño variable, puesto que todos los arreglos en Java tienen una longitud fija después de
haber sido creados, entonces, ¿qué se puede hacer? La respuesta es sencilla: cada vez que se necesite
cambiar el tamaño del arreglo, se crea uno nuevo del tamaño deseado, se pasa el contenido del
arreglo viejo al arreglo nuevo, se desecha el arreglo viejo y se toma únicamente con el arreglo nuevo.
Este truco permite simular en Java arreglos dinámicos de tamaño variable.

Figura 6. Representación de la lista 〈x0, x1, x2, … ,xn-1 〉 como un arreglo dinámico de tamaño variable
Fuente: Sotelo (s.f.)

POLITÉCNICO GRANCOLOMBIANO 17
Los atributos de la clase VEDArrayList<E> son:

• tamanho, es una variable de tipo int que almacena el tamaño de la lista, y que se abreviará de
aquí en adelante con la letra n. Recuerde que el tamaño de una lista es el número de elementos
que almacena.

• arreglo, es un arreglo de objetos que almacena todos los elementos de la lista, en el orden que
aparecen. Al tamaño del arreglo se le llama capacidad y se abreviará con la letra t.

Siempre debe cumplirse que t ≥ n (que la capacidad del arreglo sea mayor o igual que el tamaño de
la lista), porque de lo contrario, los elementos de la lista no cabrían en el arreglo. Todas las posiciones
del arreglo desde 0 hasta n-1 son casillas ocupadas por los elementos de la lista, y todas las posiciones
del arreglo desde n hasta t-1 son casillas de reserva para permitir de forma eficiente la inserción de
elementos futuros. La figura 7 ilustra la definición de la clase VEDArrayList<E>.

Figura 7. Declaración de la clase VEDArrayList<E>


Fuente: Sotelo (s.f.)

POLITÉCNICO GRANCOLOMBIANO 18
6.2.1. Constructor

El método constructor de la clase (figura 8), que se responsabiliza de crear una nueva lista vacía,
no debe realizar ninguna operación adicional porque con la inicialización de los atributos ya se está
representando una lista vacía: el atributo arreglo se inicializó con un arreglo de capacidad 1, y el
atributo tamanho se inicializó en 0. No importa la capacidad inicial del arreglo porque a medida que se
vayan realizando inserciones sobre la lista, se va ajustando su capacidad.

Figura 8. Método constructor de la clase VEDArrayList<E>


Fuente: Sotelo (s.f.)

La tabla 5, presenta los análisis de complejidad temporal del método constructor para el mejor y el peor caso.

Tabla 5. Análisis de complejidad del método constructor VEDArrayList(). Modificado de Sotelo (s.f)

Tipo de análisis Complejidad Justificación

Peor caso 0 (1) En todo caso, el atributo arreglo se inicializa


con un arreglo de capacidad 1 y el
atributo tamanho se inicializa en 0, dando
una complejidad temporal de O (1)
Mejor caso 0 (1) por ser un número constante de operaciones.

Fuente: elaboración propia

POLITÉCNICO GRANCOLOMBIANO 19
6.2.2. Destructor

Para eliminar todos los elementos de la lista existe el método clear, cuya implementación debe
asignarles a todas las casillas ocupadas del arreglo el valor null y debe ponerle el valor 0 al atributo
tamanho. De esta manera, se dejan de referenciar los objetos de la lista, marcándolos como basura
y dejándole el trabajo de la liberación de memoria al Recolector de Basura. La figura 9 representa el
método destructor.

Figura 9. Método que elimina todos los elementos de la lista


Fuente: Sotelo (s.f.)

La tabla 6 presenta los análisis de complejidad temporal del método destructor para el mejor y el peor caso.

Tabla 6. Análisis de complejidad temporal del método void clear (). Modificado de Sotelo (s.f)

Tipo de análisis Complejidad Justificación

Peor caso 0 (n) En todo caso, se debe asignar el valor null


alas n casillas ocupadas del arreglo
Mejor caso 0 (n) para poder liberar la memoria.

Fuente: elaboración propia

POLITÉCNICO GRANCOLOMBIANO 20
6.2.3. Operación de consulta

Para consultar el elemento que se encuentra en cierta posición de la lista, basta acceder al arreglo en
la posición dada. La figura 10 ilustra esa operación ejecutada por el método get.

Figura 10. Método para consultar el valor del elemento que está en una posición determinada de la lista
Fuente: Sotelo (s.f.)

La tabla 7 presenta los análisis de complejidad temporal del método de consulta para el mejor y el peor caso.

Tabla 7. Análisis de complejidad temporal del método de consulta. Modificado de Sotelo (s.f)

Tipo de análisis Complejidad Justificación

Peor caso 0 (1) Acceder a la posición de un arreglo para


consultarla tiene complejidad
temporal 0(1) pues implica un número
Mejor caso 0 (1)
constante de operaciones.

Fuente: elaboración propia

6.2.4. Operación de modificación

Para modificar el elemento que se encuentra en cierta posición de la lista, basta acceder al arreglo
en la posición dada y cambiar el valor. En la figura 11 está contenido un método llamado set que
ejecuta una modificación.

POLITÉCNICO GRANCOLOMBIANO 21
Figura 11. Método para modificar el valor del elemento que está en una posición determinada de la lista
Fuente: Sotelo (s.f.)

La tabla 8 presenta los análisis de complejidad temporal del método de modificación para el mejor y el peor caso.

Tabla 8. Análisis de complejidad temporal del método modificación. Modificado de Sotelo (s.f)

Tipo de análisis Complejidad Justificación

Peor caso 0 (1) Acceder a la posición de un arreglo para


modificarla tiene complejidad
temporal 0(1) pues implica un número
Mejor caso 0 (1)
constante de operaciones.

Fuente: elaboración propia

6.2.5. Operación de inserción

Antes de insertar un elemento en la estructura de datos, hay que revisar si cabe en el arreglo.
En caso de que el arreglo esté completamente lleno (lo que sucede cuando se agotan las casillas
de reserva), es necesario incrementar su capacidad a través del siguiente proceso:

A. Crear un nuevo arreglo con la nueva capacidad deseada.

B. Copiar todos los elementos de la lista al nuevo arreglo.

C. Poner a apuntar la variable arreglo al arreglo nuevo, para desechar el arreglo viejo.
El Recolector de Basura será el encargado de liberar la memoria ocupada por el arreglo viejo.
El método privado garantizarCapacidad de la clase VEDArrayList<E>, ilustrado en la
figura 12, se responsabiliza de garantizar que cierta cantidad de elementos quepa en el arreglo,
incrementando la capacidad de este (de ser necesario).

POLITÉCNICO GRANCOLOMBIANO 22
Figura 12. Método para garantizar que cierta cantidad de elementos quepa en el arreglo
Fuente: Sotelo (s.f.)

Como el proceso que incrementa la capacidad del arreglo es ineficiente, pues su complejidad
temporal es O(n), hay que evitar a toda costa que sea ejecutado frecuentemente. Un mecanismo
para reducir sustancialmente el número de veces que se debe hacer crecer el tamaño del arreglo
es duplicar su capacidad cada vez que se necesite un aumento de capacidad. Tómese el siguiente
ejemplo: suponga que se tiene un arreglo de capacidad 16 que no tiene casillas de reserva porque
todas sus casillas están ocupadas. Al intentar añadir el decimoséptimo elemento, se notará que el
arreglo está lleno y que se requiere incrementar su capacidad; entonces, se agranda la capacidad
del arreglo a 32, lo que deja 16 casillas ocupadas y 16 casillas de reserva. Como ahora hay 16 casillas
de reserva, es posible insertar el decimoséptimo, el decimoctavo y el trigésimo segundo elemento,
sin necesidad de volver a incrementar la capacidad del arreglo. Al intentar añadir el trigésimo tercer
elemento se notará que hay que volver a duplicar la capacidad, quedando un arreglo con 64 casillas,
donde 32 estarán ocupadas y 32 servirán de reserva. Y ahora, esas 32 casillas de reserva permitirán
agregar el trigésimo tercer, el trigésimo cuarto, … y el sexagésimo cuarto elemento. Siguiendo este
argumento, ¡el proceso que aumenta la capacidad del arreglo debe llamarse cada vez con menos
frecuencia a medida que el tamaño de la lista aumenta!

POLITÉCNICO GRANCOLOMBIANO 23
Es posible alterar la capacidad del arreglo con un porcentaje distinto al 200%, que corresponde a
duplicar el número de casillas. Por ejemplo, la clase ArrayList<E> de Java modifica la capacidad en un
150% cada vez que se necesita incrementar el tamaño de un arreglo.

Cómo mejorar...
Lo invito a responder la siguiente pregunta: ¿cuántas veces habría que duplicar el
tamaño del arreglo para efectuar un millón de inserciones consecutivas?

Figura 13. Paso b del proceso que inserta un elemento en la posición k (donde k = index)
Fuente: Sotelo (s.f.)

Ahora, sabiendo que ya se cuenta con un mecanismo capaz de asegurar el espacio para alojar un
nuevo elemento, se puede implementar una solución para insertarlo. Para insertar un valor que será
llamado element en la posición index de la lista se deberá seguir el siguiente proceso:

A. Se ejecuta el método garantizarCapacidad para asegurar que quepan en total tamanho +


1 elementos en el arreglo.

POLITÉCNICO GRANCOLOMBIANO 24
B. Se corren una posición hacia la derecha todos los elementos de la lista que están ubicados
desde la posición index hasta la posición tamanho-1; recorriendo el arreglo al revés, primero
se traslada el elemento de la posición tamanho-1, luego se traslada el elemento de la posición
tamanho-2, …, y, finalmente, se mueve el elemento de la posición index. Este procedimiento
se representa en la figura 13. Pregunta para el lector: ¿qué tan complicado sería el código si se
hiciera el corrimiento recorriendo el arreglo al derecho en lugar de hacerlo al revés?
C. Se ubica el valor element en la posición index de la lista.

D. Se incrementa el tamaño de la lista, tamanho, en una unidad.

Figura 14. Método para insertar un elemento en una posición determinada de la lista
Fuente: Sotelo (s.f.)

La tabla 9 presenta los análisis de complejidad temporal del método de inserción para el mejor y el peor caso.
Tabla 9. Análisis de complejidad temporal del método de inserción. Modificado de Sotelo (s.f)

Tipo de análisis Complejidad Justificación


El peor caso ocurre en dos situaciones:
* Cuando la inserción es al principio, la complejidad
temporal es O(n) pues todos los elementos de la lista se
deben correr una posición a la derecha.
Peor caso 0 (n) * Cuando se debe aumentar la capacidad del arreglo, la
complejidad temporal es O(n) pues se debe crear el nuevo
arreglo, trasladar todos los elementos a ese nuevo arreglo y
ejecutar la inserción.
El mejor caso ocurre cuando hay casillas de reserva y
la inserción se realiza al final de la lista. La complejidad
Mejor caso 0 (n) temporal en esta situación es 0(1) porque no es necesario
trasladar ningún elemento ni hay aumentar la capacidad del
arreglo.
Fuente: elaboración propia

POLITÉCNICO GRANCOLOMBIANO 25
6.2.6. Operación de eliminación

Figura 15. Pasos b y c del proceso que elimina un elemento de una posición determinada de la lista
Fuente: Sotelo (s.f.)

Para eliminar el elemento ubicado en la posición index de la lista, se debe seguir el proceso que se
describe a continuación y que se ilustra en la figura 15:
A. Se almacena en una variable auxiliar el elemento que se encuentra en la posición index.
B. Se corren una posición hacia la izquierda todos los elementos de la lista que están ubicados
desde la posición index+1 hasta la posición tamanho-1, recorriendo el arreglo al derecho:
primero se traslada el elemento de la posición index+1, luego se traslada el elemento de
la posición index+2, …, y finalmente se mueve el elemento de la posición tamanho-1.
Pregunta para el lector: ¿qué tan complicado sería codificar el algoritmo si se hiciera el
corrimiento recorriendo el arreglo al revés en lugar de hacerlo al derecho?
C. Se asigna el valor null a la casilla de la posición tamanho-1 del arreglo.
D. Se disminuye el tamaño de la lista (tamanho) en una unidad-
E. Se retorna el elemento eliminado que fue almacenado en el primer paso.

Figura 16. Método para eliminar un elemento de una posición determinada de la lista
Fuente: Sotelo (s.f.)

POLITÉCNICO GRANCOLOMBIANO 26
La tabla 10 presenta los análisis de complejidad temporal del método de eliminación para el mejor y el peor caso.
Tabla 10. Análisis de complejidad temporal del método de eliminación

Tipo de análisis Complejidad Justificación


El peor caso ocurre cuando se desea eliminar el primer
elemento de la lista, en este evento se alcanza la
Peor caso 0 (n) complejidad temporal O(n) porque es necesario correr
todos los elementos de la lista, excepto el primero, una
posición a la izquierda.
El mejor caso ocurre cuando se requiere eliminar el útlimo
elemento de la lista. La complejidad temporal en esta situación
Mejor caso 0 (n)
es 0(1) porque no hay que trasladar ningún el emento.

Fuente: Elaboración propia a partir de la tabla presentada en Sotelo (s.f.)

En síntesis...

Una lista es una secuencia finita de elementos del mismo tipo. Las listas tienen gran aplicabilidad como
estructuras de datos, porque permiten almacenar elementos en secuencia.

Existen cuatros operaciones básicas sobre los elementos de una lista: consulta, modificación, inserción y
eliminación.

En Java, las listas se representan por medio de la interfaz List<E>, donde E simboliza un tipo genérico.

Los datos que pertenecen a un tipo de dato primitivo son administrados por valor; mientras que, los
datos que pertenecen a tipos que corresponden a clases son administrados por referencia. El recolector
de basura de Java es un proceso que libera la memoria ocupada por aquellos objetos que se han dejado
de referenciar en un programa.

POLITÉCNICO GRANCOLOMBIANO 27
Referencias
Sotelo, A. (s.f.). Implementaciones de listas (parte 1). Bogotá, Colombia.

Sotelo, A. (s.f.). Las listas como estructuras de datos. Bogotá, Colombia.

Sotelo, A. (s.f.). Las listas en el lenguaje Java. Bogotá, Colombia.

Referencias de imágenes y tablas


Sotelo, Alejandro. (s.f.). Declaración de la clase VEDArrayList<E> [Captura de pantalla]. Recuperado
de https://poli.instructure.com/courses/67/files/2393?module_item_id=2116

Sotelo, Alejandro. (s.f.). Ejemplo de la aplicación de las operaciones básicas sobre listas. Recuperado
de https://poli.instructure.com/courses/67/files/2440?module_item_id=2114

Sotelo, Alejandro. (s.f.). Ejemplos sobre los conceptos básicos. Recuperado de https://poli.
instructure.com/courses/67/files/2440?module_item_id=2114

Sotelo, Alejandro. (s.f.). Ejemplos sobre los conceptos de igualdad, contenencia y sublista.
Recuperado de https://poli.instructure.com/courses/67/files/2440?module_item_id=2114

Sotelo, Alejandro. (s.f.). La constante null como apuntador a la nada [Captura de pantalla].
Recuperado de https://poli.instructure.com/courses/67/files/2393?module_item_id=2116

Sotelo, Alejandro. (s.f.). Las variables cuyo tipo sea una clase se administran por referencia [Captura
de pantalla]. Recuperado de https://poli.instructure.com/courses/67/files/2393?module_item_id=2116

Sotelo, Alejandro. (s.f.). Las variables de tipo básico se administran por valor [Captura de pantalla].
Recuperado de https://poli.instructure.com/courses/67/files/2393?module_item_id=2116

Sotelo, Alejandro. (s.f.). Los veinticinco métodos sin implementación ofrecidos por la interfaz List<E>.
Recuperado de https://poli.instructure.com/courses/67/files/2421?module_item_id=2115

Sotelo, Alejandro. (s.f.). Método constructor de la clase VEDArrayList<E> [Captura de pantalla].


Recuperado de https://poli.instructure.com/courses/67/files/2393?module_item_id=2116

Sotelo, Alejandro. (s.f.). Método para asegurar que cierta cantidad de valores quepa en el arreglo
[Captura de pantalla]. Recuperado de https://poli.instructure.com/courses/67/files/2393?module_
item_id=2116

POLITÉCNICO GRANCOLOMBIANO 28
Sotelo, Alejandro. (s.f.). Método para consultar el valor del elemento que está en determinada
posición de la lista [Captura de pantalla]. Recuperado de https://poli.instructure.com/courses/67/
files/2393?module_item_id=2116

Sotelo, Alejandro. (s.f.). Método para eliminar el elemento presente en determinada posición
de la lista. [Captura de pantalla]. Recuperado de https://poli.instructure.com/courses/67/
files/2393?module_item_id=2116

Sotelo, Alejandro. (s.f.). Método para insertar un elemento en determinada posición de la lista
[Captura de pantalla]. Recuperado de https://poli.instructure.com/courses/67/files/2393?module_
item_id=2116

Sotelo, Alejandro. (s.f.). Método para modificar el valor del elemento que está en determinada
posición de la lista [Captura de pantalla]. Recuperado de https://poli.instructure.com/courses/67/
files/2393?module_item_id=2116

Sotelo, Alejandro. (s.f.). Método que elimina todos los elementos de la lista [Captura de pantalla].
Recuperado de https://poli.instructure.com/courses/67/files/2393?module_item_id=2116

Sotelo, Alejandro. (s.f.). Paso 2 del proceso que inserta un elemento en la posición k (donde k=index)
[Captura de pantalla]. Recuperado de https://poli.instructure.com/courses/67/files/2393?module_
item_id=2116

Sotelo, Alejandro. (s.f.). Pasos 2 y 3 del proceso que elimina el elemento de la posición k (donde
k=index) [Captura de pantalla]. Recuperado de https://poli.instructure.com/courses/67/
files/2393?module_item_id=2116

Sotelo, Alejandro. (s.f.). Representación de la lista 〈x0, x1, x2, … ,xn-1 〉 como un arreglo dinámico
de tamaño variable [Captura de pantalla]. Recuperado de https://poli.instructure.com/courses/67/
files/2393?module_item_id=2116

Sotelo, Alejandro. (s.f.). Representación de la lista 〈x0, x1, x2, … ,xn-1 〉 con la clase ArrayList<E>
de Java [Captura de pantalla]. Recuperado de https://poli.instructure.com/courses/67/
files/2421?module_item_id=2115

Sotelo, Alejandro. (s.f.). Representación de la lista 〈x0, x1, x2, … ,xn-1 〉 con la clase LinkedList<E>
de Java [Captura de pantalla]. Recuperado de https://poli.instructure.com/courses/67/
files/2421?module_item_id=2115
INFORMACIÓN TÉCNICA

Módulo: Estructura de Datos


Unidad 2: Estructuras de datos lineales
Escenario 3: Listas

Autor: Javier Fernando Niño Velásquez

Asesor Pedagógico: Heidy Liliana Moncada


Diseñador Gráfico: Nicolás Jiménez O.
Asistente: Ginna Quiroga

Este material pertenece al Politécnico Grancolombiano.


Prohibida su reproducción total o parcial.

POLITÉCNICO GRANCOLOMBIANO 30