Está en la página 1de 6

UNIVERSIDAD ANDINA DEL CUSCO

FACULTAD DE INGENIERÍA Y ARQUITECTURA


ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMAS
ESTRUCTURA DE DATOS

Guía de estudio Nº 06: Listas enlazadas.

Fecha: setiembre 2022


Semestre: 2022-II

I. COMPETENCIAS A LOGRAR
Durante el desarrollo de la guía el estudiante:
● Conocerá y aplicará los conceptos de la lista enlazada.
● Realizará correctamente la implementación y uso de una lista enlazada.
● Aplicará los algoritmos de una lista enlazada en sus diferentes versiones.
● Entenderá las ventajas de del uso de la lista enlazada para la solución de
problemas complejos de agrupación de datos.

II. DESARROLLO
Un arreglo es el contenedor de secuencias más básico utilizado para almacenar y acceder
a una colección de datos, proporcionando un acceso fácil y directo a los elementos
individuales. Pero los arreglos tienen una funcionalidad limitada.

La lista de Python, que también es un contenedor de secuencias, es un tipo de secuencia


abstracta implementada utilizando una estructura tipo arreglo. Extiende la funcionalidad
de un arreglo proporcionando un conjunto de operaciones más amplio que el de los
arreglos, y puede ajustarse automáticamente en tamaño a medida que se añaden o
eliminan elementos.

El arreglo y la lista de Python pueden utilizarse para implementar muchos tipos de datos
abstractos diferentes. Ambos almacenan datos en orden lineal y proporcionan un fácil
acceso a sus elementos. La búsqueda binaria puede utilizarse con ambas estructuras
cuando los elementos se almacenan ordenados para permitir búsquedas rápidas.

Pero hay varias desventajas en el uso del arreglo y la lista de Python. En primer lugar, las
operaciones de inserción y eliminación suelen requerir que los elementos se desplacen
para hacer espacio o cerrar un hueco. Esto puede llevar mucho tiempo, sobre todo en el
caso de las secuencias grandes. En segundo lugar, el tamaño de un arreglo es fijo y no
puede cambiar. Mientras que la lista de Python proporciona una colección expandible, esa
expansión no viene sin un coste. Dado que los elementos de una lista de Python se
almacenan en una matriz, una expansión requiere la creación de una nueva ma triz más
grande en la que los elementos de la matriz original tienen que ser copiados. Por último,
los elementos de un arreglo se almacenan en bytes contiguos de memoria, sin importar el
tamaño del arreglo. Cada vez que se crea un arreglo, el programa debe encontrar y asignar
un bloque de memoria lo suficientemente grande como para almacenar todo el arr eglo.
Para matrices grandes, puede ser difícil o imposible para el programa localizar un bloque
de memoria en el que se pueda almacenar el arreglo. Esto es especialmente cierto en el
caso de una lista de Python que crece durante la ejecución de un programa, ya que cada
expansión requiere bloques de memoria cada vez más grandes.
UNIVERSIDAD ANDINA DEL CUSCO
FACULTAD DE INGENIERÍA Y ARQUITECTURA
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMAS
ESTRUCTURA DE DATOS

Una estructura de datos de lista enlazada incluye una serie de nodos conectados. Aquí,
cada nodo almacena los datos y la dirección del siguiente nodo.

Figura 1

Hay que empezar por algún sitio, así que damos a la dirección del primer nodo un nombre
especial llamado HEAD. Además, el último nodo de la lista enlazada puede ser identificado
porque su siguiente porción apunta a NULL.

Por lo tanto, las listas son un tipo de estructura de datos lineal y dinámica. Es lineal porque
cada elemento tiene un único predecesor y un único sucesor, y es dinámica porque su tamaño
no es fijo y se puede definir conforme se requiera. Las operaciones básicas dentro de una
lista son Buscar, Insertar y Eliminar.

Una lista simple (también conocida como lista ligada o lista simplemente ligada) está
constituida por un conjunto de nodos alineados de manera lineal (uno después de otro) y
unidos entre sí por una referencia.

A diferencia de un arreglo, el cual también es un conjunto de nodos alineados de manera


lineal, el orden está determinado por una referencia, no por un índice, y el tamaño no es
fijo.

La unidad básica de una lista simple es un elemento o nodo. Cada elemento de la lista es
un objeto que contiene la información que se desea almacenar, así como una referencia
(Next) al siguiente elemento (Sucesor).

Figura 2

Para poder diseñar un algoritmo que defina el comportamiento de una LISTA LIGADA se
deben considerar 2 casos para cada operación (Buscar, Insertar y Eliminar):
• Estructura vacía (caso extremo).
• Estructura con elemento(s) (caso base).

INSERTAR:
Dado un nodo x que contenga una llave k previamente establecida, el método Insertar
agrega el elemento x al inicio de la lista.

Es posible insertar elementos tanto en una lista simple vacía como en una lista simple con
elementos. Cuando se inserta un nuevo elemento en una lista simple vacía la referencia al
inicio de la lista (Head) apunta al nodo insertado.
UNIVERSIDAD ANDINA DEL CUSCO
FACULTAD DE INGENIERÍA Y ARQUITECTURA
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMAS
ESTRUCTURA DE DATOS

Figura 3

Cuando se inserta un nuevo elemento en una lista simple con elementos, la referencia del
nuevo nodo (Next) apunta al mismo nodo al que apunta el inicio de la lista (Head) y ahora
Head apunta al nuevo nodo.

Figura 4

ELIMINAR:
El método elimina el elemento x de la lista L (si es que éste se encuentra en la estructura).
Para eliminar un elemento de la lista primero es necesario saber la ubicación del nodo a
eliminar, por lo tanto, primero se debe realizar una búsqueda del element o.

En una lista simple vacía no es posible eliminar, debido a que esta estructura no contiene
elementos. Para eliminar un nodo en una lista simple con elementos, primero se debe
buscar el elemento a eliminar, una vez encontrado el nodo en la lista, se de ben mover las
referencias de la estructura de tal manera de que el antecesor del nodo a eliminar apunte
al sucesor del mismo.

Figura 5

BUSCAR:
El método debe buscar el primer elemento que coincida con la llave K dentro de la lista L,
a través de una búsqueda lineal simple, regresando un apuntador a dicho elemento si éste
se encuentra en la lista o nulo en caso contrario.
UNIVERSIDAD ANDINA DEL CUSCO
FACULTAD DE INGENIERÍA Y ARQUITECTURA
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMAS
ESTRUCTURA DE DATOS

Una lista simple vacía no contiene elementos, la referencia al inicio de la misma (head)
apunta a nulo, por lo tanto, en una lista vacía no es posible buscar elementos.

NULL
Figura 6

Una lista simple con elementos puede contener de 1 a n elementos, en tal caso, la
referencia al inicio (Head) apunta al primer elemento de la lista. Es posible recorrer la lista
a través de la referencia (Next) de cada nodo hasta llegar al que apunta a Nullo, el cuál
será el último elemento. Por lo tanto, dentro de una lista simple con elementos e s posible
buscar una llave K.

Figura 7

III. DESARROLLO EN LABORATORIO:

Ejemplo 1:
class ListNode :
def __init__(self, data ) :
self.data = data

a = ListNode(23)
b = ListNode(66)
c = ListNode(91)

Ahora, supongamos que añadimos un segundo elemento de datos a la clase


ListNode:

class ListNode :
def __init__(self, data ) :
self.data = data
self.next = None

a.next = b
b.next = c
print( a.data )
print( a.next.data )
print( a.next.next.data )
UNIVERSIDAD ANDINA DEL CUSCO
FACULTAD DE INGENIERÍA Y ARQUITECTURA
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMAS
ESTRUCTURA DE DATOS

Ejemplo 2:
class LinkedList:
def __init__(self):
self.head = None

# Insertando un elemento al inicio


def insertAtBeginning(self, data):
new_node = ListNode(data)
new_node.next = self.head
self.head = new_node

# Insertar después del nodo


def insertAfter(self, node, data):
if node is None:
print("El nodo anterior debe estar en la lista enlazada.")
return
new_node = ListNode(data)
new_node.next = node.next
node.next = new_node

# Insertar al final
def insertAtEnd(self, data):
new_node = ListNode(data)
if self.head is None:
self.head = new_node
return
last = self.head
while (last.next):
last = last.next
last.next = new_node

# Eliminando un nodo
def deleteNode(self, position):
if self.head == None:
return
temp_node = self.head
if position == 0:
self.head = temp_node.next
temp_node = None
return

# Buscando el nodo para ser eliminado


for i in range(position - 1):
temp_node = temp_node.next
if temp_node is None:
break

# Si no existe el nodo a eliminar


if temp_node is None:
return
UNIVERSIDAD ANDINA DEL CUSCO
FACULTAD DE INGENIERÍA Y ARQUITECTURA
ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMAS
ESTRUCTURA DE DATOS

if temp_node.next is None:
return
next = temp_node.next.next
temp_node.next = None
temp_node.next = next

def printList(self):
temp_node = self.head
while (temp_node):
print(str(temp_node.item) + " ", end="")
temp_node = temp_node.next

llist = LinkedList()
llist.insertAtEnd(1)
llist.insertAtBeginning(2)
llist.insertAtBeginning(3)
llist.insertAtEnd(4)
llist.insertAfter(llist.head.next, 5)
print('Lista enlazada:')
llist.printList()
print("\nLista después de eliminar el elemento:")
llist.deleteNode(3)
llist.printList()

IV. EJERCICIOS PRÁCTICOS A DESARROLLAR:


1. Implementar una lista enlazada circular

También podría gustarte