0% ont trouvé ce document utile (0 vote)
5 vues29 pages

Algorithmes de graphes et structures de données

Le document présente plusieurs structures de données et algorithmes, notamment le parcours en largeur (BFS) et en profondeur (DFS) d'un graphe, un arbre AVL, une liste chaînée, et un arbre binaire. Chaque structure est accompagnée de son implémentation en C++, illustrant les opérations de base comme l'insertion, la suppression et le parcours. Ces exemples démontrent l'utilisation de différentes techniques de gestion des données en programmation.

Transféré par

Ikrame Baskane
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
5 vues29 pages

Algorithmes de graphes et structures de données

Le document présente plusieurs structures de données et algorithmes, notamment le parcours en largeur (BFS) et en profondeur (DFS) d'un graphe, un arbre AVL, une liste chaînée, et un arbre binaire. Chaque structure est accompagnée de son implémentation en C++, illustrant les opérations de base comme l'insertion, la suppression et le parcours. Ces exemples démontrent l'utilisation de différentes techniques de gestion des données en programmation.

Transféré par

Ikrame Baskane
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

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.

};

Vous aimerez peut-être aussi