Implémenter l'algorithme de tri de sélection en C++

Jinku Hu 12 octobre 2023
Implémenter l'algorithme de tri de sélection en C++

Cet article explique comment implémenter l’algorithme de tri par sélection en C++.

Implémenter le tri de sélection pour le conteneur std::vector en C++

Parmi les algorithmes de tri simples, vous pouvez considérer le tri par sélection comme l’un des plus simples à mettre en œuvre ; bien qu’il ait la complexité O(n2), et le rend totalement inefficace sur les grands vecteurs.

Le tri par sélection peut être spécifié comme la routine suivante : Au début, nous trouvons la valeur minimale dans le vecteur et l’échangeons avec le premier élément. Ensuite, nous déplaçons le pointeur sur le deuxième élément et trouvons la valeur minimale du sous-vecteur restant à échanger avec le deuxième élément. Nous continuons les étapes précédentes pour le reste du vecteur tout en avançant le pointeur un élément à la fois.

Une autre explication du tri par sélection pourrait consister à diviser le vecteur d’entrée en deux partiesL : la première est un sous-vecteur trié et la seconde est le sous-vecteur restant d’éléments non triés (qui est dans l’ordre d’origine). Comme le sous-vecteur trié ne peut pas être supposé être présent dans le vecteur donné, nous devons choisir le premier élément comme diviseur entre les sous-vecteurs triés et non triés. Ainsi, lorsque nous commençons à échanger les valeurs minimales avec les éléments aux positions de départ. Le vecteur sera naturellement divisé en parties triées et non triées.

Dans l’exemple suivant, nous implémentons la fonction selectionSort qui prend la référence à l’objet std::vector et effectue une modification sur place des éléments. Nous avons utilisé l’algorithme std::min_element pour trouver la valeur minimale à chaque itération ; cela permet de mieux comprendre l’algorithme pour la première fois.

#include <algorithm>
#include <iostream>
#include <vector>

using std::cout;
using std::endl;
using std::vector;

template <typename T>
void printVector(const vector<T> &vec) {
  for (auto &i : vec) {
    cout << i << "; ";
  }
  cout << endl;
}

template <typename T>
void selectionSort(vector<T> &vec) {
  for (auto it = vec.begin(); it != vec.end(); ++it) {
    std::swap(*it, *std::min_element(it, vec.end()));
  }
}

int main() {
  vector<int> vec1 = {43, 5, 123, 94, 359, -23, 2, -1};

  printVector(vec1);
  selectionSort(vec1);
  printVector(vec1);

  return EXIT_SUCCESS;
}

Production:

43;
5;
123;
94;
359;
- 23;
2;
- 1;
- 23;
- 1;
2;
5;
43;
94;
123;
359;

Alternativement, nous pouvons réécrire la fonction selectionSort avec la deuxième boucle for qui trouve la valeur minimale pour le sous-vecteur non trié restant de chaque itération. Cette version est adaptée à l’analyse de la complexité des algorithmes. Même si l’algorithme de tri par sélection a un temps d’exécution quadratique, il peut être étonnamment efficace sur des vecteurs plus petits par rapport aux algorithmes O(nlogn), comme le tri par fusion ou le tri par tas. Notez que nous utilisons toujours une fonction STL, std::swap, qui est une opération à temps constant dans ce cas, et il est utile que l’exemple de code soit concis.

#include <algorithm>
#include <iostream>
#include <vector>

using std::cout;
using std::endl;
using std::vector;

template <typename T>
void printVector(const vector<T> &vec) {
  for (auto &i : vec) {
    cout << i << "; ";
  }
  cout << endl;
}

template <typename T>
void selectionSort(vector<T> &vec) {
  for (auto it = vec.begin(); it != vec.end(); ++it) {
    auto min = it;

    for (auto i = it + 1; i != vec.end(); ++i) {
      if (*i < *min) min = i;
    }

    std::swap(*it, *min);
  }
}

int main() {
  vector<int> vec1 = {43, 5, 123, 94, 359, -23, 2, -1};

  printVector(vec1);
  selectionSort(vec1);
  printVector(vec1);

  return EXIT_SUCCESS;
}

Production:

43;
5;
123;
94;
359;
- 23;
2;
- 1;
- 23;
- 1;
2;
5;
43;
94;
123;
359;
Auteur: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

Article connexe - C++ Algorithm