BFS :
#include <iostream>
#include <list>
#include <vector>
#include <queue>
// Classe représentant un graphe utilisant une liste d'adjacence
class Graph {
int V; // Nombre de sommets
std::vector<std::list<int>> adj; // Pointeur vers un tableau contenant des listes d'adjacence
public:
// Constructeur
Graph(int V);
// Fonction pour ajouter une arête au graphe
void addEdge(int v, int w);
// Fonction pour effectuer BFS à partir d'un sommet source donné
void BFS(int s);
};
Graph::Graph(int V) {
this->V = V;
[Link](V);
void Graph::addEdge(int v, int w) {
adj[v].push_back(w); // Ajouter w à la liste d'adjacence de v
void Graph::BFS(int s) {
// Marquer tous les sommets comme non visités
std::vector<bool> visited(V, false);
// Créer une file pour BFS
std::queue<int> queue;
// Marquer le sommet source comme visité et l'enfiler
visited[s] = true;
[Link](s);
while (![Link]()) {
// Défilement d'un sommet de la file et l'imprimer
s = [Link]();
std::cout << s << " ";
[Link]();
// Obtenir tous les sommets adjacents au sommet défilé s
// Si un sommet adjacent n'a pas été visité, le marquer comme visité et l'enfiler
for (auto adjacent : adj[s]) {
if (!visited[adjacent]) {
visited[adjacent] = true;
[Link](adjacent);
int main() {
// Créer un graphe avec 4 sommets
Graph g(4);
[Link](0, 1);
[Link](0, 2);
[Link](1, 2);
[Link](2, 0);
[Link](2, 3);
[Link](3, 3);
std::cout << "Parcours BFS à partir du sommet 2 :\n";
[Link](2);
return 0;
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::..
DFS :
#include <iostream>
#include <list>
#include <vector>
#include <stack>
// Classe représentant un graphe utilisant une liste d'adjacence
class Graph {
int V; // Nombre de sommets
std::vector<std::list<int>> adj; // Pointeur vers un tableau contenant des listes d'adjacence
public:
// Constructeur
Graph(int V);
// Fonction pour ajouter une arête au graphe
void addEdge(int v, int w);
// Fonction pour effectuer DFS de manière itérative à partir d'un sommet source donné
void DFS(int s);
};
Graph::Graph(int V) {
this->V = V;
[Link](V);
}
void Graph::addEdge(int v, int w) {
adj[v].push_back(w); // Ajouter w à la liste d'adjacence de v
void Graph::DFS(int s) {
// Marquer tous les sommets comme non visités
std::vector<bool> visited(V, false);
// Créer une pile pour DFS
std::stack<int> stack;
// Pousser le sommet source sur la pile
[Link](s);
while (![Link]()) {
// Dépiler un sommet de la pile
s = [Link]();
[Link]();
// Si le sommet n'a pas été visité
if (!visited[s]) {
std::cout << s << " ";
visited[s] = true;
// Obtenir tous les sommets adjacents au sommet défilé s
// Si un sommet adjacent n'a pas été visité, le pousser sur la pile
for (auto adjacent : adj[s]) {
if (!visited[adjacent]) {
[Link](adjacent);
}
}
int main() {
// Créer un graphe avec 4 sommets
Graph g(4);
[Link](0, 1);
[Link](0, 2);
[Link](1, 2);
[Link](2, 0);
[Link](2, 3);
[Link](3, 3);
std::cout << "Parcours DFS à partir du sommet 2 :\n";
[Link](2);
return 0;
:::::::::::::::::::::::::::::::::AVL
#include <iostream>
#include <iostream>
#include <algorithm>
class Node {
public:
int key;
Node* left;
Node* right;
int height;
Node(int key) : key(key), left(nullptr), right(nullptr), height(1) {}
};
class AVLTree {
private:
Node* root;
int height(Node* n) {
return n ? n->height : 0;
int getBalance(Node* n) {
return n ? height(n->left) - height(n->right) : 0;
Node* rightRotate(Node* y) {
Node* x = y->left;
Node* T2 = x->right;
// Effectuer la rotation
x->right = y;
y->left = T2;
// Mettre à jour les hauteurs
y->height = std::max(height(y->left), height(y->right)) + 1;
x->height = std::max(height(x->left), height(x->right)) + 1;
// Retourner le nouveau root
return x;
Node* leftRotate(Node* x) {
Node* y = x->right;
Node* T2 = y->left;
// Effectuer la rotation
y->left = x;
x->right = T2;
// Mettre à jour les hauteurs
x->height = std::max(height(x->left), height(x->right)) + 1;
y->height = std::max(height(y->left), height(y->right)) + 1;
// Retourner le nouveau root
return y;
Node* insert(Node* node, int key) {
// 1. Effectuer l'insertion BST normale
if (!node)
return new Node(key);
if (key < node->key)
node->left = insert(node->left, key);
else if (key > node->key)
node->right = insert(node->right, key);
else // Les clés égales ne sont pas autorisées dans BST
return node;
// 2. Mettre à jour la hauteur de cet ancêtre nœud
node->height = 1 + std::max(height(node->left), height(node->right));
// 3. Obtenir le facteur d'équilibre de cet ancêtre nœud pour vérifier si ce nœud est déséquilibré
int balance = getBalance(node);
// Si ce nœud devient déséquilibré, alors il y a 4 cas
// Cas gauche gauche
if (balance > 1 && key < node->left->key)
return rightRotate(node);
// Cas droit droit
if (balance < -1 && key > node->right->key)
return leftRotate(node);
// Cas gauche droit
if (balance > 1 && key > node->left->key) {
node->left = leftRotate(node->left);
return rightRotate(node);
// Cas droit gauche
if (balance < -1 && key < node->right->key) {
node->right = rightRotate(node->right);
return leftRotate(node);
// Retourner le pointeur de nœud (inchangé)
return node;
void preOrder(Node* root) {
if (root) {
std::cout << root->key << " ";
preOrder(root->left);
preOrder(root->right);
public:
AVLTree() : root(nullptr) {}
void insert(int key) {
root = insert(root, key);
}
void preOrder() {
preOrder(root);
};
int main() {
AVLTree tree;
// Insérer des nœuds dans l'arbre AVL
[Link](10);
[Link](20);
[Link](30);
[Link](40);
[Link](50);
[Link](25);
// Afficher l'arbre en parcours pré-ordre
std::cout << "Parcours pré-ordre de l'arbre AVL est : ";
[Link]();
return 0;
:::::::::::::::::::::::::::::Liste chainee
#include <iostream>
// Définition de la classe d'un nœud de la liste chaînée générique
template <class T>
class Node {
public:
T data;
Node* next;
Node(T data) : data(data), next(nullptr) {}
};
// Classe représentant une liste chaînée générique
template <class T>
class LinkedList {
private:
Node<T>* head;
public:
// Constructeur
LinkedList() : head(nullptr) {}
// Fonction pour insérer un nouvel élément au début de la liste
void insertAtBeginning(T new_data) {
Node<T>* new_node = new Node<T>(new_data);
new_node->next = head;
head = new_node;
// Fonction pour insérer un nouvel élément après un nœud donné
void insertAfter(Node<T>* prev_node, T new_data) {
if (prev_node == nullptr) {
std::cout << "Le nœud précédent ne peut pas être nul." << std::endl;
return;
Node<T>* new_node = new Node<T>(new_data);
new_node->next = prev_node->next;
prev_node->next = new_node;
// Fonction pour insérer un nouvel élément à la fin de la liste
void insertAtEnd(T new_data) {
Node<T>* new_node = new Node<T>(new_data);
new_node->next = nullptr;
if (head == nullptr) {
head = new_node;
return;
Node<T>* last = head;
while (last->next != nullptr) {
last = last->next;
last->next = new_node;
// Fonction pour supprimer un nœud avec une clé donnée
void deleteNode(T key) {
Node<T>* temp = head;
Node<T>* prev = nullptr;
if (temp != nullptr && temp->data == key) {
head = temp->next;
delete temp;
return;
while (temp != nullptr && temp->data != key) {
prev = temp;
temp = temp->next;
if (temp == nullptr) return;
prev->next = temp->next;
delete temp;
}
// Fonction pour afficher la liste chaînée
void printList() const {
Node<T>* node = head;
while (node != nullptr) {
std::cout << node->data << " ";
node = node->next;
std::cout << std::endl;
};
int main() {
LinkedList<int> intList;
[Link](6);
[Link](7);
[Link](1);
[Link](4);
[Link]([Link]->next, 8);
std::cout << "Liste chaînée après insertion : ";
[Link]();
[Link](1);
std::cout << "Liste chaînée après suppression du nœud contenant 1 : ";
[Link]();
LinkedList<std::string> stringList;
[Link]("world");
[Link]("Hello");
[Link]("!");
std::cout << "Liste chaînée des chaînes de caractères après insertion : ";
[Link]();
return 0;
:::::Binary_tree
#include <iostream>
// Définition de la structure d'un nœud de l'arbre binaire
struct Node {
int data;
Node* left;
Node* right;
};
// Fonction pour créer un nouveau nœud
Node* newNode(int data) {
Node* node = new Node();
node->data = data;
node->left = node->right = nullptr;
return node;
// Fonction pour insérer un nouvel élément dans l'arbre binaire
Node* insert(Node* root, int data) {
if (root == nullptr) {
return newNode(data);
if (data < root->data) {
root->left = insert(root->left, data);
} else {
root->right = insert(root->right, data);
return root;
}
// Fonction pour trouver le nœud avec la valeur minimale dans un sous-arbre
Node* minValueNode(Node* node) {
Node* current = node;
while (current && current->left != nullptr) {
current = current->left;
return current;
// Fonction pour supprimer un nœud avec une clé donnée
Node* deleteNode(Node* root, int key) {
if (root == nullptr) {
return root;
if (key < root->data) {
root->left = deleteNode(root->left, key);
} else if (key > root->data) {
root->right = deleteNode(root->right, key);
} else {
if (root->left == nullptr) {
Node* temp = root->right;
delete root;
return temp;
} else if (root->right == nullptr) {
Node* temp = root->left;
delete root;
return temp;
Node* temp = minValueNode(root->right);
root->data = temp->data;
root->right = deleteNode(root->right, temp->data);
}
return root;
// Fonction pour rechercher un nœud avec une clé donnée
Node* search(Node* root, int key) {
if (root == nullptr || root->data == key) {
return root;
if (key < root->data) {
return search(root->left, key);
return search(root->right, key);
// Fonction pour afficher l'arbre en parcours pré-ordre
void preOrder(Node* root) {
if (root != nullptr) {
std::cout << root->data << " ";
preOrder(root->left);
preOrder(root->right);
// Fonction pour afficher l'arbre en parcours en-ordre
void inOrder(Node* root) {
if (root != nullptr) {
inOrder(root->left);
std::cout << root->data << " ";
inOrder(root->right);
}
}
// Fonction pour afficher l'arbre en parcours post-ordre
void postOrder(Node* root) {
if (root != nullptr) {
postOrder(root->left);
postOrder(root->right);
std::cout << root->data << " ";
int main() {
Node* root = nullptr;
root = insert(root, 50);
root = insert(root, 30);
root = insert(root, 20);
root = insert(root, 40);
root = insert(root, 70);
root = insert(root, 60);
root = insert(root, 80);
std::cout << "Parcours pré-ordre de l'arbre binaire : ";
preOrder(root);
std::cout << std::endl;
std::cout << "Parcours en-ordre de l'arbre binaire : ";
inOrder(root);
std::cout << std::endl;
std::cout << "Parcours post-ordre de l'arbre binaire : ";
postOrder(root);
std::cout << std::endl;
std::cout << "Suppression de 20\n";
root = deleteNode(root, 20);
std::cout << "Parcours en-ordre de l'arbre binaire après suppression de 20 : ";
inOrder(root);
std::cout << std::endl;
std::cout << "Suppression de 30\n";
root = deleteNode(root, 30);
std::cout << "Parcours en-ordre de l'arbre binaire après suppression de 30 : ";
inOrder(root);
std::cout << std::endl;
std::cout << "Suppression de 50\n";
root = deleteNode(root, 50);
std::cout << "Parcours en-ordre de l'arbre binaire après suppression de 50 : ";
inOrder(root);
std::cout << std::endl;
return 0;
HEAP SORT :
class Heap
{
private:
vector<int> hp;
void heapify_haut(int indice);
void heapify_bas(int indice);
public:
void inserer_element(int elem);
void supprimer_element(int elem);
void retourner_max();
void supprimer_max();
void chercher_element(int elem);
void afficher_tas();
};
#include "Heap.h"
//remonter un element à sa position correcte
void Heap::heapify_haut(int indice)
{
while (indice > 0)
{
int parent = (indice-1)/2;
if (hp[indice] > hp[parent])
{
swap(hp[indice], hp[parent]);
indice = parent;
}
else break;
}
}
//descendre un element à sa position correcte
void Heap::heapify_bas(int indice)
{
while (indice < [Link]())
{
int gch = 2*indice+1;
int droit = 2*indice+2;
int max = indice; // pour trouver l'enfant le plus grand
if ((gch < [Link]()) && (hp[gch] > hp[max]))
max = gch;
if ((droit < [Link]() ) && (hp[droit] > hp[max]))
max = droit;
if (max != indice)
{
swap(hp[indice], hp[max]);
indice = max;
}
else break;
}
}
void Heap::inserer_element(int elem)
{
hp.push_back(elem);
heapify_haut([Link]() - 1);
}
void Heap::supprimer_element(int elem)
{
auto it = find([Link](), [Link](), elem);
if (it != [Link]())
{
int ind = distance([Link](), it);
swap(hp[ind], [Link]()); //echanger avec le dernier element
hp.pop_back(); //le supprimer
heapify_bas(ind); //reajuster en appelant ces deux methodes
heapify_haut(ind);
}
}
void Heap::retourner_max()
{
if (![Link]())
cout << "Max: " << hp[0] << endl;
else
cout << "Le tas est vide." << endl;
}
void Heap::supprimer_max()
{
if (![Link]())
{
swap(hp[0], [Link]());
hp.pop_back();
heapify_bas(0);
}
else
cout << "Le tas est vide rien a supprimer." << endl;
}
void Heap::chercher_element(int elem)
{
auto it = find([Link](), [Link](), elem);
if (it != [Link]())
cout << "Element " << elem << " trouve!!" << endl;
else
cout << "Element " << elem << " non trouve!!" << endl;
}
void Heap::afficher_tas()
{
cout << "Tas: ";
for (int val : hp)
{
cout << val << " ";
}
cout <<"\n"<< endl;
}
:::::::::::::::::::Iterator
ITERATORS :
#include <iostream>
#include <vector>
#include <list>
#include <iterator>
#include <algorithm>
class IteratorManipulator {
public:
// Function to demonstrate forward iteration with a regular iterator
void demonstrateForwardIteration(const std::vector<int>& vec) {
std::cout << "Forward iteration using regular iterator:\n";
for (std::vector<int>::const_iterator it = [Link](); it != [Link](); ++it) {
std::cout << *it << " ";
}
std::cout << "\n";
}
// Function to demonstrate reverse iteration with a reverse iterator
void demonstrateReverseIteration(const std::vector<int>& vec) {
std::cout << "Reverse iteration using reverse iterator:\n";
for (std::vector<int>::const_reverse_iterator rit = [Link](); rit != [Link](); ++rit) {
std::cout << *rit << " ";
}
std::cout << "\n";
}
// Function to demonstrate modification using a regular iterator
void modifyUsingIterator(std::vector<int>& vec) {
std::cout << "Modifying elements by adding 10:\n";
for (std::vector<int>::iterator it = [Link](); it != [Link](); ++it) {
*it += 10;
}
display(vec);
}
// Function to demonstrate usage of constant iterators
void demonstrateConstIterator(const std::list<std::string>& lst) {
std::cout << "Accessing elements using const iterator:\n";
for (std::list<std::string>::const_iterator it = [Link](); it != [Link](); ++it) {
std::cout << *it << " ";
}
std::cout << "\n";
}
// Function to demonstrate inserting elements using an insert iterator
void demonstrateInsertIterator(std::vector<int>& vec, const std::vector<int>& toInsert) {
std::cout << "Inserting elements using insert iterator:\n";
std::copy([Link](), [Link](), std::back_inserter(vec));
display(vec);
}
// Function to demonstrate conversion between regular and reverse iterators
void demonstrateIteratorConversion() {
// Create vector with elements from 1 to 9
std::vector<int> coll = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
// Find position of element with value 5
std::vector<int>::const_iterator pos;
pos = std::find([Link](), [Link](), 5);
// Print value to which iterator pos refers
std::cout << "pos: " << *pos << std::endl;
// Convert iterator to reverse iterator rpos
std::vector<int>::const_reverse_iterator rpos(pos);
// Print value to which reverse iterator rpos refers
std::cout << "rpos: " << *rpos << std::endl;
}
// Function to demonstrate reverse iteration with a loop
void demonstrateLoopReverseIteration(const std::vector<int>& nums) {
std::cout << "Reverse iteration:\n";
for (auto it = [Link](); it != [Link](); ++it) {
std::cout << *it << " ";
}
std::cout << "\n";
}
// Function to demonstrate ostream_iterator
void demonstrateOstreamIterator(const std::vector<int>& nums1) {
std::cout << "Ostream iteration:\n";
std::ostream_iterator<int> out_it(std::cout, " ");
std::copy([Link](), [Link](), out_it);
std::cout << "\n";
}
// Function to demonstrate istream_iterator
void demonstrateIstreamIterator() {
std::vector<int> nums2;
std::cout << "Enter integers (press Ctrl+D or Ctrl+Z to stop):\n";
std::istream_iterator<int> in_it(std::cin), end;
std::copy(in_it, end, std::back_inserter(nums2));
std::cout << "You entered:\n";
for (int num : nums2) {
std::cout << num << " ";
}
std::cout << "\n";
}
// Function to display elements of a container
template <typename Container>
void display(const Container& container) {
for (typename Container::const_iterator it = [Link](); it != [Link](); ++it) {
std::cout << *it << " ";
}
std::cout << "\n";
}
};
int main() {
IteratorManipulator manipulator;
// Demonstrate with a vector of integers
std::vector<int> numbers = {1, 2, 3, 4, 5};
[Link](numbers);
[Link](numbers);
[Link](numbers);
// Demonstrate with a list of strings
std::list<std::string> words = {"Hello", "World", "C++", "Iterators"};
[Link](words);
// Demonstrate inserting elements into a vector
std::vector<int> additionalNumbers = {6, 7, 8};
[Link](numbers, additionalNumbers);
// Demonstrate iterator conversion
[Link]();
// Demonstrate reverse iteration with a loop
std::vector<int> nums = {10, 20, 30, 40, 50};
[Link](nums);
// Demonstrate ostream iterator
std::vector<int> nums1 = {1, 2, 3, 4, 5};
[Link](nums1);
// Demonstrate istream iterator
[Link]();
return 0;
}
:::::::::::::::::::::::::::::::Dijikstra
#include "Graph.h"
#include <iostream>
#include <vector>
#include <queue>
#include <climits> // Pour INT_MAX
#include <fstream>
#include <sstream>
using namespace std;
Graph::Graph() : nbSommet(0) {}
void Graph::lireFichierPondere(const string& nomFichier)
{
ifstream fichier(nomFichier);
if (!fichier.is_open()) {
cout << "Erreur d'ouverture du fichier !" << endl;
return;
}
int nbArret;
fichier >> nbSommet >> nbArret;
[Link](nbSommet);
int u, v, poids;
while (fichier >> u >> v >> poids) {
ajouterArretPondere(u, v, poids);
}
[Link]();
}
void Graph::ajouterArretPondere(int u, int v, int poids)
{
listAdj[u].emplace_back(v, poids); // Graphe dirigé : u -> v
}
void Graph::dijkstra(int depart)
{
vector<int> distance(nbSommet, INT_MAX); // Tableau pour stocker les
distances minimales
vector<bool> visite(nbSommet, false); // Tableau pour vérifier si un
sommet a été visité
vector<int> predecesseur(nbSommet, -1); // Tableau pour stocker les
prédécesseurs de chaque sommet
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq; //
File de priorité
distance[depart] = 0; // La distance du sommet de départ est de 0
[Link]({ 0, depart }); // On insère le sommet de départ dans la file de
priorité
while (![Link]()) {
int dist = [Link]().first; // La distance minimale
int u = [Link]().second; // Le sommet extrait
[Link]();
if (visite[u]) continue; // Si le sommet a déjà été visité, on passe
au suivant
visite[u] = true; // On marque le sommet comme visité
// On explore les voisins de u
for (auto& voisin : listAdj[u]) {
int v = [Link]; // Le voisin du sommet u
int poids = [Link]; // Le poids de l'arête entre u et v
// Si on trouve un chemin plus court pour atteindre v, on met à
jour la distance et le prédécesseur
if (distance[u] != INT_MAX && distance[u] + poids < distance[v])
{
distance[v] = distance[u] + poids;
predecesseur[v] = u; // On enregistre le sommet précédent de
v
[Link]({ distance[v], v }); // On insère v dans la file de
priorité avec la nouvelle distance
}
}
}
// Affichage des distances minimales depuis le sommet de départ
cout << "Distances minimales depuis le sommet " << depart << " :" <<
endl;
for (int i = 0; i < nbSommet; i++) {
cout << "Sommet " << i << ": " << (distance[i] == INT_MAX ? -1 :
distance[i]) << endl;
}
// Affichage des chemins les plus courts
for (int i = 0; i < nbSommet; i++) {
if (i != depart) {
cout << "Chemin le plus court vers le sommet " << i << ": ";
afficherChemin(i, predecesseur);
cout << endl;
}
}
}
// Fonction pour afficher le chemin de 'depart' à 'destination'
void Graph::afficherChemin(int destination, const vector<int>& predecesseur)
{
if (destination == -1) {
cout << "Aucun chemin trouvé." << endl;
return;
}
// On remonte les prédécesseurs pour reconstruire le chemin
vector<int> chemin;
for (int v = destination; v != -1; v = predecesseur[v]) {
chemin.push_back(v);
}
// Affichage du chemin dans l'ordre du départ à la destination
for (int i = [Link]() - 1; i >= 0; --i) {
cout << chemin[i];
if (i > 0) cout << " -> ";
}
}
::::::::::::::::::::::::::::::::
Exo1:
#include <iostream>
#include <vector>
// Fonction qui transforme le vecteur d'origine en un vecteur deux fois plus grand.
// Pour chaque entier n :
// - S'il est pair, on génère [n/2, n/2].
// - S'il est impair, on génère [n/2 + 1, n/2].
void VectElargi(std::vector<int>& vec) {
std::vector<int> newVec;
[Link]([Link]() * 2); // On réserve la place pour éviter les réallocations
for (int n : vec) {
if (n % 2 == 0) {
// n est pair
newVec.push_back(n / 2);
newVec.push_back(n / 2);
} else {
// n est impair
newVec.push_back(n / 2 + 1);
newVec.push_back(n / 2);
}
// On remplace l'ancien vecteur par le nouveau
vec = newVec;
int main() {
// Exemple de test
std::vector<int> valeurs = {18, 4, 11};
// Appel de la fonction VectElargi
VectElargi(valeurs);
// Affichage du vecteur après la transformation
for (int val : valeurs) {
std::cout << val << " ";
std::cout << std::endl;
return 0;
:::::::::::::::::::::::::::::::::::::Ex2
#include <iostream>
#include <string>
// Exemple minimal d'une classe Point
class Point {
private:
double x, y;
public:
Point(double xVal = 0.0, double yVal = 0.0) : x(xVal), y(yVal) {}
// Accesseurs
double getX() const { return x; }
double getY() const { return y; }
// Méthode d'affichage
void afficher() const {
std::cout << "(" << x << ", " << y << ")";
};
// Exemple minimal d'une classe Triangle
class Triangle {
private:
Point p1, p2, p3;
public:
Triangle(const Point& a, const Point& b, const Point& c)
: p1(a), p2(b), p3(c) {}
// Méthode d'affichage
void afficher() const {
std::cout << "Triangle[";
[Link](); std::cout << ", ";
[Link](); std::cout << ", ";
[Link](); std::cout << "]";
};
/////////////////////////////////
#include <memory> // pour std::unique_ptr si besoin, ou new/delete classiques
// Noeud de la liste
template <typename T>
struct Noeud {
T data; // la donnée stockée dans le noeud
Noeud<T>* suivant; // pointeur vers le noeud suivant
// Constructeur
Noeud(const T& val) : data(val), suivant(nullptr) {}
};
template <typename T>
class Liste {
private:
Noeud<T>* tete; // pointeur vers le premier noeud de la liste
public:
// Constructeur : liste vide
Liste() : tete(nullptr) {}
// Destructeur : on libère tous les noeuds
~Liste() {
vider();
// Empêcher la copie (pour simplifier l'exemple),
// ou alors on gère la copie en profondeur.
Liste(const Liste&) = delete;
Liste& operator=(const Liste&) = delete;
// Insère un élément au début de la liste
void insererDebut(const T& val) {
Noeud<T>* nouveau = new Noeud<T>(val);
nouveau->suivant = tete;
tete = nouveau;
// Afficher tous les éléments
void afficher() const {
Noeud<T>* courant = tete;
while (courant != nullptr) {
// Supposons que T possède une méthode afficher() ou
// un opérateur << surchargé.
courant->[Link]();
std::cout << " -> ";
courant = courant->suivant;
std::cout << "NULL\n";
// Vérifier si la liste est vide
bool estVide() const {
return (tete == nullptr);
// Supprimer tous les éléments de la liste
void vider() {
while (tete != nullptr) {
Noeud<T>* tmp = tete;
tete = tete->suivant;
delete tmp;
// Exemple d'insertion en fin de liste
void insererFin(const T& val) {
Noeud<T>* nouveau = new Noeud<T>(val);
if (estVide()) {
tete = nouveau;
} else {
Noeud<T>* courant = tete;
while (courant->suivant != nullptr) {
courant = courant->suivant;
}
courant->suivant = nouveau;
// Autres méthodes possibles :
// - insererApres(Noeud<T>* pos, const T& val)
// - supprimerDebut()
// - supprimerFin()
// - etc.
};