Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Escenario 4 Estrcutura de Datos
Escenario 4 Estrcutura de Datos
Lectura fundamental
Contenido
1 Listas (continuación)
2 Pilas
3 Colas
La clase VEDLinkedList<E> implementa listas con nodos doblemente encadenados en anillo con
encabezado (en inglés: header), exhibiendo la estructura interna de la clase LinkedList<E> de
Java. En esta estructura de datos, los nodos son capaces de almacenar valores y de apuntar al nodo
anterior y al nodo siguiente en el encadenamiento. Para mayor entendimiento véase la figura 1. Un
nodo, representado con la clase VEDNodo<E>, tiene los siguientes atributos:
Cada elemento de la lista se almacena en un nodo por separado. Además, hay un nodo especial
llamado encabezado o header, cuyo valor es null y que tiene como propósito hacer más cómoda
la programación de la estructura de datos. Véase la figura 2.
POLITÉCNICO GRANCOLOMBIANO 2
Figura 2. Representación de la lista como una lista 〈x0, x1, x2, … ,xn-1 〉doblemente encadenada en anillo con encabezado
Fuente: Sotelo (s.f.)
Por simplicidad, es preferible dibujar los nodos de forma lineal y no circular, como se muestra en la figura 3.
Figura 3. Representación lineal de la lista como una lista doblemente encadenada en anillo con encabezado
Fuente: Sotelo (s.f.)
POLITÉCNICO GRANCOLOMBIANO 3
Figura 4. Representación de la lista vacía como una lista doblemente encadenada en anillo con encabezado
Fuente: Sotelo (s.f.)
• tamaño: una variable de tipo int que almacena el tamaño de la lista, y que será abreviada con la
letra n. Se debe recordar que el tamaño de una lista es el número de elementos que almacena.
¿Sabía que...?
El encabezado no guarda ningún elemento de la lista. Por esta razón,
si el tamaño de la lista es n, entonces habrán n+1 nodos, contando el
encabezado.
POLITÉCNICO GRANCOLOMBIANO 4
Figura 5. Declaración de la clase VEDLinkedList<E>
Fuente: Sotelo (s.f.)
1.1.1. Constructor
El método constructor de la clase, que se responsabiliza de crear una nueva lista vacía, debe asegurar
que se cumpla la situación ilustrada en la figura 6.
POLITÉCNICO GRANCOLOMBIANO 5
Obsérvese que, en la inicialización de los atributos de la clase, se colocó el tamaño en 0 y se creó el
encabezado con valor null, anterior null y siguiente null, quedando como lo muestra la figura 7.
¿Falta algo? Poner como anterior y como siguiente del encabezado al mismo encabezado, tal como se
muestra en la figura 8.
La tabla 1 presenta los análisis de complejidad temporal del método constructor para el mejor y el peor caso.
Tabla 1. Análisis de complejidad temporal del método constructor VEDLinkedList (). Modificado de Sotelo (s.f)
POLITÉCNICO GRANCOLOMBIANO 6
1.1.2. Destructor
Para eliminar todos los elementos de la lista, existe el método clear, cuya implementación debe
asegurar que se pase de la situación presentada en la figura 9a a la situación de la figura 9b.
(a)
(b)
Figura 9. Estados deseados de la lista antes (a) y después (b) de llamar al método clear
Fuente: Sotelo (s.f.)
Basta con poner como anterior y como siguiente del encabezado al mismo encabezado y asignarle
el valor 0 a la variable tamaño, como lo muestra la figura 10. ¿Qué pasa con los nodos de la lista que
están coloreados de verde? Debido a que no hay forma de llegar a ellos, se convierten en basura y la
memoria que ocupan sería liberada por el Recolector de Basura cuando sea el momento. Se concluye
entonces que, después de las operaciones descritas, la lista queda vacía.
Figura 10. Estado de la lista después de re-encadenar el encabezado consigo mismo y de asignarle cero al tamaño
Fuente: Sotelo (s.f.)
POLITÉCNICO GRANCOLOMBIANO 7
La figura 11 contiene el método que elimina todos los elementos de una lista.
La tabla 2 presenta los análisis de complejidad temporal del método que elimina todos los elementos
de la lista para el mejor y el peor caso.
Tabla 2. Análisis de complejidad temporal del método void clear ( ) Modificado de Sotelo (s.f)
Para las operaciones de consulta, modificación, inserción y eliminación es necesario contar con un
método que, dada una posición, entregue el nodo de la lista que guarda el elemento de la posición
dada. Este método es el presentado en la figura 12.
POLITÉCNICO GRANCOLOMBIANO 8
Figura 12. Método que retorna el nodo que se encuentra en una posición de la lista
Fuente: Sotelo (s.f.)
Si index está entre 0 y tamanho-1, el método getNodo retorna como resultado el nodo que
almacena el elemento de la posición index de la lista; de lo contrario, retorna header. En caso
de que index sea menor que la mitad del tamaño de la lista, sale más barato llegar al nodo yendo
hacia delante de siguiente en siguiente; por otro lado, si index es mayor que la mitad del tamaño
de la lista, sale más barato llegar al nodo yendo hacia atrás de anterior en anterior. Obsérvese que, si
index es igual a la mitad del tamaño de la lista, es igual de pesado ir hacia delante que ir hacia atrás.
La tabla 3, presenta los análisis de complejidad temporal del método que retorna un nodo, dada su
posición en la lista.
Tabla 3. Análisis de complejidad temporal de VedNodo getnodo(int index). Modificado de Sotelo (s.f)
POLITÉCNICO GRANCOLOMBIANO 9
Usando el método getNodo es posible consultar el elemento que se encuentra en cierta posición de
la lista, como se muestra en la figura 13.
Figura 13. Método para consultar el valor del elemento en una determinada posición de la lista
Fuente: Sotelo (s.f.)
Nótese que la complejidad temporal del algoritmo depende completamente del método getNodo,
como se muestra en la tabla 4.
Tabla 4. Análisis de complejidad temporal de E get (int index). Modificado de Sotelo (s.f)
Usando el método getNodo es posible modificar el elemento que se encuentra en cierta posición de
la lista, como se muestra en la figura 14.
POLITÉCNICO GRANCOLOMBIANO 10
Figura 14. Método para modificar el valor del elemento en una determinada posición de la lista
Fuente: Sotelo (s.f.)
Nótese que la complejidad temporal del algoritmo depende completamente del método getNodo,
como se muestra en la tabla 5.
Tabla 5. Análisis de complejidad temporal de E set (int index, E element). Modificado de Sotelo (s.f)
A. Crear un nuevo nodo cuyo valor sea el elemento que se desea insertar. Esta situación se
representa gráficamente en la figura 15 y el código correspondiente en lenguaje Java se muestra
en la figura 16.
POLITÉCNICO GRANCOLOMBIANO 11
Figura 15. Un nuevo nodo es creado, pero aún no se incluye en la lista
Fuente: Sotelo (s.f.)
POLITÉCNICO GRANCOLOMBIANO 12
C. Poner el anterior del nodo nuevo en el nodo a y el siguiente del nodo nuevo en el nodo b. Esta
situación se representa gráficamente en la figura 19 y el código correspondiente en lenguaje
Java se muestra en la figura 20.
Figura 19. El nodo a es asociado como anterior y el nodo b como siguiente al nodo nuevo
Fuente: Sotelo (s.f.)
Figura 20. Código para asociar el nodo a como anterior y el nodo b como siguiente al nodo nuevo
Fuente: Sotelo (s.f.)
D. Poner el siguiente del nodo a en el nodo nuevo y el anterior del nodo b en el nodo nuevo. Esta
situación se representa gráficamente en la figura 21 y el código correspondiente en lenguaje Java
se muestra en la figura 22.
Figura 21. El nodo nuevo es asociado como siguiente al nodo a y como anterior al nodo b
Fuente: Sotelo (s.f.)
POLITÉCNICO GRANCOLOMBIANO 13
Figura 22. Código para asociar el nodo nuevo como siguiente al nodo a y como anterior al nodo b
Fuente: Sotelo (s.f.)
Figura 23. Código implementado en Java para ejecutar los pasos del proceso de inserción
Fuente: Sotelo (s.f.)
Como en los anteriores casos, la complejidad temporal del algoritmo depende completamente del
método getNodo, como lo muestra la tabla 6.
Tabla 6. Análisis de complejidad temporal de void add(int index, E element). Modificado de Sotelo (s.f)
POLITÉCNICO GRANCOLOMBIANO 14
1.1.6. Operación de eliminación
Usando el método getNodo, también es posible eliminar el elemento ubicado en cierta posición de
la lista (supóngase que k es la posición del elemento que se desea eliminar de la lista). El proceso de
eliminación es el siguiente:
A. Por medio de la función getNodo, se obtiene un apuntador b al nodo que almacena el elemento
de la posición index, se declara a como un apuntador al nodo anterior del nodo b, y se declara c
como un apuntador al nodo siguiente del nodo b. Esta situación se representa gráficamente en
la figura 24 y el código correspondiente en lenguaje Java se muestra en la figura 25.
Figura 24. Tres apuntadores son dispuestos para el nodo que será eliminado y sus vecinos
Fuente: Sotelo (s.f.)
Figura 25. Código para referenciar tres apuntadores al nodo que será eliminado y sus vecinos
Fuente: Sotelo (s.f.)
B. Poner el siguiente del nodo a en el nodo c y el anterior del nodo c en el nodo a. Esta situación se
representa gráficamente en la figura 26 y el código correspondiente en lenguaje Java se muestra
en la figura 27.
Figura 26. El nodo a se asocia como anterior al nodo c y el nodo c como siguiente al nodo
Fuente: Sotelo (s.f.)
POLITÉCNICO GRANCOLOMBIANO 15
Figura 27. Código para asociar el nodo a como anterior al nodo c y el nodo c como siguiente al nodo a
Fuente: Sotelo (s.f.)
D. Como el elemento xk dejó de ser referenciado por la lista, se volvió basura. Cuando lo decida la
Máquina Virtual de Java, el Recolector de Basura liberará la memoria ocupada por este nodo. Esta
situación se representa gráficamente en la figura 28.
La figura 29 compendia el código presentado en este y los anteriores pasos y lo incluye dentro de un
método diseñado para eliminar un elemento.
Figura 29. Código implementado en Java para ejecutar los pasos del proceso de eliminación
Fuente: Sotelo (s.f.)
POLITÉCNICO GRANCOLOMBIANO 16
Nuevamente, se observa que la complejidad temporal del algoritmo depende completamente del
método getNodo. El análisis se muestra en la tabla 7.
¿Sabía que...?
Responda los siguientes interrogantes: ¿por qué el algoritmo de eliminación
descrito funciona para eliminar al principio de la lista, para eliminar al final de la
lista y para eliminar en medio de la lista? ¿Tiene algo que ver con el encabezado?
Otra implementación posible para las listas es la que usa nodos doblemente encadenados con
apuntador al primero y al último (de aquí en adelante, se llamará a esta versión VEDLinkedListD<E>).
La figura 30 representa esta implementación con un número n de nodos; mientras que, la figura 31
muestra la misma implementación para una lista vacía.
POLITÉCNICO GRANCOLOMBIANO 17
Figura 30. Representación de la lista como una lista 〈x0, x1, x2, … ,xn-1 〉doblemente encadenada de tipo VEDLinkedListD<E>
Fuente: Sotelo (s.f.)
Figura 31. Representación una lista vacía como una lista doblemente encadenada de tipo VEDLinkedListD<E>
Fuente: Sotelo (s.f.)
Las listas también se pueden implementar con nodos sencillamente encadenados con apuntador
al primero (de aquí en adelante, se llamará a esta versión VEDLinkedListS<E>). En una lista
sencillamente encadenada, los nodos solo tienen valor y apuntador al siguiente. La figura 32 es la
representación gráfica de un nodo; la figura 33 representa esta implementación con un número n de
nodos; finalmente, la figura 34 muestra la misma implementación para una lista vacía.
POLITÉCNICO GRANCOLOMBIANO 18
Figura 33. Representación de la lista como una lista 〈x0, x1, x2, … ,xn-1 〉 sencillamente encadenada de tipo VED
LinkedListS<E>.
Fuente: Sotelo (s.f.)
Figura 34. Representación de una lista vacía como una lista sencillamente encadenada de tipo VEDLinkedListS<E>.
Fuente: Sotelo (s.f.)
Tabla 8. Cuadro comparativo de las ventajas y desventajas en términos de eficiencia de las distintas implementaciones de listas
POLITÉCNICO GRANCOLOMBIANO 19
Implementación Ventajas Desventajas
POLITÉCNICO GRANCOLOMBIANO 20
2. Pilas
Una pila (en inglés stack), es una estructura de datos lineal, que solo permite inserciones
y eliminaciones en uno de los extremos, llamado tope. Las figuras 35a, 35b y 35c son ejemplos de
pilas que pueden encontrarse en el mundo real.
La clase Stack<E> de Java, que extiende de la clase Vector<E>, representa una pila de elementos
de tipo E y permite realizar, entre otras, las operaciones relacionadas en la tabla 9.
Implementación Ventajas
E push (E item) Insertar en el tope de la pila el ítem suministrado. Retorna el ítem insertado.
POLITÉCNICO GRANCOLOMBIANO 21
Como todo elemento en una pila, puede ser añadido o eliminado solo por el tope, se cumple que el
último elemento que se inserta es el primer elemento que puede eliminarse, razón por la que se dice
que esta estructura de datos satisface que el último en entrar es el primero en salir (Last-in First-Out en
inglés, abreviado con las siglas LIFO). La figura 36 es una representación esquemática de esta condición.
Gracias a que la clase Stack<E> extiende de la clase Vector<E>, las pilas en Java están
implementadas con arreglos dinámicos de tamaño variable (vectores) como se muestra en la figura 37.
Figura 37. Representación de una pila en Java por medio de arreglos de tamaño variable
Fuente: Sotelo (s.f.)
POLITÉCNICO GRANCOLOMBIANO 22
Estando el tope en la última posición del vector, las operaciones push, pop y peek tienen complejidad
temporal O(1), porque las inserciones, eliminaciones y consultas al final de una lista implementada
con arreglos son O(1) todas, con la salvedad de que la complejidad de las inserciones se vuelve O(n)
cuando hay que aumentar el tamaño del arreglo. La tabla 10, contiene el ejemplo de la manera en que
una serie de operaciones afecta una pila.
Tabla 10. Evolución de una pila de cadenas de texto tras una secuencia de operaciones
POLITÉCNICO GRANCOLOMBIANO 23
3. Colas
Una cola (en inglés queue), es una estructura de datos lineal, que permite inserciones en un extremo
(llamado cola) y eliminaciones del otro extremo (llamado cabeza). La figura 38, ejemplifica una cola:
La interfaz Queue<E> de Java, implementada por la clase LinkedList<E>, representa una cola
de elementos de tipo E que permite realizar, entre otras, las operaciones relacionadas en la tabla 11:
Implementación Ventajas
Insertar en la cola el ítem suministrado. Retorna verdadero en
boolean offer (E item)
caso de éxito.
E poll ( ) Elimina y retorna el objeto que se encuentra en la cabeza de la cola.
POLITÉCNICO GRANCOLOMBIANO 24
Como todo elemento en una cola puede ser insertado solo en la cola y eliminado solo de la cabeza,
se cumple que el primer elemento que se inserta es el primer elemento que puede eliminarse, razón
por la que se dice que esta estructura de datos satisface que el primero en entrar es el primero en salir
(First-in First-Out en inglés, abreviado con las siglas FIFO). La figura 39, es una representación
esquemática de esta condición.
La clase LinkedList<E> provee una implementación de colas con nodos doblemente encadenados
en anillo con encabezado, como lo ilustra la figura 40:
Figura 40. Representación de una cola en Java por medio de nodos doblemente encadenados
Fuente: Sotelo (s.f.)
POLITÉCNICO GRANCOLOMBIANO 25
Estando la cola en la última posición de la lista y la cabeza en la primera, las operaciones offer,
poll y peek tienen complejidad temporal O(1), porque las inserciones, eliminaciones y consultas,
tanto al principio como al final de una lista implementada con nodos doblemente encadenados,
son todas O(1). Obsérvese que no sería muy apropiado implementar colas con arreglos dinámicos de
tamaño variable de tipo ArrayList<E> porque las inserciones y eliminaciones al principio del
arreglo tienen complejidad O(n). La tabla 12, contiene el ejemplo de la manera en que una serie de
operaciones afecta una cola:
Tabla 12. Evolución de una cola de cadenas de texto tras una secuencia de operaciones
POLITÉCNICO GRANCOLOMBIANO 26
En síntesis...
Una pila es una estructura de datos lineal que solo permite inserciones y eliminaciones en uno de los
extremos, llamado tope. Una forma apropiada de representar una pila es por medio del uso de arreglos
dinámicos de tamaño variable.
Una cola es una estructura de datos lineal que permite inserciones en un extremo, llamado cola, y
eliminaciones del otro extremo, llamado cabeza. Una forma apropiada de representar una cola es por
medio del uso de nodos doblemente encadenados en anillo encabezado.
POLITÉCNICO GRANCOLOMBIANO 27
Referencias
Sotelo, A. (s.f.). Implementaciones de listas (parte 2). Bogotá, Colombia.
Freepik. (2017). Stacked books with different colors [Gráfica]. Recuperado de https://www.
freepik.com/free-photo/stacked-books-with-different-colors_1092555.htm#term=stack of
books&page=1&position=4
Sotelo, Alejandro. (s.f.). Estado de la lista antes de llamar al método void clear() [Diagrama].
Recuperado de https://poli.instructure.com/courses/67/files/2431?module_item_id=2121
POLITÉCNICO GRANCOLOMBIANO 28
Sotelo, Alejandro. (s.f.). Estado de la lista después de llamar al método void clear() [Diagrama].
Recuperado de https://poli.instructure.com/courses/67/files/2431?module_item_id=2121
Sotelo, Alejandro. (s.f.). Estado de la lista después de re-encadenar el encabezado consigo mismo
y de asignarle cero al tamaño [Diagrama]. Recuperado de https://poli.instructure.com/courses/67/
files/2431?module_item_id=2121
Sotelo, Alejandro. (s.f.). Estado de la lista después de re-encadenar el encabezado consigo mismo
y de asignarle cero al tamaño [Diagrama]. Recuperado de https://poli.instructure.com/courses/67/
files/2431?module_item_id=2121
Sotelo, Alejandro. (s.f.). Estado de la lista justo después de la inicialización de los atributos de la
clase VEDLinkedList<E> [Diagrama]. Recuperado de https://poli.instructure.com/courses/67/
files/2431?module_item_id=2121
Sotelo, Alejandro. (s.f.). Estado deseado después de la construcción de una lista vacía [Diagrama].
Recuperado de https://poli.instructure.com/courses/67/files/2431?module_item_id=2121
Sotelo, Alejandro. (s.f.). Evolución de una cola de cadenas de texto tras una secuencia de operaciones
de ejemplo. Recuperado de https://poli.instructure.com/courses/67/files/2391?module_item_
id=2123
Sotelo, Alejandro. (s.f.). Evolución de una pila de cadenas de texto tras una secuencia de operaciones
de ejemplo. Recuperado de https://poli.instructure.com/courses/67/files/2391?module_item_
id=2123
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/2431?module_item_id=2121
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/2431?module_item_id=2121
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/2431?module_
item_id=2121
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/2431?module_item_id=2121
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/2431?module_item_id=2121
Sotelo, Alejandro. (s.f.). Método que retorna el nodo que almacena el valor que se encuentra en
determinada posición de la lista [Captura de pantalla]. Recuperado de https://poli.instructure.com/
courses/67/files/2431?module_item_id=2121
Sotelo, Alejandro. (s.f.). Representación de la lista 〈x0, x1, x2, … ,xn-1 〉 como una lista doblemente
encadenada en anillo con encabezado [Diagrama]. Recuperado de https://poli.instructure.com/
courses/67/files/2431?module_item_id=2121
Sotelo, Alejandro. (s.f.). Representación de la lista 〈x0, x1, x2, … ,xn-1 〉 como una lista doblemente
encadenada de tipo VEDLinkedListD<E> [Diagrama].]. Recuperado de https://poli.instructure.com/
courses/67/files/2431?module_item_id=2121
Sotelo, Alejandro. (s.f.). Representación de la lista como una lista sencillamente encadenada de
tipo VEDLinkedListS<E> [Diagrama]. Recuperado de https://poli.instructure.com/courses/67/
files/2431?module_item_id=2121
Sotelo, Alejandro. (s.f.). Representación de la lista vacía como una lista doblemente encadenada
en anillo con encabezado [Diagrama Recuperado de https://poli.instructure.com/courses/67/
files/2431?module_item_id=2121
Sotelo, Alejandro. (s.f.). Representación de la lista vacía como una lista doblemente encadenada
de tipo VEDLinkedListD<E> [Diagrama]. Recuperado de https://poli.instructure.com/courses/67/
files/2431?module_item_id=2121
Sotelo, Alejandro. (s.f.). Representación de la lista vacía como una lista sencillamente encadenada
de tipo VEDLinkedListS<E> [Diagrama]. Recuperado de https://poli.instructure.com/courses/67/
files/2431?module_item_id=2121
Sotelo, Alejandro. (s.f.). Representación gráfica de los nodos en una lista doblemente encadenada
[Diagrama]. Recuperado de https://poli.instructure.com/courses/67/files/2431?module_item_id=2121
Sotelo, Alejandro. (s.f.). Representación gráfica de los nodos en una lista sencillamente encadenada
[Diagrama]. Recuperado de https://poli.instructure.com/courses/67/files/2431?module_item_id=2121
Sotelo, Alejandro. (s.f.). Representación interna de las colas en Java, a través de nodos
doblemente encadenados [Diagrama]. Recuperado de https://poli.instructure.com/courses/67/
files/2391?module_item_id=2123
Sotelo, Alejandro. (s.f.). Representación interna de las pilas en Java, a través de arreglos dinámicos
de tamaño variable [Diagrama]. Recuperado de https://poli.instructure.com/courses/67/
files/2391?module_item_id=2123
Sotelo, Alejandro. (s.f.). Representación lineal de la lista 〈x0, x1, x2, … ,xn-1 〉 como una lista
doblemente encadenada en anillo con encabezado [Diagrama]. Recuperado de https://poli.
instructure.com/courses/67/files/2431?module_item_id=2121
POLITÉCNICO GRANCOLOMBIANO 32