Tri à peigne

Harshit Jindal 12 octobre 2023
  1. Algorithme de tri à peigne
  2. Exemple de tri par peigne
  3. Implémentation de l’algorithme de tri en peigne
  4. Complexité de l’algorithme de tri à peigne
Tri à peigne

Le tri à peigne est un algorithme de tri simple basé sur la comparaison. C’est une forme améliorée de tri à bulles. Dans le tri à bulles, les éléments adjacents sont comparés dans chaque passe/phase et éliminent les inversions une par une. En revanche, le tri en peigne commence par utiliser un grand écart et le réduit à chaque fois d’un facteur de réduction de 1.3. Le tri en peigne peut supprimer plusieurs inversions avec un seul échange. Il est basé sur l’idée de tuer les tortues. Les tortues sont les petits éléments vers la fin de la liste, ce qui réduit l’efficacité du tri par bulles et le fait de les tuer améliore considérablement les performances du tri.

Algorithme de tri à peigne

Supposons que nous ayons un tableau non trié A[] contenant n éléments. Nous prendrons le facteur de rétrécissement comme 1.3 car il a été empiriquement prouvé qu’il donne les meilleurs résultats.

  • Initialisez la variable gap comme étant la taille du tableau et la variable swapped comme true.
  • Déclarer la variable constante SHRINK_FACTOR comme étant 1.3.
  • Si la variable gap n’est pas à 1 ou que la variable swapped est à true, faites ce qui suit :
    • Set swapped as false.
    • Set gap as (int)gap/SHRINK_FACTOR.
    • For every element in the range 0 to n - gap do the following - if A[i] > A[i+gap], swap(A[i], A[i+gap]) and set swapped to true.

Exemple de tri par peigne

Supposons que nous ayons le tableau : (3, 5, 2, 8, 1, 7, 6, 4). Nous allons le trier en utilisant l’algorithme de tri en peigne.

Initialisez gap=8 , swapped=true et SHRINK_FACTOR = 1.3.

  • La première passe

gap = 8/1,3 = 6 , swapped = false

Itération (3, 5, 2, 8, 1, 7, 6, 4) Action
i = 0 (3, 5, 2, 8, 3, 7, 6, 4) 3 < 6, Pas d’échange
i = 1 (3, 4, 2, 8, 1, 7, 6, 5) 5 > 4, Échangés
  • Le deuxième passage

écart" = 6/1,3 = 4 , “échangé” = “faux

Itération (3, 4, 2, 8, 1, 7, 6, 5) Action
i = 0 (1, 4, 2, 8, 3, 7, 6, 5) 3 > 1, Échangé
i = 1 (1, 4, 2, 8, 3, 7, 6, 5) 4 < 7, Pas d’échange
i = 2 (1, 4, 2, 8, 3, 7, 6, 5) 2 < 6, Pas d’échange
i = 3 (1, 4, 2, 5, 3, 7, 6, 8) 8 > 5, Échangés
  • Le troisième passage

gap = 4 / 1,3 = 3, swapped = false

Itération (1, 4, 2, 5, 3, 7, 6, 8) Action
i = 0 (1, 4, 2, 5, 3, 7, 6, 8) 1 < 5, Pas d’échange
i = 1 (1, 3, 2, 5, 4, 7, 6, 8) 4 > 3, Échangés
i = 2 (1, 3, 2, 5, 4, 7, 6, 8) 2 < 7, Pas d’échange
i = 3 (1, 3, 2, 5, 4, 7, 6, 8) 5 < 6, Pas d’échange
i = 4 (1, 3, 2, 5, 4, 7, 6, 8) 4 < 8, Pas d’échange
  • Le quatrième passage

gap = 3 / 1,3 = 2, swapped = false

Itération (1, 3, 2, 5, 4, 7, 6, 8) Action
i = 0 (1, 3, 2, 5, 4, 7, 6, 8) 1 < 2, Pas d’échange
i = 1 (1, 3, 2, 5, 4, 7, 6, 8) 3 < 5, Pas d’échange
i = 2 (1, 3, 2, 5, 4, 7, 6, 8) 2 < 4, Pas d’échange
i = 3 (1, 3, 2, 5, 4, 7, 6, 8) 5 < 7, Pas d’échange
i = 4 (1, 3, 2, 5, 4, 7, 6, 8) 4 < 6, Pas d’échange
i = 5 (1, 3, 2, 5, 4, 7, 6, 8) 7 < 8, Pas d’échange
  • Le cinquième passage

gap = 2 / 1,3 = 1, swapped = false

Itération (1, 3, 2, 5, 4, 7, 6, 8) Action
i = 0 (1, 3, 2, 5, 4, 7, 6, 8) 1 < 3, Pas d’échange
i = 1 (1, 2, 3, 5, 4, 7, 6, 8) 3 > 2, Échangé
i = 2 (1, 2, 3, 5, 4, 7, 6, 8) 3 < 5, Pas d’échange
i = 3 (1, 2, 3, 4, 5, 7, 6, 8) 5 > 4, Échangés
i = 4 (1, 2, 3, 4, 5, 7, 6, 8) 5 < 7, Pas d’échange
i = 5 (1, 2, 3, 5, 4, 6, 7, 8) 7 > 6, Échangé
i = 6 (1, 2, 3, 4, 5, 6, 7, 8) 7 < 8, Pas d’échange

Nous obtenons le tableau final trié comme : (1, 2, 3, 4, 5, 6, 7, 8).

Implémentation de l’algorithme de tri en peigne

#include <iostream>
using namespace std;

int updateGap(int gap) {
  gap = (gap * 10) / 13;
  if (gap < 1)
    return 1;
  else
    return gap;
}

void combSort(int arr[], int n) {
  int gap = n;
  bool swapped = true;
  while (gap > 1 || swapped == true) {
    gap = updateGap(gap);
    swapped = false;
    for (int i = 0; i < (n - gap); i++) {
      int temp;
      if (arr[i] > arr[i + gap]) {
        temp = arr[i];
        arr[i] = arr[i + gap];
        arr[i + gap] = temp;
        swapped = true;
      }
    }
  }
}

int main() {
  int n = 6;
  int arr[6] = {5, 3, 4, 2, 1, 6};
  cout << "Input array: ";
  for (int i = 0; i < n; i++) {
    cout << arr[i] << " ";
  }
  cout << "\n";
  combSort(arr, n);
  cout << "Output array: ";
  for (int i = 0; i < n; i++) {
    cout << arr[i] << " ";
  }
  cout << "\n";
}

Complexité de l’algorithme de tri à peigne

Complexité temporelle

  • Cas moyen

La complexité temporelle est de l’ordre du [Big Theta] : O(n2/2p) où p est le nombre d’incréments.

  • Pire cas

La complexité temporelle dans le pire des cas est [Big O] : O(n2).

  • Meilleur cas

Dans le meilleur des cas, le tableau est déjà trié ou presque trié. Le meilleur cas de complexité temporelle est [Big Omega] : O(nlogn). Il s’agit d’une amélioration significative par rapport au meilleur cas de complexité temporelle du tri à bulles.

Complexité spatiale

La complexité de l’espace pour cet algorithme est O(n) car l’algorithme de tri en peigne ne nécessite pas d’espace supplémentaire autre que des variables temporaires.

Harshit Jindal avatar Harshit Jindal avatar

Harshit Jindal has done his Bachelors in Computer Science Engineering(2021) from DTU. He has always been a problem solver and now turned that into his profession. Currently working at M365 Cloud Security team(Torus) on Cloud Security Services and Datacenter Buildout Automation.

LinkedIn

Article connexe - Sort Algorithm