La bibliothèque standard C++ (STL) fournit un riche ensemble d'algorithmes pour la manipulation efficace des conteneurs. Ces algorithmes sont classés en plusieurs catégories en fonction de leur comportement : ceux qui ne modifient pas les séquences, ceux qui les modifient, les algorithmes de tri, les algorithmes de tas, les algorithmes de recherche de minimum/maximum, et les algorithmes numériques.
- Algorithmes de séquence non modifiants
Ces algorithmes inspectent les éléments d'un conteneur sans en altérer le contenu.
1.1 Recherche d'éléments
std::find(debut, fin, valeur): Recherche la première occurrence devaleurdans la plage[debut, fin). Retourne un itérateur vers l'élément trouvé, oufinsi l'élément n'est pas présent.std::find_if(debut, fin, predicat): Recherche la première occurrence d'un élément satisfaisant lepredicat(une fonction ou un foncteur retournant un booléen).std::find_end(debut1, fin1, debut2, fin2): Recherche la dernière occurrence de la sous-séquence définie par[debut2, fin2)dans la séquence[debut1, fin1).
std::vector<int> nombres = {10, 30, 50, 70, 90};
// Rechercher la valeur 50
auto it_trouve = std::find(nombres.begin(), nombres.end(), 50);
if (it_trouve != nombres.end()) {
std::cout << "Trouvé : " << *it_trouve << std::endl; // Affiche : Trouvé : 50
}
// Rechercher le premier élément supérieur à 60
auto it_condition = std::find_if(nombres.begin(), nombres.end(), [](int x){ return x > 60; });
if (it_condition != nombres.end()) {
std::cout << "Premier > 60 : " << *it_condition << std::endl; // Affiche : Premier > 60 : 70
}
// Rechercher une sous-séquence
std::vector<int> sous_sequence = {30, 50};
auto it_sous = std::find_end(nombres.begin(), nombres.end(), sous_sequence.begin(), sous_sequence.end());
if (it_sous != nombres.end()) {
// Note : find_end retourne un itérateur vers le début de la dernière occurrence
std::cout << "Sous-séquence trouvée commençant à l'index : " << (it_sous - nombres.begin()) << std::endl; // Affiche : Sous-séquence trouvée commençant à l'index : 1
}
</int></int>
1.2 Comptage d'éléments
std::count(debut, fin, valeur): Compte le nombre d'occurrences devaleur.std::count_if(debut, fin, predicat): Compte le nombre d'éléments satisfaisant lepredicat.
std::vector<int> valeurs = {11, 22, 33, 22, 44, 22};
int compte_22 = std::count(valeurs.begin(), valeurs.end(), 22); // compte_22 vaut 3
int compte_pairs = std::count_if(valeurs.begin(), valeurs.end(), [](int x){ return x % 2 == 0; }); // compte_pairs vaut 4
</int>
1.3 Parcours d'éléments
std::for_each(debut, fin, fonction): Applique unefonctionà chaque élément de la plage[debut, fin).
std::vector<int> chiffres = {1, 2, 3, 4, 5};
std::for_each(chiffres.begin(), chiffres.end(), [](int& elem){ elem *= 2; });
// chiffres contient maintenant {2, 4, 6, 8, 10}
</int>
1.4 Comparaison de séquences
std::equal(debut1, fin1, debut2): Vérifie si la plage[debut1, fin1)est égale à la plage commençant àdebut2et de même taille.std::mismatch(debut1, fin1, debut2): Trouve la première paire d'éléments non égaux entre les plages[debut1, fin1)et[debut2, ...). Retourne une paire d'itérateurs vers les éléments non correspondants.
std::vector<int> seq_a = {1, 2, 3};
std::vector<int> seq_b = {1, 2, 4};
std::vector<int> seq_c = {1, 2, 3, 4};
bool sont_egales = std::equal(seq_a.begin(), seq_a.end(), seq_b.begin()); // sont_egales vaut false
auto denom_pair = std::mismatch(seq_a.begin(), seq_a.end(), seq_c.begin());
if (denom_pair.first != seq_a.end()) {
// Dans cet exemple, seq_a et seq_c correspondent sur les 3 premiers éléments.
// Si seq_a était {1, 2, 4} et seq_c {1, 2, 3}, denom_pair.first pointerait sur 4 et denom_pair.second sur 3.
}
</int></int></int>
1.5 Vérification de prédicats sur des plages
std::all_of(debut, fin, predicat): Retournetruesi tous les éléments satisfont lepredicat.std::any_of(debut, fin, predicat): Retournetruesi au moins un élément satisfait lepredicat.std::none_of(debut, fin, predicat): Retournetruesi aucun élément ne satisfait lepredicat.
std::vector<int> ensemble = {2, 4, 6, 8};
bool tous_pairs = std::all_of(ensemble.begin(), ensemble.end(), [](int x){ return x % 2 == 0; }); // true
bool y_a_impair = std::any_of(ensemble.begin(), ensemble.end(), [](int x){ return x % 2 != 0; }); // false
bool aucun_negatif = std::none_of(ensemble.begin(), ensemble.end(), [](int x){ return x < 0; }); // true
</int>
- Algorithmes de séquence modifiants
Ces algorithmes altèrent le contenu des conteneurs sur lesquels ils opèrent.
2.1 Copie d'éléments
std::copy(debut_source, fin_source, debut_destination): Copie les éléments de la plage source vers la destination. La destination doit avoir suffisamment d'espace alloué.std::copy_if(debut_source, fin_source, debut_destination, predicat): Copie uniquement les éléments qui satisfont lepredicat.
std::vector<int> source = {1, 2, 3, 4, 5};
std::vector<int> destination(source.size());
// Copier tous les éléments
std::copy(source.begin(), source.end(), destination.begin()); // destination contient {1, 2, 3, 4, 5}
// Copier uniquement les éléments pairs dans un nouveau vecteur
std::vector<int> pairs;
std::copy_if(source.begin(), source.end(), std::back_inserter(pairs), [](int x){ return x % 2 == 0; }); // pairs contient {2, 4}
</int></int></int>
L'utilisation de std::back_inserter permet d'ajouter des éléments à la fin du conteneur de destination sans nécessiter d'allocation préalable.
2.2 Transformation d'éléments
std::transform(debut_source, fin_source, debut_destination, operation): Applique uneoperationunaire à chaque élément de la plage source et stocke le résultat dans la plage de destination.std::transform(debut_source1, fin_source1, debut_source2, debut_destination, operation): Applique uneoperationbinaire aux éléments des deux plages sources et stocke le résultat dans la destination.
std::vector<int> nombres = {1, 2, 3};
std::vector<int> carres(nombres.size());
std::transform(nombres.begin(), nombres.end(), carres.begin(), [](int x){ return x * x; }); // carres contient {1, 4, 9}
std::vector<int> v1 = {1, 2, 3};
std::vector<int> v2 = {4, 5, 6};
std::vector<int> somme(v1.size());
std::transform(v1.begin(), v1.end(), v2.begin(), somme.begin(), [](int x, int y){ return x + y; }); // somme contient {5, 7, 9}
</int></int></int></int></int>
2.3 Remplacement d'éléments
std::replace(debut, fin, ancienne_valeur, nouvelle_valeur): Remplace toutes les occurrences deancienne_valeurparnouvelle_valeur.std::replace_if(debut, fin, predicat, nouvelle_valeur): Remplace les éléments satisfaisant lepredicatparnouvelle_valeur.std::replace_copy(debut_source, fin_source, debut_destination, ancienne_valeur, nouvelle_valeur): Copie les éléments de la source vers la destination, en remplaçantancienne_valeurparnouvelle_valeur. Le conteneur source n'est pas modifié.
std::vector<int> donnees = {1, 2, 3, 2, 5};
std::replace(donnees.begin(), donnees.end(), 2, 20); // donnees contient {1, 20, 3, 20, 5}
std::replace_if(donnees.begin(), donnees.end(), [](int x){ return x > 10; }, 0); // donnees contient {1, 0, 3, 0, 5}
std::vector<int> resultat_copie;
std::replace_copy(donnees.begin(), donnees.end(), std::back_inserter(resultat_copie), 3, 300); // resultat_copie contient {1, 0, 300, 0, 5}
</int></int>
2.4 Suppression d'éléments (logique)
std::remove(debut, fin, valeur): Déplace tous les éléments égaux àvaleurvers la fin de la plage[debut, fin)et retourne un itérateur vers le nouveau "fin logique" des éléments valides. Ne supprime pas réellement les éléments du conteneur.std::remove_if(debut, fin, predicat): Similaire àremove, mais utilise unpredicatpour identifier les éléments à "supprimer".
Ces fonctions sont généralement utilisées en combinaison avec la méthode erase du conteneur pour supprimer physiquement les éléments déplacés.
std::vector<int> liste = {1, 2, 3, 2, 4};
// Déplacer les 2 vers la fin
auto nouveau_fin = std::remove(liste.begin(), liste.end(), 2); // liste est maintenant {1, 3, 4, ?, ?} (les ? sont les anciens 2)
// Supprimer physiquement les éléments invalides
liste.erase(nouveau_fin, liste.end()); // liste contient {1, 3, 4}
// Suppression des éléments pairs en une seule opération
std::vector<int> liste2 = {1, 2, 3, 4, 5};
liste2.erase(std::remove_if(liste2.begin(), liste2.end(), [](int x){ return x % 2 == 0; }), liste2.end()); // liste2 contient {1, 3, 5}
</int></int>
2.5 Suppression des doublons consécutifs
std::unique(debut, fin): Supprime les éléments dupliqués adjacents dans la plage[debut, fin). Commeremove, il retourne le nouvel itérateur de fin logique et ne modifie pas la taille du conteneur. Il doit être combiné avecerase.
std::vector<int> vec_doublons = {1, 1, 2, 2, 3, 3, 3, 4, 5};
auto dernier_unique = std::unique(vec_doublons.begin(), vec_doublons.end());
vec_doublons.erase(dernier_unique, vec_doublons.end()); // vec_doublons contient {1, 2, 3, 4, 5}
</int>
2.6 Inversion et Rotation
std::reverse(debut, fin): Inverse l'ordre des éléments dans la plage[debut, fin).std::rotate(debut, milieu, fin): Effectue une rotation de la plage[debut, fin)de sorte que l'élément pointé parmilieudevienne le premier élément.
std::vector<int> v_a_inverser = {1, 2, 3, 4, 5};
std::reverse(v_a_inverser.begin(), v_a_inverser.end()); // v_a_inverser contient {5, 4, 3, 2, 1}
std::vector<int> v_a_rotater = {1, 2, 3, 4, 5};
// Déplace l'élément à l'index 2 (valeur 3) au début
std::rotate(v_a_rotater.begin(), v_a_rotater.begin() + 2, v_a_rotater.end()); // v_a_rotater contient {3, 4, 5, 1, 2}
</int></int>
2.7 Mélange aléatoire
std::shuffle(debut, fin, generateur): Réorganise aléatoirement les éléments dans la plage[debut, fin)en utilisant legenerateurde nombres aléatoires fourni. (Nécessite C++11 ou plus)
#include <random>
#include <algorithm> // Nécessaire pour std::shuffle
std::vector<int> desordonner = {1, 2, 3, 4, 5};
std::random_device rd; // Génère une graine aléatoire matérielle
std::mt19937 g(rd()); // Mersenne Twister, un générateur de nombres pseudo-aléatoires de haute qualité
std::shuffle(desordonner.begin(), desordonner.end(), g); // desordonner est maintenant dans un ordre aléatoire
</int>
- Algorithmes de tri et apparentés
3.1 Tri
std::sort(debut, fin): Trie la plage[debut, fin). C'est un tri rapide (généralement introsort), non stable, avec une complexité temporellle moyenne de O(N log N).std::stable_sort(debut, fin): Trie la plage de manière stable, préservant l'ordre relatif des éléments égaux. Sa complexité est également O(N log N), mais il peut utiliser plus de mémoire.std::partial_sort(debut, milieu, fin): Trie seulement lesmilieu - debutplus petits éléments de la plage[debut, fin)et les place dans l'ordre dans la sous-plage[debut, milieu).
std::vector<int> elements = {5, 3, 1, 4, 2};
std::sort(elements.begin(), elements.end()); // elements trié : {1, 2, 3, 4, 5}
// Tri décroissant
std::sort(elements.begin(), elements.end(), std::greater<int>()); // elements trié : {5, 4, 3, 2, 1}
// Tri stable basé sur une clé
std::vector<std::pair<int, char>> paires = {{1, 'b'}, {2, 'a'}, {1, 'c'}, {2, 'd'}};
std::stable_sort(paires.begin(), paires.end(), [](const auto& a, const auto& b){ return a.first < b.first; });
// paires trié : {{1, 'b'}, {1, 'c'}, {2, 'a'}, {2, 'd'}} (ordre relatif préservé pour les clés égales)
std::vector<int> data = {5, 3, 1, 4, 2, 6};
// Place les 3 plus petits éléments triés au début
std::partial_sort(data.begin(), data.begin() + 3, data.end());
// data contient {1, 2, 3, ?, ?, ?} où les '?' sont les éléments restants non triés.
</int></int></int>
3.2 Tri partiel avancé
std::nth_element(debut, n, fin): Réorganise la plage[debut, fin)de telle sorte que l'élément à la positionnsoit celui qui serait à cette position si la plage était entièrement triée. Tous les éléments avantnsont inférieurs ou égaux à l'élément àn, et tous les éléments aprèsnsont supérieurs ou égaux. C'est un tri partiel non garanti en O(N) en moyenne.
std::vector<int> nums = {5, 3, 1, 4, 2, 6};
// Assure que l'élément à l'index 2 (3ème plus petit) est à sa place correcte
std::nth_element(nums.begin(), nums.begin() + 2, nums.end());
// Après l'appel, nums[2] contient la valeur 3. Les éléments avant nums[2] sont <= 3,
// et ceux après nums[2] sont >= 3. L'ordre interne de ces sous-plages n'est pas garanti.
</int>
3.3 Recherche binaire et bornes
Ces algorithmes nécessitent que la plage soit préalablement triée.
std::binary_search(debut, fin, valeur): Vérifie sivaleurest présente dans la plage triée[debut, fin). Retournetrueoufalse.std::lower_bound(debut, fin, valeur): Retourne un itérateur vers le premier élément de la plage qui n'est pas inférieur àvaleur(c'est-à-dire, >=valeur).std::upper_bound(debut, fin, valeur): Retourne un itérateur vers le premier élément de la plage qui est strictement supérieur àvaleur.
std::vector<int> triee = {1, 3, 3, 5, 7};
bool existe = std::binary_search(triee.begin(), triee.end(), 3); // existe vaut true
auto borne_inf = std::lower_bound(triee.begin(), triee.end(), 3); // pointe vers le premier 3 (index 1)
std::cout << "Index borne inférieure pour 3 : " << (borne_inf - triee.begin()) << std::endl;
auto borne_sup = std::upper_bound(triee.begin(), triee.end(), 3); // pointe vers 5 (index 3)
std::cout << "Index borne supérieure pour 3 : " << (borne_sup - triee.begin()) << std::endl;
</int>
3.4 Fusion de séquences triées
std::merge(debut1, fin1, debut2, fin2, debut_destination): Fusionne deux plages triées[debut1, fin1)et[debut2, fin2)en une seule plage triée dans la destination. La destination doit avoir une capacité suffisante.
std::vector<int> v_trie1 = {1, 3, 5};
std::vector<int> v_trie2 = {2, 4, 6};
std::vector<int> fusionnee(v_trie1.size() + v_trie2.size());
std::merge(v_trie1.begin(), v_trie1.end(), v_trie2.begin(), v_trie2.end(), fusionnee.begin());
// fusionnee contient {1, 2, 3, 4, 5, 6}
</int></int></int>
- Algorithmes de tas
La STL fournit des algorithmes pour manipuler des séquences comme des tas binaires (généralement des tas maximaux par défaut).
std::make_heap(debut, fin): Transforme la plage[debut, fin)en un tas.std::push_heap(debut, fin): Ajoute le dernier élément de la plage (qui a été préalablement ajouté au conteneur) dans le tas existant couvrant[debut, fin-1).std::pop_heap(debut, fin): Déplace le plus grand élément (la racine du tas) du tas[debut, fin)vers la positionfin-1, et réorganise le reste[debut, fin-1)en un tas valide.std::sort_heap(debut, fin): Trie la plage qui représente un tas.
std::vector<int> tas_data = {4, 1, 3, 2, 5};
std::make_heap(tas_data.begin(), tas_data.end()); // tas_data ressemble à {5, 4, 3, 2, 1} (structure de tas max)
tas_data.push_back(6); // Ajout de l'élément
std::push_heap(tas_data.begin(), tas_data.end()); // tas_data ressemble à {6, 4, 5, 2, 1, 3}
std::pop_heap(tas_data.begin(), tas_data.end()); // Le plus grand (6) est déplacé à la fin
int max_element = tas_data.back(); // max_element vaut 6
tas_data.pop_back(); // Retire 6 du vecteur
std::sort_heap(tas_data.begin(), tas_data.end()); // tas_data est maintenant trié : {1, 2, 3, 4, 5}
</int>
- Algorithmes de minimum/maximum
5.1 Minimum et Maximum de deux valeurs
std::min(a, b): Retourne le plus petit deaetb.std::max(a, b): Retourne le plus grand deaetb.- Il existe également des surcharges pour les listes d'initialisation (depuis C++11).
int val1 = 5, val2 = 3;
int minimum = std::min(val1, val2); // minimum vaut 3
int maximum = std::max(val1, val2); // maximum vaut 5
auto min_liste = std::min({4, 2, 8, 5, 1}); // min_liste vaut 1
auto max_liste = std::max({4, 2, 8, 5, 1}); // max_liste vaut 8
5.2 Minimum et Maximum dans une plage
std::min_element(debut, fin): Retourne un itérateur vers le plus petit élément dans la plage[debut, fin).std::max_element(debut, fin): Retourne un itérateur vers le plus grand élément dans la plage[debut, fin).
std::vector<int> vals = {3, 1, 4, 2, 5};
auto it_min = std::min_element(vals.begin(), vals.end()); // it_min pointe vers 1
auto it_max = std::max_element(vals.begin(), vals.end()); // it_max pointe vers 5
</int>
5.3 Minimum et Maximum simultanés
std::minmax_element(debut, fin): Retourne une paire d'itérateurs, le premier pointant vers le plus petit élément et le second vers le plus grand élément de la plage. (Nécessite C++11 ou plus)
std::vector<int> vals = {3, 1, 4, 2, 5};
auto minmax_it = std::minmax_element(vals.begin(), vals.end());
// minmax_it.first pointe vers 1, minmax_it.second pointe vers 5
</int>
- Algorithmes numériques (dans <numeric>)
6.1 Accumulation
std::accumulate(debut, fin, valeur_initiale): Calcule la somme des éléments de la plage[debut, fin), en commençant parvaleur_initiale.std::accumulate(debut, fin, valeur_initiale, operation_binaire): Permet d'utiliser une opération binaire personnalisée (par défaut, l'addition).
#include <numeric>
std::vector<int> chiffres = {1, 2, 3, 4, 5};
int somme = std::accumulate(chiffres.begin(), chiffres.end(), 0); // somme vaut 15
// Calculer le produit
int produit = std::accumulate(chiffres.begin(), chiffres.end(), 1, std::multiplies<int>()); // produit vaut 120
</int>
6.2 Produit scalaire
std::inner_product(debut1, fin1, debut2, valeur_initiale): Calcule le produit scalaire de deux plages. La plage 1 est[debut1, fin1)et la plage 2 commence àdebut2et a la même taille que la plage 1.
std::vector<int> vec_a = {1, 2, 3};
std::vector<int> vec_b = {4, 5, 6};
// Calcule (1*4 + 2*5 + 3*6)
int produit_scalaire = std::inner_product(vec_a.begin(), vec_a.end(), vec_b.begin(), 0); // produit_scalaire vaut 32
</int></int>
6.3 Remplissage séquentiel
std::iota(debut, fin, valeur_debut): Remplit la plage[debut, fin)avec des valeurs consécutives commençant àvaleur_debut. (Nécessite C++11 ou plus)
std::vector<int> suite(5);
std::iota(suite.begin(), suite.end(), 10); // suite contient {10, 11, 12, 13, 14}
</int>
6.4 Somme partielle
std::partial_sum(debut_source, fin_source, debut_destination): Calcule les sommes partielles des éléments de la plage source et les stocke dans la plage destination.
std::vector<int> source_somme = {1, 2, 3, 4, 5};
std::vector<int> dest_somme(source_somme.size());
std::partial_sum(source_somme.begin(), source_somme.end(), dest_somme.begin()); // dest_somme contient {1, 3, 6, 10, 15}
</int></int>
6.5 Différence adjacente
std::adjacent_difference(debut_source, fin_source, debut_destination): Calcule la différence entre chaque élément et le précédent dans la plage source et stocke les résultats dans la plage destination. Le premier élément est copié tel quel.
std::vector<int> source_diff = {1, 2, 3, 4, 5};
std::vector<int> dest_diff(source_diff.size());
std::adjacent_difference(source_diff.begin(), source_diff.end(), dest_diff.begin()); // dest_diff contient {1, 1, 1, 1, 1} (car 2-1=1, 3-2=1, etc.)
</int></int>
- Autres algorithmes utiles
7.1 Génération de séquences
std::generate(debut, fin, generateur): Remplit la plage[debut, fin)en appelant répétitivement la fonctiongenerateur.std::generate_n(debut_destination, nombre, generateur): Génèrenombreéléments en utilisant legenerateuret les écrit à partir dedebut_destination.
std::vector<int> generateur_vec(5);
int compteur = 0;
std::generate(generateur_vec.begin(), generateur_vec.end(), [&compteur](){ return compteur++; }); // generateur_vec contient {0, 1, 2, 3, 4}
std::vector<int> generateur_n_vec(5);
int debut_val = 10;
std::generate_n(generateur_n_vec.begin(), 3, [&debut_val](){ return debut_val++; }); // generateur_n_vec contient {10, 11, 12, 0, 0} (les deux derniers éléments ne sont pas modifiés)
</int></int>
7.2 Inclusion de plages
std::includes(debut1, fin1, debut2, fin2): Vérifie si la plage triée[debut1, fin1)contient tous les éléments de la plage triée[debut2, fin2).
std::vector<int> plage_principale = {1, 2, 3, 4, 5};
std::vector<int> sous_ensemble = {2, 4};
bool contient = std::includes(plage_principale.begin(), plage_principale.end(), sous_ensemble.begin(), sous_ensemble.end()); // contient vaut true
</int></int>
7.3 Opérations sur ensembles
Ces algorithmes nécessitent que les deux plages d'entrée soient triées.
std::set_union: Calcule l'union des deux ensembles.std::set_intersection: Calcule l'intersection des deux ensembles.std::set_difference: Calcule la différence entre le premier et le second ensemble (éléments dans le premier mais pas dans le second).std::set_symmetric_difference: Calcule la différence symétrique (éléments présents dans l'un ou l'autre ensemble, mais pas dans les deux).
std::vector<int> ens1 = {1, 2, 3, 4, 5};
std::vector<int> ens2 = {3, 4, 5, 6, 7};
std::vector<int> resultat;
// Union
std::set_union(ens1.begin(), ens1.end(), ens2.begin(), ens2.end(), std::back_inserter(resultat));
// resultat : {1, 2, 3, 4, 5, 6, 7}
// Intersection
resultat.clear();
std::set_intersection(ens1.begin(), ens1.end(), ens2.begin(), ens2.end(), std::back_inserter(resultat));
// resultat : {3, 4, 5}
// Différence (ens1 - ens2)
resultat.clear();
std::set_difference(ens1.begin(), ens1.end(), ens2.begin(), ens2.end(), std::back_inserter(resultat));
// resultat : {1, 2}
// Différence symétrique
resultat.clear();
std::set_symmetric_difference(ens1.begin(), ens1.end(), ens2.begin(), ens2.end(), std::back_inserter(resultat));
// resultat : {1, 2, 6, 7}
</int></int></int>
- Questions fréquentes
- Quelle est la différence entre
std::sortetstd::stable_sort?std::sortest généralemetn plus rapide mais n'est pas stable : l'ordre relatif des éléments égaux peut changer.std::stable_sortgarantit que l'ordre relatif des éléments égaux est préservé, au prix d'une complexité spatiale potentiellement plus élevée. - Pourquoi
std::removedoit-il être utilisé aveccontainer.erase?std::removene supprime pas réellement les éléments ; il les déplace vers la fin de la plage et retourne un itérateur vers le début de cette section "invalide". La taille du conteneur n'est pas modifiée.container.eraseest nécessaire pour supprimer physiquement ces éléments de la fin du conteneur et ajuster sa taille. - **Quels algorithmes STL nécessitent que le conteneur soit trié ?**Les algorithmes de recherche binaire (
std::binary_search,std::lower_bound,std::upper_bound), les algorithmes de fusion (std::merge) et les algorithmes d'opérations sur ensembles (std::set_union,std::set_intersection, etc.) nécessitent des plages d'entrée triées pour fonctionner correctement et efficacement.