Las listas vinculadas, enlazadas o enhebradas en la estructuras de datos lineales en las que los elementos no se almacenan en ubicaciones contiguas en la memoria y en las que los elementos están vinculados entre sí mediante punteros. La siguiente figura muestra la estructura de listas enlazadas:

Las listas de subprocesos constan de nodos y cada nodo contiene un campo de datos y un puntero (enlace) al siguiente nodo de la lista.
Tabla de contenidos
- ¿Por qué utilizar listas vinculadas?
- Listas y matrices vinculadas
- Desventajas de las listas enlazadas
- Representación de listas enlazadas
- Crea listas enlazadas
- Navegación por los nodos en las listas de los subprocesos
- Agregar nodos a listas de subprocesos
- Eliminar nodos de listas vinculadas
- Buscar un elemento en la lista encadenada
- Fuente
¿Por qué utilizar listas vinculadas?
Las matrices se pueden utilizar para almacenar datos lineales del mismo tipo, pero el uso de estas matrices tienen las siguientes desventajas:
- Las matrices tienen un tamaño fijo, lo que significa que debemos conocer el número máximo de elementos que entrarán en la matriz de antemano, y la cantidad de memoria reservada es igual a la cantidad máxima de elementos en la matriz, independientemente de cuantos elementos la componen realmente.
- Para agregar un nuevo elemento a la matriz requiere un elevado consumo de memoria. Esto se debe a que agregar un nuevo elemento significa encontrar un espacio para él en la matriz, lo que a su vez significa desplazar los elementos de la matriz de sus posiciones.
Supongamos el siguiente ejemplo, digamos que tenemos una lista de identificadores dispuestos en una matriz: id[] = [10, 12, 15, 20, 22].
Si queremos agregar un nuevo identificador que contenga el valor 15 sin alterar el orden de los elementos, entonces tenemos que mover todos los elementos que siguen al identificador 10.
El proceso de eliminación también es costoso, a menos que usemos algunas técnicas especiales. Por ejemplo, para poder borrar el identificador 12 en el arreglo anterior, debemos mover todos los elementos que siguen al identificador 12.
Listas y matrices vinculadas
Las listas enlazadas difieren de las matrices en los siguientes puntos:
- Una matriz es una estructura de datos que contiene un grupo de elementos de tipo similar, mientras que una lista vinculada es una estructura de datos no primitiva que contiene un grupo de elementos relacionados y desordenados llamados nodos.
- Los elementos de las matrices pertenecen a índices, lo que significa que para acceder al cuarto elemento de la matriz, el nombre de la variable debe escribirse con su índice o ubicación entre corchetes.
- En las listas enlazadas, debes empezar desde la cabecera y luego ir pasando por los elementos uno por uno hasta llegar al cuarto elemento.
- Se puede acceder rápidamente a un elemento de una matriz. Para una lista vinculada, se necesita más tiempo lineal para acceder a los elementos. Por lo tanto, las listas de subprocesos son un poco más lentas que las matrices.
- Las operaciones como la adición y eliminación toman mucho tiempo en matrices, pero son rápidas en listas de subprocesos.
- Las matrices tienen un tamaño fijo, a diferencia de las listas de subprocesos que tienen un tamaño variable y son flexibles y tienen la capacidad de aumentar o disminuir su tamaño según sea necesario.
- La información sobre el uso de matrices se asigna a la memoria en el momento de la compilación. Cuando se utilizan listas de subprocesos, la memoria se reserva en el tiempo de ejecución.
- Los elementos de la matriz se almacenan en orden y se almacenan en listas relacionadas aleatoriamente.
- Las matrices requieren menos memoria porque los datos reales se almacenan en el índice y las listas de subprocesos requieren más memoria porque necesitan almacenar elementos adicionales para apuntar a los nodos anteriores y posteriores.
- La memoria no se puede utilizar de forma eficiente con matrices, a diferencia de las listas enlazadas.
Desventajas de las listas enlazadas
- No se puede acceder a las listas de subprocesos de forma aleatoria, se debe acceder a ellas en orden comenzando desde el primer nodo. Por lo tanto, la búsqueda binaria no se puede realizar de manera eficiente si usamos el método predeterminado para tratar con listas enhebradas.
- Cada elemento necesita espacio de memoria adicional para que cada elemento esté asociado con un puntero.
- No es compatible con la caché. Dado que los elementos de la matriz están en ubicaciones contiguas, las referencias a los elementos están en una única localidad de referencia, algo que falta en las listas vinculadas.
Representación de listas enlazadas
Una lista de subprocesos está representada por un puntero al primer nodo en la lista de subprocesos. El primer nodo se llama cabeza, y si la lista de subprocesos está vacía, el valor del encabezado es NULL.
Cada nodo de la lista tiene dos partes:
- datos.
- Punteros o referencia al siguiente nodo.
Los nodos se pueden representar en C usando estructuras. El siguiente ejemplo muestra un nodo de lista enhebrado con datos escalares.
struct Node {
int data;
struct Node *next;
}En Java y C #, las listas de subprocesos se pueden representar por una clase y los nodos por una clase separada, y la clase de lista de subprocesos contiene una referencia a la clase de nodo.
class LinkedList {
Node head;
class Node {
int data;
Node next;
// constructor para crear un nuevo nodo
Node (int d) {data = d;}
}
}
class LinkedList {
Node head;
class Node {
int data;
Node next;
// constructor para crear un nuevo nodo
// el valor del nodo siguiente se inicializa automáticamente a nulo
Node(int d) {data = d;}
}
}
# Node class
class Node:
#función para inicializar el objeto de nodo
def __init__(self, data):
self.data = data # Asignamos datos
self.next = None # Inicializa el siguiente nodo para que esté vacío null
#
class LinkedList:
# Función para inicializar el objeto de lista enhebrada
def __init__(self):
self.head = NoneCrea listas enlazadas
Los siguientes ejemplos muestran cómo crear listas de subprocesos en varios lenguajes de programación(C++, Python, Java) :
#include <bits/stdc++.h>
using namespace std;
class Node {
public:
int data;
Node *next;
}
// Este programa crea una lista sencilla
// que tiene tres nodos
int main() {
Node* head = NULL;
Node* second = NULL;
Node* third = NULL;
// reservar posiciones para 3 nodos
head = new Node();
second = new Node();
third = new Node();
/*
Tres bloques se reservan en memoria dinámicamente y
tenemos punteros a estos bloques son
head second third
| | |
| | |
+---+-----+ +----+----+ +----+----+
| # | # | | # | # | | # | # |
+---+-----+ +----+----+ +----+----+
representa cualquier valor aleatorio Los datos son aleatorios porque no hemos asignado ningún valor aún
*/
head->data = 1; // asigna un valor al primer
head->next = second; // atar el primer nudo con el segundo
/*
Los datos se asignan a la parte de datos del primer bloque (encabezado del menú) y el puntero
posterior apunta al segundo bloque, por lo que los dos bloques están relacionados
head second third
| | |
| | |
+---+---+ +----+----+ +-----+----+
| 1 | o----->| # | # | | # | # |
+---+---+ +----+----+ +-----+----+
*/
second->data = 2; // asigna un valor al segundo nodo
second->next = third; // conecta el segundo nodo al tercer
/*
Asignar un valor a la parte de datos del segundo bloque,
y el puntero al segundo bloque apunta al tercer bloque,
por lo que los dos bloques están vinculados
head second third
| | |
| | |
+---+---+ +---+---+ +----+----+
| 1 | o----->| 2 | o-----> | # | # |
+---+---+ +---+---+ +----+----+
*/
third->data = 3; // asigna un valor al tercer nodo
third->next = NULL;
/*
Asignar un valor a la parte de datos del tercer nodo
Null y el puntero final en el tercer bloque apunta al valor
para indicar el final de la lista enhebrada en esa posición
head
|
|
+---+---+ +---+---+ +----+------+
| 1 | o----->| 2 | o-----> | 3 | NULL |
+---+---+ +---+---+ +----+------+
Tenga en cuenta que el encabezado de la lista es suficiente para representar la lista completa. Puede navegar por todos los elementos del menú siguiendo el cursor
*/
return 0;
}clase Nodo:
# Una función para inicializar el objeto de nodo
def __init__(self, data):
self.data = data # Asignar datos a
self.next = None # null Inicializa el nodo subsiguiente para ser
# clase de lista vinculada que contiene el objeto
class LinkedList:
# Inicializar encabezado de lista
def __init__ ( self ):
self.head = none
if __name__=='__main__':
# Comenzamos con una lista de subprocesos vacía
llist = LinkedList()
llist.head = Node(1)
second = Node(2)
third = Node(3)
'''
Tres bloques se reservan dinámicamente en la memoria y
tenemos punteros a estos bloques son
first, second, third
llist.head second third
| | |
| | |
+----+------+ +----+------+ +----+------+
| 1 | None | | 2 | None | | 3 | None |
+----+------+ +----+------+ +----+------+
'''
llist.head.next = second; # une el primer nudo al segundo
'''
El primer nodo ahora se refiere al segundo nodo, por lo que están interconectados
llist.head second third
| | |
| | |
+ ---- + ------ + + ---- + ------ + + ---- + ------ +
| 1 | o --------> | 2 | nulo | 3 | | nulo |
+ ---- + ------ + + ---- + ------ + + ---- + ------ +
'''
second.next = third; # une el segundo nudo con el tercero
'''
El segundo nudo se refiere al tercer nudo, por lo que están interconectados
llist.head second third
| | |
| | |
+ ---- + ------ + + ---- + ------ + + ---- + ------ +
| 1 | o --------> | 2 | o --------> | 3 | nulo |
+ ---- + ------ + + ---- + ------ + + ---- + ------ +
'''class LinkedList {
Node head; // parte superior de la lista
/* lista de subprocesos nodo */
static class Node {
int data;
Node next;
Node(int d) { data = d; next=null; } // constructor }
}
/* Continuar creando una lista simple de tres nodos */
public static void main(String[] args) {
/* Comenzamos con una lista vacía */
LinkedList llist = new LinkedList();
llist.head = new Node(1);
Node second = new Node(2);
Node third = new Node(3);
/* Tres nodos reservan un lugar en la memoria dinámicamente y
nuestras referencias a estos bloques son
first, second, third
llist.head second third
| | |
| | |
+ ---- + ------ + + ---- + ------ + + ---- + ------ +
| 1 | nulo | | 2 | nulo | | 3 | nulo |
+ ---- + ------ + + ---- + ------ + + ---- + ------ + */
llist.head.next = second; // atar el primer nudo al segundo
/* El primer nodo ahora se refiere al segundo nodo y,
por lo tanto, los dos nodos están vinculados
llist.head second third
| | |
| | |
+ ---- + ------ + + ---- + ------ + + ---- + ------ +
| 1 | o --------> | 2 | nulo | | 3 | nulo |
+ ---- + ------ + + ---- + ------ + + ---- + ------ + */
second.next = third; // conecta el segundo nodo al tercer nodo
/* Ahora el segundo nodo se refiere al tercer nodo y
así los dos nodos están vinculados
llist.head second third
| | |
| | |
+ ---- + ------ + + ---- + ------ + + ---- + ------ +
| 1 | o --------> | 2 | o --------> | 3 | nulo |
+ ---- + ------ + + ---- + ------ + + ---- + ------ + */
}
}Navegación por los nodos en las listas de los subprocesos
Los siguientes ejemplos muestran cómo navegar por los nodos en listas de subprocesos en varios lenguajes de programación (C++, Python, Java):
#include <bits/stdc++.h>
using namespace std;
class Node {
public:
int data;
Node *next;
};
// Esta función imprime el contenido de la lista de subprocesos
// comenzando desde el nodo dado
void printList(Node *n) {
while (n != NULL) {
cout << n->data << " ";
n = n->next;
}
}
// prueba la función anterior
int main() {
Node* head = NULL;
Node* second = NULL;
Node* third = NULL;
// reserva tres nodos en la memoria
head = new Node();
second = new Node();
third = new Node();
head->data = 1; // Asignar los datos a la
head->next = second; // atar el primer nudo al segundo
second->data = 2; // Asignar los datos al segundo nodo
second->next = third;
third->data = 3; // Asignar los datos al tercer nodo
third->next = NULL;
printList(head);
return 0;
}class Node:
# Una función para inicializar el objeto de nodo
def __init__(self, data):
self.data = data # Asignar datos
self.next = None # null Inicializa el nodo subsiguiente
# class una lista vinculada que contiene un objeto de nodo de
class LinkedList:
# Inicializar encabezado de lista
def __init__(self):
self.head = None
# Esta función imprime el contenido de la lista
# enhebrada comenzando desde el nodo dado
def printList(self):
temp = self.head
while (temp):
print temp.data,
temp = temp.next
if __name__=='__main__':
# comenzar con una lista de subprocesos vacía
llist = LinkedList()
llist.head = Node(1)
second = Node(2)
third = Node(3)
llist.head.next = second; # Conecta el primer nudo con el
second.next = third; # Ate el segundo nudo con el tercero
llist.printList()class LinkedList {
Node head; // parte superior de la lista
/* Nodo en la lista de subprocesos */
static class Node {
int data;
Node next;
Node(int d) { data = d; next=null; } // constructor }
/* Esta función imprime el contenido de la lista enhebrada comenzando desde el encabezado de la lista */
public void printList() {
Node n = head;
while (n != null) {
System.out.print(n.data+" ");
n = n.next;
}
}
/* Crea una lista de subprocesos de tres nodos */
public static void main(String[] args) {
/* Empiece con una lista de subprocesos vacía */
LinkedList llist = new LinkedList();
llist.head = new Node(1);
Node second = new Node(2);
Node third = new Node(3);
llist.head.next = second; // Conecta el primer nodo al
second.next = third; // atar el segundo nudo al tercero
llist.printList();
}
}El código anterior da la siguiente salida:
1 2 3
Agregar nodos a listas de subprocesos
Los nodos se pueden agregar a la lista vinculada en tres lugares:
- al principio de la lista enhebrada.
- después de un cierto nodo.
- al final de la lista vinculada.
Agregue un nodo al comienzo de la lista de subprocesos
El nuevo nodo siempre se agrega antes del encabezado de la lista de subprocesos, y el nuevo nodo se convierte en el encabezado de esa lista. Por ejemplo, si tenemos la lista enlazada siguiente: y 10->15->20->25 añadimos el número 5 al principio de la lista, que se verá como esto: 5->10->15->20->25.
Si llamamos a la función que agrega el nuevo elemento al principio de la lista de subprocesos por nombre, push() entonces esta función debe recibir un puntero al puntero del encabezado. Esto se debe a que este puntero debe apuntar al nuevo nodo.
La complejidad temporal de la función push() O (1) se debe a que realiza una cantidad fija de trabajo.
Agregar un nodo después de un nodo existente
En este caso, tenemos un puntero a un nodo específico y queremos agregar un nuevo nodo después.
La complejidad temporal de una función insertAfter() O(q) se debe a que realiza una cantidad fija de trabajo.
Agregue un nodo al final de la lista de subprocesos
El nuevo nodo siempre se agrega después del último nodo en la lista de subprocesos. Por ejemplo, si tenemos la lista enlazada siguiente: y 5->10->15->20->25 queremos añadir el elemento 30 al final de la lista, la lista enlazada se hace de la siguiente manera: 5->10->15->20->25->30.
Dado que el encabezado suele ser una lista enhebrada, tenemos que pasar por los elementos de la lista hasta el final, y luego cambiar el nodo junto al último nodo para convertirlo en el nuevo nodo.
La cantidad de tiempo que representa la complejidad de este proceso para O(n) representar los n nodos de conteo en la lista vinculada, y cuando el tráfico por parte de los elementos existentes de la función de trabajo, la función para realizar el O(n) trabajo.
Esta función se puede mejorar con complejidad O(1)manteniendo un puntero adicional al final de la lista de subprocesos.
Ejemplos y aplicaciones en código
Los siguientes ejemplos muestran los tres métodos de suma y en varios lenguajes de programación:
#include <bits/stdc++.h>
using namespace std;
// lista de nodos interconectado
class Node {
public:
int data;
Node *next;
};
/* Inserta un nuevo nodo al principio de la lista
usando un puntero al encabezado de la lista
y el entero dado */
void push(Node** head_ref, int new_data) {
/* 1. Reserva la ubicación del nodo en la memoria */
Node* new_node = new Node();
/* 2. Agregar datos */
new_node->data = new_data;
/* 3. Hacer que el encabezado de la lista sea el siguiente nodo del nuevo nodo */
new_node->next = (*head_ref);
/* 4. Mover el encabezado de la lista para apuntar al nuevo nodo */
(*head_ref) = new_node;
}
/* Inserta un nodo después del nodo anterior dado */
void insertAfter(Node* prev_node, int new_data) {
/* 1. Null Comprueba que
el nodo anterior dado no puede ser NULL */
if (prev_node == NULL)
{
cout<<"the given previous node cannot be NULL";
return;
}
/* 2. Reserva la ubicación del nuevo nodo en la memoria */
Node* new_node = new Node();
/* 3. Agregar datos */
new_node->data = new_data;
/* 4. Hacer que el siguiente nodo del nuevo nodo sea el sucesor del nodo anterior */
new_node->next = prev_node->next;
/* 5. Mueva el siguiente nodo del nodo anterior para convertirse en el nuevo nodo */
prev_node->next = new_node;
}
/* Agrega un nuevo nodo al final de la lista usando el
puntero (un puntero a un puntero) al encabezado de la lista y el entero dado */
void append(Node** head_ref, int new_data) {
/* 1. Reserva la nueva ubicación del nodo en la memoria */
Node* new_node = new Node();
/* utilizado en el paso 5 */
Node *last = *head_ref;
/* 2. Insertar datos */
new_node->data = new_data;
/* 3. El nuevo nodo será el último nodo en la lista
por lo que haremos que el siguiente nodo sea
NULL */
new_node->next = NULL;
/* 4. Si la lista está vacía, el
nuevo nodo será en la cabecera de la lista */
if (*head_ref == NULL) {
*head_ref = new_node;
return;
}
/* 5. Si la lista no está vacía, mueva el nuevo nodo al final de la lista */
while (last->next != NULL)
last = last->next;
/* 6. Cambiamos el nodo final al último nodo. */
last->next = new_node;
return;
}
// Esta función imprime el contenido de la lista de subprocesos
// comenzando desde el encabezado
void printList(Node *node)
{
while (node != NULL)
{
cout<<" "<<node->data;
node = node->next;
}
}
// probar las funciones anteriores
int main() {
/* comenzar con una lista vacía */
Node* head = NULL;
// inserte el elemento 6
// la lista se verá así
// 6-> NULL
append(&head, 6);
// inserte el elemento 7 al principio de la lista
// la lista se verá así
// 7-> 6-> NULL
push(&head, 7);
// inserte el elemento 1 al principio de la lista
// la lista se verá así
// 1-> 7-> 6-> NULL
push(&head, 1);
// inserta el elemento 4 al final de la lista
append(&head, 4);
// inserta el elemento 8 después del elemento 7
// la lista se verá como
insertAfter(head->next, 8);
cout<<"Created Linked list is: ";
printList(head);
return 0;
}# class node
class Node:
# Una función para inicializar el objeto de nodo
def __init__(self, data):
self.data = data # Asignar datos a
self.next = None # null Inicializa el nodo subsiguiente para ser
# La clase de lista vinculada incluye un objeto de nodo de
class LinkedList:
# Función para inicializar el encabezado de la lista
def __init__(self):
self.head = None
# función para insertar un nodo al principio de la lista
def push(self, new_data):
# 1: reservando la ubicación del nodo en la memoria
# 2: agregando datos
new_node = Node(new_data)
# 3. Haga que el nodo final del nuevo nodo sea el encabezado
new_node.next = self.head
# 4: Mueva el encabezado de la lista para apuntar al nuevo nodo
self.head = new_node
# Este método inserta un nuevo nodo después de un nodo dado
def insertAfter(self, prev_node, new_data):
# 1: Verifique que un nodo dado esté realmente en la lista de subprocesos
if prev_node is None:
print "The given previous node must inLinkedList."
return
# 2: Cree un nuevo nodo
# 3: agregue datos
new_node = Node(new_data)
# 4: Haga que el nodo que sigue al nuevo nodo sea el nodo que sigue al
new_node.next = prev_node.next
# 5: Hacer que el nuevo nodo al nodo raíz de la dada
prev_node.next = new_node
# agrega un nuevo nodo al final de la lista de subprocesos
def append(self, new_data):
# 1: Crear un nuevo nodo
# 2: Agregar datos
# 3: Ninguno Hacer que el siguiente nodo sea
new_node = Node(new_data)
# 4: Haga que el nuevo nodo sea el encabezado de la lista
# si la lista enhebrada está vacía
if self.head is None:
self.head = new_node
return
# 5: de lo contrario, Venntql a través de los elementos del menú hasta el último nodo
last = self.head
while (last.next):
last = last.next
# 6: cambiar la siguiente último nodo
last.next = new_node
# función auxiliar para imprimir el contenido de la lista enhebrada
def printList(self):
temp = self.head
while (temp):
print temp.data,
temp = temp.next
# Prueba las funciones anteriores
if __name__=='__main__':
# Empezamos con una lista vacía
llist = LinkedList()
# Insertamos el elemento 6 en la lista para que se convierta en
# 6-> Ninguno
llist.append(6)
# Inserte el elemento 7 al principio de la lista, por lo que se convierte en
# 7-> 6-> Ninguno
llist.push(7);
# Insertamos el elemento 1 al principio de la lista para que se convierta en
# 1 -> 7-> 6-> None
llist.push(1);
# Ponemos el elemento 4 al final de la lista para que se convierta en
# 1 -> 7-> 6-> 4-> None
llist.append(4)
# Insertamos el elemento 8 después del elemento 7 en la lista para que se convierta en
# 1 -> 7-> 8-> 6-> 4-> None
llist.insertAfter(llist.head.next, 8)
print 'Created linked list is:',
llist.printList()class LinkedList {
Node head; // parte superior de la lista
// nodo de lista enhebrada
class Node {
int data;
Node next;
Node(int d) {data = d; next = null; }
}
/* Inserta un nuevo nodo en la parte superior de la lista */
public void push(int new_data) {
/*
1: Reserva la ubicación del nodo en la memoria
2: Agrega información */
Node new_node = new Node(new_data);
/* 3. Hacer que el encabezado de la lista lea el nuevo nodo */
new_node.next = head;
/* 4. Mover el encabezado de la lista para apuntar al nuevo nodo */
head = new_node;
}
/* Insertar el nodo después de un nodo determinado */
public void insertAfter(Node prev_node, int new_data) {
/* 1. Verificar la presencia de un nodo determinado en la lista vinculada */
if (prev_node == null)
{
System.out.println("The given previous node cannot be null");
return;
}
/* 2: establece la ubicación del nodo en la memoria
3: agrega datos
*/
Node new_node = new Node(new_data);
/* 4. Haga que el siguiente del nuevo nodo sea el siguiente del nodo anterior */
new_node.next = prev_node.next;
/* 5. Hacer que el nuevo nodo siga al nodo anterior */
prev_node.next = new_node;
}
/* El
método agrega un nuevo nodo al final de la lista de subprocesos */
public void append(int new_data) {
/* 1: Reserva la ubicación del nodo en la memoria
2: Agrega datos
3: null
Hace lo siguiente para el nuevo nodo */
Node new_node = new Node(new_data);
/* Hacer que el nuevo nodo sea el encabezado de la lista si la lista está vacía */
if (head == null)
{
head = new Node(new_data);
return;
}
/* 4. El nuevo nodo será el último nodo de la lista
nulo, por lo que convertiremos el siguiente */
new_node.next = null;
/* 5. De lo contrario, pasaremos por los elementos de la lista hasta el último nodo */
Node last = head;
while (last.next != null)
last = last.next;
/* 6. Cambiamos lo siguiente al último nodo */
last.next = new_node;
return;
}
/* Este
método imprime el contenido de la lista de subprocesos comenzando desde el nodo dado */
public void printList() {
Node tnode = head;
while (tnode != null)
{
System.out.print(tnode.data+" ");
tnode = tnode.next;
}
}
/* Probar el código anterior */
public static void main(String[] args) {
/* comienza con una lista vacía */
LinkedList llist = new LinkedList();
// Inserte el elemento 6 en la lista, por lo que se convierte
// 6-> NUllist
llist.append(6);
// Inserte el elemento 7 al principio de la lista, de modo que se convierta
// 7-> 6-> NUllist
llist.push(7);
// Inserte el elemento 1 al principio de la lista, por lo que se convierte en
// 1-> 7-> 6-> NUllist
llist.push(1);
// Inserte el elemento 4 al final de la lista, por lo que se convierte en
// 1-> 7-> 6-> 4-> NUllist
llist.append(4);
// Inserta el elemento 8 después del elemento 7 en la lista, por lo que se convierte en
// 1-> 7-> 8-> 6-> 4-> NUllist
llist.insertAfter(llist.head.next, 8);
System.out.println("\n Lista vinculada creada: ");
llist.printList();
}
}
Eliminar nodos de listas vinculadas
El proceso de eliminación de los nodos de las listas vinculadas se realiza de acuerdo con los siguientes pasos:
- Busque el nodo anterior del nodo que se va a eliminar.
- Cambie el siguiente nodo al nodo anterior.
- Vacíe la memoria reservada por el nodo a borrar.
La siguiente figura muestra el proceso de eliminación de un nodo de la lista de subprocesos:

C reserva dinámicamente memoria para cada nodo en la lista de subprocesos usando la función malloc(). Por lo tanto, se debe llamar free() a la función para vaciar la porción de memoria reservada por el nodo a eliminar.
Los siguientes ejemplos muestran cómo eliminar un nodo de la lista de subprocesos en varios lenguajes de programación (C++, Python, Java):
#incluir <stdio.h>
#incluir <stdlib.h>
// nodo en la lista encadenada
struct Node {
int data;
struct Node *next;
}
/* La función inserta un nuevo nodo al principio de la lista
usando una referencia (puntero a un puntero) al encabezado de la lista y el entero dado */
void push(struct Node** head_ref, int new_data) {
struct Node* new_node = (struct Node*) malloc(sizeof(struct Node));
new_node->data = new_data;
new_node->next = (*head_ref);
(*head_ref) = new_node;
}
/* La función elimina la primera aparición de la clave dada en la lista encadenada
usando una referencia (puntero a un puntero) al encabezado de la lista y la clave dada */
void deleteNode(struct Node **head_ref, int key) {
// almacena los nodos de encabezado de la lista
struct Node* temp = *head_ref, *prev;
// si el nodo del encabezado de la lista es el nodo que contiene la clave que se eliminará
if (temp != NULL && temp->data == key)
{
*head_ref = temp->next; // cambiar el encabezado del menú
free(temp); // deshacerse del antiguo encabezado de
return;
}
// Encuentre la clave para eliminar mientras continúa
// el nodo anterior porque necesitamos
// cambiar el nodo anterior al siguiente nodo
// 'prev->next'
while (temp != NULL && temp->data != key) {
prev = temp;
temp = temp->next;
}
// si la clave no está en la lista de subprocesos
if (temp == NULL) return;
// desvincular el nodo de la lista de subprocesos
prev->next = temp->next;
free(temp); // Free memory
}
// Esta función imprime el contenido de la lista encadenada a partir del nodo dado
void printList(struct Node *node) {
while (node != NULL)
{
printf(" %d ", node->data);
node = node->next;
}
}
/* Probar las funciones anteriores */
int main() {
/* comenzar con un nodo vacío */
struct Node* head = NULL;
push(&head, 7);
push(&head, 1);
push(&head, 3);
push(&head, 2);
puts("Lista vinculada creada: ");
printList(head);
deleteNode(&head, 1);
puts("\nLinked List after Deletion of 1: ");
printList(head);
return 0;
}# nodo de clase
class Node:
# Función del constructor para inicializar el objeto de nodo
def __init__(self, data):
self.data = data
self.next = None
class LinkedList:
# Inicializa el encabezado de la lista
def __init__(self):
self.head = None
# La función inserta un nuevo nodo al comienzo de la lista
def push(self, new_data):
new_node = Node(new_data)
new_node.next = self.head
self.head = new_node
# La función elimina la primera aparición de la clave dada en la lista encadenada
# usando una referencia al encabezado de la lista y la clave dada
def deleteNode(self, key):
# almacena la temperatura del nodo
temp = self.head
# si el nodo principal contiene el valor de la clave dada
if (temp is not None):
if (temp.data == key):
self.head = temp.next
temp = None
return
# Encuentre la clave para eliminar mientras continúa con el
# porque la necesitamos para cambiar el nodo posterior del nodo anterior
# 'prev.next'
while(temp is not None):
if temp.data == key:
break
prev = temp
temp = temp.next
# Si la clave no está en la lista de subprocesos
if(temp == None):
return
# Desvincular el nodo de la lista de subprocesos
prev.next = temp.next
temp = None
# Utility function to print the linked LinkedList
def printList(self):
temp = self.head
while(temp):
print " %d" %(temp.data),
temp = temp.next
# Probar las funciones anteriores
llist = LinkedList()
llist.push(7)
llist.push(1)
llist.push(3)
llist.push(2)
print "Lista vinculada creada: "
llist.printList()
llist.deleteNode(1)
print "\nLinked List after Deletion of 1:"
llist.printList()class LinkedList {
Node head; // al principio de la lista
// nodo de lista encadenada
class Node {
int data;
Node next;
Node(int d)
{
data = d;
next = null;
}
}
// La función elimina la primera aparición de la clave dada en la lista encadenada
void deleteNode(int key) {
// almacena el nodo principal
Node temp = head, prev = null;
// si el propio nodo principal contiene la clave que se eliminará
if (temp != null && temp.data == key) {
head = temp.next; // cambia el encabezado de la lista
return;
}
// Encuentre la clave para eliminar, continuando
// el nodo anterior porque necesitamos cambiar el nodo posterior
// temp.next
while (temp != null && temp.data != key) {
prev = temp;
temp = temp.next;
}
// si la clave no está en la lista de subprocesos
if (temp == null) return;
// Desvincular el nodo de la lista de subprocesos
prev.next = temp.next;
}
// El método inserta un nuevo nodo al comienzo de la lista de subprocesos
public void push(int new_data) {
Node new_node = new Node(new_data);
new_node.next = head;
head = new_node;
}
/* Esta función imprime el contenido de la lista
encadenada a partir del nodo dado */
public void printList() {
Node tnode = head;
while (tnode != null) {
System.out.print(tnode.data+" ");
tnode = tnode.next;
}
}
// probar funciones anteriores
public static void main(String[] args)
{
LinkedList llist = new LinkedList();
llist.push(7);
llist.push(1);
llist.push(3);
llist.push(2);
System.out.println("\n Lista vinculada creada:");
llist.printList();
llist.deleteNode(1); // elimina el nodo en la ubicación 1
System.out.println("\n Lista enlazada después de la eliminación en la posición 4:");
llist.printList();
}
}El código anterior da el siguiente resultado:
Lista enlazada creada 2 3 1 7 Lista encadenada después de eliminar el elemento 1 2 3 7
Eliminación de un nodo de una lista encadenada en función de la ubicación
Si el nodo a eliminar es el primer nodo, se puede eliminar directamente, de lo contrario debe haber un puntero al nodo anterior del nodo a eliminar. Entonces, si la ubicación es cualquier cosa menos cero, debe repetir iterativamente (ubicación – 1) veces para obtener el puntero al nodo anterior.
Los siguientes ejemplos muestran cómo eliminar un nodo de una lista encadenada según la ubicación:
#include <stdio.h>
#include <stdlib.h>
// nodo en la lista encadenada
struct Node {
int data;
struct Node *next;
}
/* La siguiente función inserta un nuevo nodo al frente de la lista encadenada
usando un puntero al encabezado de la lista y el entero dado */
void push(struct Node** head_ref, int new_data) {
struct Node* new_node = (struct Node*) malloc(sizeof(struct Node));
new_node->data = new_data;
new_node->next = (*head_ref);
(*head_ref) = new_node;
}
/* La siguiente función elimina el nodo en la ubicación dada
usando una referencia (puntero a un puntero) al encabezado de la lista y la ubicación dada */
void deleteNode(struct Node **head_ref, int position) {
// si el la lista
if (*head_ref == NULL)
return;
// almacenar el nodo de encabezado de lista
struct Node* temp = *head_ref;
// si el nodo a eliminar es
if (position == 0) {
*head_ref = temp->next; // cambiar el encabezado del menú
free (temp);
return;
}
// Encuentre el nodo anterior del nodo a eliminar
for (int i=0; temp!=NULL && i<position-1; i++)
temp = temp->next;
// si la ubicación es mayor que el número de nodos
if (temp == NULL || temp->next == NULL)
return;
// temp->next
// es el nodo a eliminar
// almacena el puntero al siguiente nodo a eliminar
struct Node *next = temp->next->next;
// desvincular el nodo de la lista de subprocesos
free(temp->next); // Vaciar la memoria ocupada por el nodo
temp->next = next; // desvincular el nodo de la lista de hilos
}
// Esta función imprime el contenido de la lista encadenada a partir del nodo dado
void printList(struct Node *node) {
while (node != NULL)
{
printf(" %d ", node->data);
node = node->next;
}
}
// prueba las funciones anteriores
int main() {
// comienza con una lista de subprocesos vacía
struct Node* head = NULL;
push(&head, 7);
push(&head, 1);
push(&head, 3);
push(&head, 2);
push(&head, 8);
puts("Lista vinculada creada: ");
printList(head);
deleteNode(&head, 4);
puts("\n Lista enlazada después de la eliminación en la posición 4: ");
printList(head);
return 0;
}# nodo de clase
class Node:
# Función del constructor para inicializar el objeto de nodo
def __init__(self, data):
self.data = data
self.next = None
class LinkedList:
# Inicializa el encabezado de la lista
def __init__(self):
self.head = None
# La función inserta un nuevo nodo al frente de la lista
def push(self, new_data):
new_node = Node(new_data)
new_node.next = self.head
self.head = new_node
# La siguiente función elimina el nodo en la ubicación dada
# usando una bandera del encabezado de la lista y la ubicación dada */
def deleteNode(self, position):
# si la lista encadenada está vacía
if self.head == None:
return
# almacena la temperatura del nodo
temp = self.head
# si se va a eliminar el encabezado de la lista
if position == 0:
self.head = temp.next
temp = None
return
# Encuentre el nodo anterior del nodo para eliminar
for i in range(position -1 ):
temp = temp.next
if temp is None:
break
# si la ubicación dada es mayor que el número de elementos en la lista
if temp is None:
return
if temp.next is None:
return
#temp.next
# es el nodo que se eliminará
# El puntero se almacena en el nodo que sigue al nodo que se eliminará
next = temp.next.next
# Desvincular el nodo de la lista de subprocesos
temp.next = None
temp.next = next
# Función de utilidad para imprimir la LinkedList vinculada
def printList(self):
temp = self.head
while(temp):
print " %d " %(temp.data),
temp = temp.next
# Probar las funciones anteriores
llist = LinkedList()
llist.push(7)
llist.push(1)
llist.push(3)
llist.push(2)
llist.push(8)
print "Lista vinculada creada: "
llist.printList()
llist.deleteNode(4)
print "\n Lista enlazada después de la eliminación en la posición 4: "
llist.printList()class LinkedList {
Node head; // al principio de la lista
/* Nodo en la lista de hilos*/
class Node {
int data;
Node next;
Node(int d)
{
data = d;
next = null;
}
}
/* Inserta un nuevo nodo al frente de la lista */
public void push(int new_data) {
/* 1: Reserve una ubicación de nodo en la memoria
2: agregue datos */
Node new_node = new Node(new_data);
/* 3: Hacer que el siguiente nodo nuevo sea el encabezado de la lista de subprocesos */
new_node.next = head;
/* 4: Mover la cabeza para señalar el nuevo nodo */
head = new_node;
}
/* La función elimina el nodo en la ubicación dada
usando un puntero al encabezado y la ubicación dada */
void deleteNode(int position) {
// si la lista encadenada está vacía
if (head == null)
return;
// almacena el nodo de cabecera de la lista
Node temp = head;
//
if (position == 0) {
head = temp.next; // cambia el encabezado de la lista
return ;
}
// Encuentre el nodo que precede al nodo que se eliminará
for (int i=0; temp!=null && i<position-1; i++)
temp = temp.next;
// si la ubicación solicitada es mayor que el número de nodos en la lista de subprocesos
if (temp == null || temp.next == null)
return;
// temp->next
// es el nodo que se eliminará
// almacena el puntero al nodo junto al nodo que se eliminará
Node next = temp.next.next;
temp.next = next; // desvincular el nodo de la lista de hilos
}
// Esta función imprime el contenido de la lista encadenada a partir del nodo dado
public void printList() {
Node tnode = head;
while (tnode != null)
{
System.out.print(tnode.data+" ");
tnode = tnode.next;
}
}
// prueba los discípulos anteriores
public static void main(String[] args) {
/* menú de inicio vacío */
LinkedList llist = new LinkedList();
llist.push(7);
llist.push(1);
llist.push(3);
llist.push(2);
llist.push(8);
llist.printList();
llist.deleteNode(4); // elimina el nodo en la posición 4
System.out.println( "\nLista enlazada después de la eliminación en la posición 4: " );
llist.printList();
}
}El código anterior da el siguiente resultado:
Lista enlazada establecida: 8 2 3 1 7 La lista encadenada después de eliminar el elemento en la posición 4: 8 2 3 1
Buscar un elemento en la lista encadenada
Puede buscar un elemento en la lista encadenada de dos maneras:
- método iterativo.
- método recursivo.
método iterativo
El método iterativo incluye los siguientes pasos:
- inicialización del puntero de nodo,
current = head - Realice lo siguiente siempre que el valor
currentno seaNull- Si es
current->keyigual a la clave a buscar, devolvemos el valortrue. - atribución
current->nextacurrent - valor de retorno
false.
- Si es
Los siguientes ejemplos muestran cómo implementar un método iterativo para encontrar un nodo específico en la lista de subprocesos y en varios lenguajes de programación (C++, Python, Java) :
#include <bits/stdc++.h>
using namespace std;
/* Nodo en la lista de hilos */
class Node {
public:
int key;
Node* next;
}
/* Esta función agrega un nuevo nodo al frente de la lista encadenada
usando una bandera (un puntero a un puntero) al encabezado de la lista y el entero dado */
void push(Node** head_ref, int new_key){
/* Reservar la ubicación del nodo en la memoria */
Node* new_node = new Node();
/* añadir clave */
new_node->key = new_key;
/*
Separar la lista anterior del nuevo nodo */
new_node->next = (*head_ref);
/* Mueve el encabezado de la lista para que apunte al nuevo nodo */
(*head_ref) = new_node;
}
/* Verifica que el valor dado esté en la lista de subprocesos */
bool search(Node* head, int x) {
Node* current = head; // inicializa el nodo actual
while (current != NULL) {
if (current->key == x)
return true;
current = current->next;
}
return false;
}
/* prueba las funciones anteriores*/
int main() {
/* comienza con una lista de subprocesos vacía */
Node* head = NULL;
int x = 21;
/* push() Usa la función
para crear la siguiente lista
encadenada
: 14->21->11->30->10 */
push(&head, 10);
push(&head, 30);
push(&head, 11);
push(&head, 21);
push(&head, 14);
search(head, 21)? cout<<"Yes" : cout<<"No";
return 0;
}# nodo de clase
class Node:
# Inicializar el objeto de nodo
def __init__(self, data):
self.data = data # Asignar datos
self.next = None # Inicializar siguiente como nulo
#
class LinkedList:
def __init__(self):
self.head = None # Inicializar el encabezado de la lista
# Este método inserta un nuevo nodo al comienzo de la lista encadenada
def push(self, new_data):
# crear un nuevo nodo
new_node = Node(new_data)
# Hacer el encabezado de la lista después de
new_node.next = self.head
# Mueva el encabezado para que apunte al nuevo nodo
self.head = new_node
# Esta función verifica si el valor dado existe en la lista de subprocesos
def search(self, x):
# Inicializa el encabezado
current = self.head
# Repetir hasta que el valor de
# Ninguno para el nodo actual sea
while current != None:
if current.data == x:
return True # datos encontrados
current = current.next
return False # No se encontraron los datos solicitados
# Probar las funciones anteriores
if __name__ == '__main__':
# comenzar con una lista vacía
llist = LinkedList()
''' Usamos el método
push() para crear la siguiente lista
encadenada : 14->21->11->30->10 '''
llist.push(10);
llist.push(30);
llist.push(11);
llist.push(21);
llist.push(14);
if llist.search(21):
print("Si")
else:
print("No")// clase noo
class Node {
int data;
Node next;
Node(int d) {
data = d;
next = null;
}
}
class LinkedList {
Node head; // al principio de la lista
// inserta un nodo al principio de la lista
public void push(int new_data) {
// reserva una ubicación para el nuevo nodo en la memoria y agrega datos
Node new_node = new Node(new_data);
// Hacer que el encabezado de la lista siga al siguiente nodo
new_node.next = head;
// mueve el encabezado de la lista para que apunte al nuevo nodo
head = new_node;
}
// Comprueba si el valor dado está en la lista de subprocesos de
public boolean search(Node head, int x) {
Node current = head; // inicializa el encabezado actual
while (current != null) {
if (current.data == x)
return true; // Se encontraron los datos solicitados
current = current.next;
}
return false;
}
// Probar las funciones anteriores
public static void main(String args[]) {
// comenzar con una lista
LinkedList llist = new LinkedList();
/* Usa el método push()
para crear la siguiente lista
encadenada 14->21->11->30->10 */
llist.push(10);
llist.push(30);
llist.push(11);
llist.push(21);
llist.push(14);
if (llist.search(llist.head, 21))
System.out.println("Si");
else
System.out.println("No");
}
}El código anterior da el siguiente resultado:
Sí
Método recursivo
La función trabaja search(head, x) de manera recursiva de acuerdo a los siguientes pasos:
- Si el vértice es igual,
Nullla función devuelve el valorfalse. - Si la clave para el encabezado es la
xmisma, la función devuelve el valortrue. - De lo contrario, la función devuelve el resultado de la llamada a la función
search(head->next, x).
Los siguientes ejemplos muestran cómo realizar una búsqueda recursiva en varios lenguajes de programación (C, Python, Java) :
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
/* Nodo en la lista de hilos */
struct Node {
int key;
struct Node* next;
}
/* La función inserta un nuevo nodo al frente de la lista encadenada
usando un puntero al encabezado de la lista y el entero dado
*/
void push(struct Node** head_ref, int new_key) {
/* Reservar la ubicación del nodo en la memoria */
struct Node* new_node =
(struct Node*) malloc(sizeof(struct Node));
/* añadir clave */
new_node->key = new_key;
/* Desconexión entre la lista de subprocesos y el nuevo nodo */
new_node->next = (*head_ref);
/* Mueve el encabezado de la lista para que apunte al nuevo nodo */
(*head_ref) = new_node;
}
/* Comprobar si el valor dado está en la lista de subprocesos */
bool search(struct Node* head, int x) {
// Prerequisito
if (head == NULL)
return false;
// devuelve verdadero si la clave requerida está en la lista
if (head->key == x)
return true;
// La función se ejecuta recursivamente para encontrar la clave requerida
return search(head->next, x);
}
/* Probar las funciones anteriores*/
int main(){
/* comenzar con una lista vacía */
struct Node* head = NULL;
int x = 21;
/* La función push() se usa
para crear la siguiente lista
encadenada 14->21->11->30->10 */
push(&head, 10);
push(&head, 30);
push(&head, 11);
push(&head, 21);
push(&head, 14);
search(head, 21)? printf("Si") : printf("No");
return 0;
}# nodo de clase
class node :
# Inicializar el objeto de nodo
def __init__(self, data):
self.data = data # Asignar datos
self.next = None # Inicializar siguiente como nulo
# Ordenar la lista enlazada
class LinkedList:
def __init__(self):
self.head = None # Inicializar el encabezado de la lista
# Este método inserta un nuevo nodo al principio de la lista de subprocesos
def push(self, new_data):
# crear un nuevo nodo
new_node = Node(new_data)
# Hacer el encabezado de la lista después de
new_node.next = self.head
# Mueva el encabezado para que apunte al nuevo nodo
self.head = new_node
# Esta función comprueba si el valor dado existe en la lista de subprocesos
def search(self, li, key):
# requisito previo
if(not li):
return False
# devuelve verdadero
# si la clave está en el nodo actual
if(li.data == key):
return True
# Ejecuta la función de forma recursiva en el resto de los nodos de la lista de subprocesos
return self.search(li.next, key)
# Probar las funciones anteriores
if __name__ == '__main__':
# comenzar con una lista vacía
llist = LinkedList()
''' Usamos el método push()
para crear la siguiente lista
encadenada: 14->21->11->30->10 '''
llist.push(10);
llist.push(30);
llist.push(11);
llist.push(21);
llist.push(14);
if llist.search(21):
print("Si")
else:
print("No")// Nodo de clase
class Node {
int data;
Node next;
Node(int d)
{
data = d;
next = null;
}
}
// Ordenar la lista enlazada
class LinkedList {
Node head; // al principio de la lista
// inserta un nodo al principio de la lista
public void push(int new_data) {
// reserva una ubicación para el nuevo nodo en la memoria y agrega datos
Node new_node = new Node(new_data);
// Hacer que el encabezado de la lista siga al siguiente nodo
new_node.next = head;
// mueve el encabezado de la lista para que apunte al nuevo nodo
head = new_node;
}
// Verifique que el valor dado esté en la lista de subprocesos
public boolean search(Node head, int x) {
// Requisito previo
if (head == null)
return false;
// devuelve verdadero
// si la clave está en el nodo actual
if (head.data == x)
return true;
// Ejecuta una función recursiva en el resto de los nodos en la lista de subprocesos
return search(head.next, x);
}
// Probar las funciones anteriores
public static void main(String args[]) {
// comenzar con una lista enlazada vacía
LinkedList llist = new LinkedList();
/* Usa el método push()
para crear la siguiente lista
encadenada 14->21->11->30->10 */
llist.push(10);
llist.push(30);
llist.push(11);
llist.push(21);
llist.push(14);
if (llist.search(llist.head, 21))
System.out.println("Si");
else
System.out.println("No");
}
}Fuente
- La página en GeeksforGeeks de estructura de datos de lista enlazada.
- Página de la documentación de estructuras de datos en el sitio GeeksforGeeks lista enlazada | Conjunto 1 (Introducción).
- Página documentación de estructuras de datos en el sitio GeeksforGeeks de lista enlazada | Conjunto 2 (Inserción de un nodo).
- Página documentación de estructuras de datos en el sitio GeeksforGeeks de lista enlazada | Conjunto 3 (Eliminación de un nodo).



