1#include <iostream>
2using namespace std;
3
4class Nodo { // Un nœud contient la donnée et un pointeur vers le suivant
5private: // Attributs privés : seules les méthodes y touchent
6 int dato;
7 Nodo* siguiente;
8public:
9 Nodo(int d) : dato(d), siguiente(nullptr) {}
10 int getDato() const { return dato; }
11 Nodo* getSiguiente() const { return siguiente; }
12 void setDato(int d) { dato = d; }
13 void setSiguiente(Nodo* s) { siguiente = s; }
14};
15
16class Lista {
17 Nodo* cabeza_; // Premier nœud de la liste
18 int n_; // Nombre de nœuds
19
20public:
21 Lista() : cabeza_(nullptr), n_(0) {}
22
23 // Constructor de copia (no se anima)
24 Lista(const Lista& otra) : cabeza_(nullptr), n_(0) {
25 for (Nodo* p = otra.cabeza_; p != nullptr; p = p->getSiguiente())
26 insertarFinal(p->getDato());
27 }
28
29 // Destructor (no se anima)
30 ~Lista() {
31 while (cabeza_ != nullptr) {
32 Nodo* temp = cabeza_;
33 cabeza_ = cabeza_->getSiguiente();
34 delete temp;
35 }
36 }
37
38 void insertarElemento(int valor) { // Insertion en tête : O(1)
39 Nodo* nuevo = new Nodo(valor); // Créer le nœud
40 nuevo->setSiguiente(cabeza_); // Le nouveau nœud pointe vers l'ancienne tête
41 cabeza_ = nuevo; // cabeza_ pointe maintenant vers le nouveau nœud
42 n_++;
43 }
44
45 void insertarFinal(int valor) { // Insertion en queue : O(n)
46 Nodo* nuevo = new Nodo(valor); // Créer le nœud
47 if (cabeza_ == nullptr) { // Liste vide ?
48 cabeza_ = nuevo;
49 } else {
50 Nodo* actual = cabeza_;
51 while (actual->getSiguiente() != nullptr) { // Parcourir jusqu'à la queue
52 actual = actual->getSiguiente();
53 }
54 actual->setSiguiente(nuevo); // Relier le nouveau nœud après la queue
55 }
56 n_++;
57 }
58
59 // Devuelve la posición (0-based) o -1 si no existe
60 int buscar(int valor) const {
61 Nodo* actual = cabeza_;
62 int indice = 0;
63 while (actual != nullptr) {
64 if (actual->getDato() == valor) return indice; // Comparer la donnée
65 actual = actual->getSiguiente();
66 indice++;
67 }
68 return -1; // Introuvable
69 }
70
71 void eliminarNodo(int indice) {
72 if (indice < 0 || indice >= n_) return; // Valider l'indice
73 Nodo* anterior = nullptr;
74 Nodo* actual = cabeza_;
75 for (int i = 0; i < indice; i++) {
76 anterior = actual;
77 actual = actual->getSiguiente();
78 }
79 if (anterior == nullptr)
80 cabeza_ = actual->getSiguiente(); // C'était la tête
81 else
82 anterior->setSiguiente(actual->getSiguiente()); // Contourner le nœud
83 delete actual; // Libérer la mémoire
84 n_--;
85 }
86
87 void invertirLista() {
88 Nodo* anterior = nullptr;
89 Nodo* actual = cabeza_;
90 while (actual != nullptr) {
91 Nodo* siguiente = actual->getSiguiente(); // Sauvegarder le nœud suivant
92 actual->setSiguiente(anterior); // Inverser le lien
93 anterior = actual;
94 actual = siguiente;
95 }
96 cabeza_ = anterior; // Le dernier nœud devient la tête
97 }
98
99 void imprimirLista() const {
100 for (Nodo* p = cabeza_; p != nullptr; p = p->getSiguiente()) { // Parcourir la liste
101 cout << p->getDato();
102 if (p->getSiguiente() != nullptr) cout << " -> "; // Séparateur entre les valeurs
103 }
104 cout << endl;
105 }
106};
107
108int main() {
109 Lista lista;
110 lista.insertarElemento(3);
111 lista.insertarElemento(6);
112 lista.insertarElemento(9);
113 lista.imprimirLista(); // 9 -> 6 -> 3
114 lista.insertarFinal(1);
115 lista.eliminarNodo(lista.buscar(6));
116 lista.imprimirLista(); // 9 -> 3 -> 1
117 lista.invertirLista();
118 lista.imprimirLista(); // 1 -> 3 -> 9
119 return 0;
120}