INICIO DE CÓDIGO
#include <iostream>
using namespace std;
// ------------------------- LISTA ENLAZADA SIMPLE -------------------------
struct Nodo {
int dato;
Nodo* siguiente;
Nodo(int dato) : dato(dato), siguiente(nullptr) {}
};
class ListaEnlazada {
private:
Nodo* cabeza;
public:
ListaEnlazada() : cabeza(nullptr) {}
~ListaEnlazada() {
while (cabeza != nullptr) {
Nodo* temp = cabeza;
cabeza = cabeza->siguiente;
delete temp;
}
}
void agregarAlFinal(int dato) {
Nodo* nuevoNodo = new Nodo(dato);
if (cabeza == nullptr) {
cabeza = nuevoNodo;
} else {
Nodo* temp = cabeza;
while (temp->siguiente != nullptr) {
temp = temp->siguiente;
}
temp->siguiente = nuevoNodo;
}
}
void eliminarNodo(int dato) {
if (cabeza == nullptr) return;
if (cabeza->dato == dato) {
Nodo* temp = cabeza;
cabeza = cabeza->siguiente;
delete temp;
return;
}
Nodo* actual = cabeza;
while (actual->siguiente != nullptr && actual->siguiente->dato != dato) {
actual = actual->siguiente;
}
if (actual->siguiente != nullptr) {
Nodo* temp = actual->siguiente;
actual->siguiente = temp->siguiente;
delete temp;
}
}
void mostrar() {
Nodo* temp = cabeza;
while (temp != nullptr) {
cout << temp->dato << " -> ";
temp = temp->siguiente;
}
cout << "NULL" << endl;
}
};
// --------------------- LISTA DOBLEMENTE ENLAZADA ---------------------
struct NodoDoble {
int dato;
NodoDoble* anterior;
NodoDoble* siguiente;
NodoDoble(int dato) : dato(dato), anterior(nullptr), siguiente(nullptr) {}
};
class ListaDoble {
private:
NodoDoble* cabeza;
NodoDoble* cola;
public:
ListaDoble() : cabeza(nullptr), cola(nullptr) {}
~ListaDoble() {
NodoDoble* actual = cabeza;
while (actual != nullptr) {
NodoDoble* temp = actual;
actual = actual->siguiente;
delete temp;
}
}
void agregarAlFinal(int dato) {
NodoDoble* nuevoNodo = new NodoDoble(dato);
if (cabeza == nullptr) {
cabeza = cola = nuevoNodo;
} else {
nuevoNodo->anterior = cola;
cola->siguiente = nuevoNodo;
cola = nuevoNodo;
}
}
void eliminarNodo(int dato) {
if (cabeza == nullptr) return;
NodoDoble* actual = cabeza;
while (actual != nullptr && actual->dato != dato) {
actual = actual->siguiente;
}
if (actual == nullptr) return;
if (actual->anterior != nullptr) {
actual->anterior->siguiente = actual->siguiente;
} else {
cabeza = actual->siguiente;
}
if (actual->siguiente != nullptr) {
actual->siguiente->anterior = actual->anterior;
} else {
cola = actual->anterior;
}
delete actual;
}
void mostrarAdelante() {
NodoDoble* temp = cabeza;
while (temp != nullptr) {
cout << temp->dato << " <-> ";
temp = temp->siguiente;
}
cout << "NULL" << endl;
}
void mostrarAtras() {
NodoDoble* temp = cola;
while (temp != nullptr) {
cout << temp->dato << " <-> ";
temp = temp->anterior;
}
cout << "NULL" << endl;
}
};
// ------------------------- PROGRAMA PRINCIPAL -------------------------
int main() {
cout << "======== Lista Enlazada Simple ========\n";
ListaEnlazada listaSimple;
listaSimple.agregarAlFinal(10);
listaSimple.agregarAlFinal(20);
listaSimple.agregarAlFinal(30);
cout << "Lista original: ";
listaSimple.mostrar(); // 10 -> 20 -> 30 -> NULL
listaSimple.eliminarNodo(20);
cout << "Despues de eliminar 20: ";
listaSimple.mostrar(); // 10 -> 30 -> NULL
cout << "\n======== Lista Doblemente Enlazada ========\n";
ListaDoble listaDoble;
listaDoble.agregarAlFinal(100);
listaDoble.agregarAlFinal(200);
listaDoble.agregarAlFinal(300);
cout << "Recorrido hacia adelante: ";
listaDoble.mostrarAdelante(); // 100 <-> 200 <-> 300 <-> NULL
cout << "Recorrido hacia atras: ";
listaDoble.mostrarAtras(); // 300 <-> 200 <-> 100 <-> NULL
listaDoble.eliminarNodo(200);
cout << "\nDespues de eliminar 200:\n";
cout << "Adelante: ";
listaDoble.mostrarAdelante(); // 100 <-> 300 <-> NULL
cout << "Atras: ";
listaDoble.mostrarAtras(); // 300 <-> 100 <-> NULL
return 0;
}
FIN DE CÓDIGO
EXPLICACIÓN DEL CÓDIGO
Este código en C++ implementa dos estructuras de datos fundamentales:
Lista Enlazada Simple y Lista Doblemente Enlazada. Ambas estructuras
permiten almacenar y manipular una secuencia de elementos de manera
dinámica.
1. Lista Enlazada Simple
Estructura del Nodo
cpp
CopiarEditar
struct Nodo {
int dato;
Nodo* siguiente;
Nodo(int dato) : dato(dato), siguiente(nullptr) {}
};
Define un nodo con:
o dato: un número entero almacenado.
o siguiente: un puntero al próximo nodo en la lista.
Se usa un constructor para inicializar el nodo con un dato y establecer
siguiente como nullptr.
Clase ListaEnlazada
cpp
CopiarEditar
class ListaEnlazada {
private:
Nodo* cabeza;
La lista tiene un puntero cabeza que apunta al primer nodo de la lista.
Constructor y Destructor
cpp
CopiarEditar
ListaEnlazada() : cabeza(nullptr) {}
Inicializa la lista vacía (cabeza es nullptr).
cpp
CopiarEditar
~ListaEnlazada() {
while (cabeza != nullptr) {
Nodo* temp = cabeza;
cabeza = cabeza->siguiente;
delete temp;
}
}
Libera la memoria de los nodos cuando el objeto ListaEnlazada es
destruido.
Método agregarAlFinal(int dato)
cpp
CopiarEditar
void agregarAlFinal(int dato) {
Nodo* nuevoNodo = new Nodo(dato);
if (cabeza == nullptr) {
cabeza = nuevoNodo;
} else {
Nodo* temp = cabeza;
while (temp->siguiente != nullptr) {
temp = temp->siguiente;
}
temp->siguiente = nuevoNodo;
}
}
Crea un nuevo nodo con dato.
Si la lista está vacía, el nodo se convierte en la cabeza.
Si la lista tiene elementos, recorre hasta el último nodo y agrega el
nuevo nodo al final.
Método eliminarNodo(int dato)
cpp
CopiarEditar
void eliminarNodo(int dato) {
if (cabeza == nullptr) return;
if (cabeza->dato == dato) {
Nodo* temp = cabeza;
cabeza = cabeza->siguiente;
delete temp;
return;
}
Nodo* actual = cabeza;
while (actual->siguiente != nullptr && actual->siguiente->dato != dato) {
actual = actual->siguiente;
}
if (actual->siguiente != nullptr) {
Nodo* temp = actual->siguiente;
actual->siguiente = temp->siguiente;
delete temp;
}
}
Si la lista está vacía, no hace nada.
Si el nodo a eliminar es la cabeza, se actualiza la cabeza al siguiente
nodo.
Recorre la lista hasta encontrar el nodo con dato y lo elimina ajustando
los punteros.
Método mostrar()
cpp
CopiarEditar
void mostrar() {
Nodo* temp = cabeza;
while (temp != nullptr) {
cout << temp->dato << " -> ";
temp = temp->siguiente;
}
cout << "NULL" << endl;
}
Recorre la lista e imprime los valores.
2. Lista Doblemente Enlazada
Estructura del Nodo
cpp
CopiarEditar
struct NodoDoble {
int dato;
NodoDoble* anterior;
NodoDoble* siguiente;
NodoDoble(int dato) : dato(dato), anterior(nullptr), siguiente(nullptr) {}
};
Similar a la lista simple, pero con dos punteros:
o anterior: apunta al nodo previo.
o siguiente: apunta al nodo siguiente.
Clase ListaDoble
cpp
CopiarEditar
class ListaDoble {
private:
NodoDoble* cabeza;
NodoDoble* cola;
Tiene dos punteros:
o cabeza: apunta al primer nodo.
o cola: apunta al último nodo.
Constructor y Destructor
cpp
CopiarEditar
ListaDoble() : cabeza(nullptr), cola(nullptr) {}
Inicializa la lista vacía.
cpp
CopiarEditar
~ListaDoble() {
NodoDoble* actual = cabeza;
while (actual != nullptr) {
NodoDoble* temp = actual;
actual = actual->siguiente;
delete temp;
}
}
Libera la memoria de los nodos.
Método agregarAlFinal(int dato)
cpp
CopiarEditar
void agregarAlFinal(int dato) {
NodoDoble* nuevoNodo = new NodoDoble(dato);
if (cabeza == nullptr) {
cabeza = cola = nuevoNodo;
} else {
nuevoNodo->anterior = cola;
cola->siguiente = nuevoNodo;
cola = nuevoNodo;
}
}
Si la lista está vacía, cabeza y cola apuntan al nuevo nodo.
Si la lista tiene elementos, el nuevo nodo se enlaza con la cola y se
actualiza la cola.
Método eliminarNodo(int dato)
cpp
CopiarEditar
void eliminarNodo(int dato) {
if (cabeza == nullptr) return;
NodoDoble* actual = cabeza;
while (actual != nullptr && actual->dato != dato) {
actual = actual->siguiente;
}
if (actual == nullptr) return;
if (actual->anterior != nullptr) {
actual->anterior->siguiente = actual->siguiente;
} else {
cabeza = actual->siguiente;
}
if (actual->siguiente != nullptr) {
actual->siguiente->anterior = actual->anterior;
} else {
cola = actual->anterior;
}
delete actual;
}
Busca el nodo con el dato y ajusta los punteros siguiente y anterior para
eliminarlo.
Método mostrarAdelante()
cpp
CopiarEditar
void mostrarAdelante() {
NodoDoble* temp = cabeza;
while (temp != nullptr) {
cout << temp->dato << " <-> ";
temp = temp->siguiente;
}
cout << "NULL" << endl;
}
Imprime los valores desde cabeza hasta cola.
Método mostrarAtras()
cpp
CopiarEditar
void mostrarAtras() {
NodoDoble* temp = cola;
while (temp != nullptr) {
cout << temp->dato << " <-> ";
temp = temp->anterior;
}
cout << "NULL" << endl;
}
Imprime los valores desde cola hasta cabeza.
3. Programa Principal main()
cpp
CopiarEditar
int main() {
cout << "======== Lista Enlazada Simple ========\n";
ListaEnlazada listaSimple;
listaSimple.agregarAlFinal(10);
listaSimple.agregarAlFinal(20);
listaSimple.agregarAlFinal(30);
cout << "Lista original: ";
listaSimple.mostrar();
listaSimple.eliminarNodo(20);
cout << "Despues de eliminar 20: ";
listaSimple.mostrar();
Crea una ListaEnlazada, agrega elementos y los muestra.
Elimina el nodo con dato = 20 y vuelve a mostrar la lista.
cpp
CopiarEditar
cout << "\n======== Lista Doblemente Enlazada ========\n";
ListaDoble listaDoble;
listaDoble.agregarAlFinal(100);
listaDoble.agregarAlFinal(200);
listaDoble.agregarAlFinal(300);
cout << "Recorrido hacia adelante: ";
listaDoble.mostrarAdelante();
cout << "Recorrido hacia atras: ";
listaDoble.mostrarAtras();
listaDoble.eliminarNodo(200);
cout << "\nDespues de eliminar 200:\n";
cout << "Adelante: ";
listaDoble.mostrarAdelante();
cout << "Atras: ";
listaDoble.mostrarAtras();
return 0;
}
Crea una ListaDoble, agrega elementos y los muestra en ambos
sentidos.
Elimina el nodo con dato = 200 y vuelve a mostrar la lista.