Algorithme de tri Shell avec exemple

⚡ Résumé intelligent

Le tri Shell est un algorithme de comparaison sur place qui généralise le tri par insertion en comparant des éléments très éloignés les uns des autres, puis en réduisant l'écart jusqu'à ce que les éléments adjacents soient triés.

  • (I.e. Définition: Une généralisation en place du tri par insertion proposée par Donald Shell en 1959 qui utilise une séquence d'espacement décroissante.
  • 🔀 Séquences d'intervalles : La séquence originale de Shell est n/2, n/4, …, 1 ; les séquences de Knuth, Sedgewick et Ciura sont plus performantes en pratique.
  • | Complexité: O(n log n) dans le meilleur des cas, O(n^2) dans le pire des cas et O(1) espace auxiliaire.
  • Cas d'utilisation: Le noyau Linux, uClibc et bzip2 utilisent Shell Sort pour éviter la récursivité et la mémoire de pile supplémentaire.
  • 🤖 Angle d'approche IA : Les assistants IA peuvent suggérer des séquences d'intervalles et générer à la demande des visualisations animées de tri Shell.

Qu'est-ce que le tri Shell ?

Le tri Shell, également appelé méthode de Shell, est un algorithme de tri efficace basé sur la comparaison en place. Nommé d'après Donald Shell, qui a introduit cette idée en 1959, il s'agit d'une généralisation du tri par insertion qui pallie son comportement quadratique sur des données dispersées.

L'idée fondamentale est de regrouper les éléments éloignés les uns des autres, de trier chaque groupe par insertion, et de réduire progressivement l'écart jusqu'à ce qu'il atteigne un. Le tableau est alors presque trié.

Cet intervalle, ce laps de temps, suit une séquence choisie, comme celle de Shell, de Knuth, d'Hibbard ou de Sedgewick. La version originale de Shell est : n/2, n/4, ..., 1.

Algorithme de tri des coques

Étape 1) Initialisez la valeur d'intervalle h = n/2, où n est la taille du tableau.

Étape 2) Placez tous les éléments situés à une distance de l'intervalle h dans une sous-liste.

Étape 3) Triez chaque sous-liste en utilisant le tri par insertion.

Étape 4) Définissez un nouvel intervalle h = h/2.

Étape 5) Si h > 0, retournez à l'étape 2. Sinon, passez à l'étape 6.

Étape 6) Le tableau résultant est désormais entièrement trié.

Comment fonctionne le tri Shell

Dans le tri par insertion, les éléments se déplacent d'une position à la fois. Le tri Shell, quant à lui, divise le tableau en sous-listes largement espacées en fonction de l'intervalle et effectue un tri par insertion sur chaque sous-liste.

À mesure que l'intervalle diminue, la taille de la sous-liste augmente. Comme les passages précédents laissent les données partiellement triées, les intervalles plus petits nécessitent beaucoup moins d'échanges que les passages en cours. tri par insertion À partir de zéro. La figure ci-dessous illustre une passe de tri Shell.

Travaux de tri des coquilles

Fonctionnement de l'algorithme de tri Shell avec exemple

Trions le tableau ci-dessous à l'aide de Shell Sort.

Fonctionnement de l'algorithme de tri Shell

Étape 1) La taille du tableau est de 8, donc la valeur de l'intervalle initial est h = 8/2 = 4.

Étape 2) Regroupez les éléments à quatre positions d'écart. Sous-listes : {8, 1}, {6, 4}, {7, 5}, {2, 3}.

Fonctionnement de l'algorithme de tri Shell

Étape 3) Triez chaque sous-liste par insertion. Une variable temporaire stocke la valeur insérée pendant le déplacement des éléments. Après les échanges, le tableau ressemble à ceci.

Fonctionnement de l'algorithme de tri Shell

Étape 4) Diminuez l'intervalle. Le nouvel intervalle est h = 4/2 = 2.

Étape 5) Parce que 2 > 0, retournez à l'étape 2 et regroupez les éléments à deux positions d'écart : {1, 5, 8, 7} et {4, 2, 6, 3}.

Fonctionnement de l'algorithme de tri Shell

Triez la première sous-liste. Le tableau devient :

Fonctionnement de l'algorithme de tri Shell

Après avoir trié la deuxième sous-liste :

Fonctionnement de l'algorithme de tri Shell

Diminuez à nouveau l'intervalle à h = 2/2 = 1. Avec un écart d'un, Shell Sort effectue un dernier passage de tri par insertion sur l'ensemble du tableau, comme indiqué ci-dessous.

Fonctionnement de l'algorithme de tri Shell

Fonctionnement de l'algorithme de tri Shell

Fonctionnement de l'algorithme de tri Shell

Étape 6) En divisant à nouveau l'intervalle, on obtient 0. Le tableau est maintenant entièrement trié :

Fonctionnement de l'algorithme de tri Shell

Pseudo-Code pour le tri des coquillages

Start
Input array a of size n
for (interval = n / 2; interval > 0; interval /= 2)
    for (i = interval; i < n; i += 1)
        temp = a[i];
        for (j = i; j >= interval && a[j - interval] > temp; j -= interval)
            a[j] = a[j - interval];
        a[j] = temp;
End

Programme de tri Shell en C/C++

Entrées :

//Shell Sort Program in C/C++
#include <bits/stdc++.h>
using namespace std;
void ShellSort(int data[], int size) {
    for (int interval = size / 2; interval > 0; interval /= 2) {
        for (int i = interval; i < size; i += 1) {
            int temp = data[i];
            int j;
            for (j = i; j >= interval && data[j - interval] > temp; j -= interval) {
                data[j] = data[j - interval];
            }
            data[j] = temp;
        }
    }
}
int main() {
    int data[] = {8, 6, 7, 2, 1, 4, 5, 3};
    int size = sizeof(data) / sizeof(data[0]);
    ShellSort(data, size);
    cout << "Sorted Output: \n";
    for (int i = 0; i < size; i++)
        cout << data[i] << " ";
    cout << "\n";
}

Sortie :

Sorted Output:

1 2 3 4 5 6 7 8

Exemple de tri de shell dans Python

Entrées :

#Shell Sort Example in Python
def ShellSort(data, size):
    interval = size // 2
    while interval > 0:
        for i in range(interval, size):
            temp = data[i]
            j = i
            while j >= interval and data[j - interval] > temp:
                data[j] = data[j - interval]
                j -= interval
            data[j] = temp
        interval //= 2
data = [8, 6, 7, 2, 1, 4, 5, 3]
ShellSort(data, len(data))
print('Sorted Output:')
print(data)

Sortie :

Sorted Output:
[1, 2, 3, 4, 5, 6, 7, 8]

Applications du tri des coques

Le tri Shell est encore présent dans les systèmes modernes où l'espace de pile ou la simplicité sont importants.

  • Le noyau Linux Utilise Shell Sort dans les cas où il est important d'éviter une pile d'appels.
  • La bibliothèque C embarquée uClibc utilise Shell Sort pour limiter l'utilisation de la mémoire.
  • bzip2 utilise Shell Sort pour éviter une récursion profonde lors du tri des blocs.
  • Le firmware embarqué privilégie le tri Shell pour les petits ensembles de données où la récursivité est limitée.

Avantages et inconvénients du tri par coquille

Avantages Désavantages
Aucune pile d'appels n'est requise, ce qui est idéal pour les systèmes embarqués. Ce n'est pas l'option la plus rapide pour les très grands réseaux.
Facile à mettre en œuvre avec peu de code. Les performances se dégradent sur les données comportant des éléments très dispersés.
Efficace pour les tableaux de taille moyenne ou partiellement triés. La complexité temporelle dans le pire des cas est sensible à la séquence d'intervalles choisie.
Fonctionnant sur place, il utilise donc une mémoire auxiliaire constante. Il ne s'agit pas d'un tri stable, donc l'ordre relatif des clés égales peut changer.

Analyse de la complexité du tri des coques

Complexité temporelle du tri des coques

La complexité temporelle du tri Shell dépend de la séquence d'intervalles utilisée.

Dans le meilleur des cas, lorsque le tableau est déjà presque organisé, chaque passage ne nécessite qu'un nombre logarithmique de tests, ce qui donne O(n log n).

Dans le pire des cas, le tableau est agencé de telle sorte que les éléments nécessitent le maximum de comparaisons, et l'incrément final domine à O(n^2) avec la séquence originale de Shell.

  1. Complexité du meilleur cas : O(n log n)
  2. Complexité moyenne : O(n log n) à O(n^(4/3)) selon la séquence d'intervalles
  3. Complexité dans le pire des cas : O(n^2) avec la séquence originale de Shell

La meilleure séquence d'intervalles à usage général reste une question de recherche ouverte, bien que les séquences de Sedgewick et de Ciura donnent de bons résultats en pratique.

Complexité spatiale du tri des coques

Le tri Shell ne nécessite pas de tableaux auxiliaires, donc la complexité spatiale est O(1) quelle que soit la taille de l'entrée, ce qui est l'un de ses plus grands avantages pratiques.

FAQ

Le tri Shell est un algorithme de tri par comparaison sur place proposé par Donald Shell en 1959. Il généralise le tri par insertion en comparant des éléments éloignés les uns des autres, puis en réduisant l'écart jusqu'à ce que les éléments adjacents soient triés, ce qui réduit considérablement le nombre d'échanges.

La complexité temporelle dans le meilleur des cas est O(n log n), et dans le pire des cas, O(n²) avec la séquence originale de Shell. Des séquences à intervalles optimisées, comme celle de Sedgewick, réduisent la complexité dans le pire des cas à environ O(n⁴/³). La complexité spatiale est O(1).

Non, le tri Shell n'est pas stable. Les éléments étant comparés et permutés malgré de grands écarts, deux clés identiques peuvent changer d'ordre relatif au cours d'une même passe. Si la stabilité est importante, utilisez plutôt le tri fusion ou une variante stable du tri par insertion.

Le tri par insertion déplace les éléments d'une position à la fois. Le tri Shell compare d'abord les éléments éloignés les uns des autres, puis réduit progressivement cet écart. Le résultat est un tableau presque trié lorsque l'écart atteint une position, ce qui permet à la dernière passe du tri par insertion de s'effectuer très rapidement.

Les assistants IA peuvent analyser la taille, la distribution et les contraintes de votre ensemble de données, puis recommander un algorithme tel que le tri Shell, le tri rapide ou le tri par base. Ils peuvent également générer des scripts de test comparant le temps d'exécution et l'utilisation de la mémoire, ce qui vous permet de valider la recommandation sur des charges de travail réelles.

Oui. Les outils d'IA peuvent générer des visualisations animées du tri Shell qui mettent en évidence les groupes d'éléments manquants, les comparaisons et les échanges en temps réel. Ces visualisations aident les apprenants à comprendre comment l'intervalle se réduit et comment le tableau converge vers un état trié, itération après itération.

Résumez cet article avec :