Accéder au contenu principal

Tutoriel Python sur le tri par fusion

Apprenez tout ce que vous devez savoir sur l'opération de tri par fusion en Python et comment mettre en œuvre cet algorithme essentiel pour le tri de grandes bases de données.
Actualisé 27 févr. 2025  · 8 min de lecture

Le tri des données est l'une des opérations les plus courantes que les spécialistes des données effectuent dans leur travail quotidien. Nous avons souvent besoin d'afficher des données dans un certain ordre pour en extraire des informations significatives. Heureusement, de nos jours, il n'est plus nécessaire d'effectuer cette tâche manuellement. Les ordinateurs peuvent faire la magie à notre place avec des performances imbattables.

Il existe plusieurs stratégies pour trier les données. Dans ce tutoriel, nous analyserons l'une des techniques de tri les plus efficaces. L'algorithme "merge sort" utilise une stratégie de division et de conquête pour trier un tableau non trié en le divisant d'abord en tableaux plus petits, qui sont ensuite fusionnés dans le bon ordre. 

Dans les prochaines sections, nous aborderons tous les détails de l'algorithme de tri par fusion, son apparence en Python et quelques conseils pratiques pour une mise en œuvre sans heurts.

Qu'est-ce que le tri par fusion ?

Il existe de nombreux algorithmes de tri, mais il est difficile d'en trouver un qui soit plus performant que le tri par fusion. Sans surprise, cet algorithme est utilisé dans toutes sortes d'applications réelles, comme le tri de grandes bases de données ou l'organisation de fichiers sur un ordinateur ordinaire.

L'algorithme est basé sur le paradigme "diviser pour régner", qui peut être décomposé en trois parties :

  • Diviser: ce processus divise le problème en sous-problèmes plus petits. 
  • Conquérir: les sous-problèmes sont résolus de manière récursive. 
  • Combiner: les solutions des sous-problèmes sont combinées pour obtenir la solution finale.

Stratégie de division et de conquête

Stratégie de division et de conquête

Voyons comment fonctionne le tri par fusion. Supposons que nous voulions ordonner les nombres suivants en appliquant l'algorithme de tri par fusion. L'algorithme divise les données de manière récursive en deux parties et continue à les diviser jusqu'à ce que chaque liste ne contienne qu'un seul élément. Ensuite, nous les combinons en les triant dans une autre liste.

Problème de tri de fusion

Problème de tri de fusion. Source : DataCamp

Complexité temporelle et spatiale du tri par fusion

Il est impossible de savoir à l'avance quel est l'algorithme de tri qui fonctionne le mieux pour un problème donné. Au-delà de l'algorithme, plusieurs variables doivent être prises en compte, notamment le langage de programmation utilisé pour écrire le code, le matériel dans lequel il est exécuté et les particularités des données à trier. 

Bien qu'il soit impossible de prédire la durée d'exécution exacte d'un algorithme de tri, nous pouvons néanmoins comparer les performances de divers algorithmes de tri en analysant la complexité en termes de temps et d'espace.

Complexité temporelle du tri par fusion

Comme nous l'avons expliqué dans un autre guide sur la notation Big O et la complexité temporelle, l'objectif de l'analyse de la complexité temporelle n'est pas de prédire la durée d'exécution exacte d'un algorithme, mais plutôt d'évaluer l'efficacité d'un algorithme en analysant l'évolution de sa durée d'exécution à mesure que la quantité de données d'entrée augmente.

L'analyse de la complexité temporelle est écrite en notation Big O, une notation mathématique qui décrit la vitesse à laquelle une fonction croît ou décroît. Le tri par fusion a une complexité temporelle log-linéaire ou linéaire, notée O(N log(N)), où N est le nombre d'éléments de la liste. La lettre "O" représente l'"ordre" de croissance. 

Dans l'analyse de la complexité temporelle, la complexité linéaireithmique se comporte à peu près de la même manière que la complexité linéaire, ce qui signifie que son exécution sera directement proportionnelle à la quantité de données. Ainsi, si la quantité de données est doublée, le temps nécessaire à l'algorithme pour traiter les données devrait également doubler, c'est-à-dire que le nombre de divisions et de fusions sera doublé.

Comme la complexité temporelle du tri par fusion se comporte de manière linéaire, sa complexité reste la même dans le meilleur, le moyen et le pire des cas. Cela signifie que, quel que soit l'ordre des entrées, l'algorithme prendra toujours le même nombre d'étapes.

Complexité spatiale du tri par fusion

Enfin, outre le temps nécessaire pour terminer la tâche, un autre aspect important de l'analyse de la complexité d'un algorithme est l'estimation de la quantité de mémoire dont l'algorithme aura besoin au fur et à mesure que le problème prendra de l'ampleur. 

Ceci est couvert par les concepts de complexité de l'espace et d'espace auxiliaire. Ce dernier fait référence à l'espace supplémentaire ou temporaire utilisé par un algorithme, tandis que le premier fait référence à l'espace total pris par l'algorithme par rapport à la taille de l'entrée. En d'autres termes, la complexité de l'espace comprend à la fois l'espace auxiliaire et l'espace utilisé par l'entrée.

Le tri par fusion a une complexité spatiale de O(N). En effet, il utilise un tableau auxiliaire de taille N pour fusionner les moitiés triées du tableau d'entrée. Le tableau auxiliaire est utilisé pour stocker le résultat fusionné, et le tableau d'entrée est remplacé par le résultat trié.

Implémentation du tri par fusion en Python

Mettons en œuvre l'algorithme de tri par fusion en Python. Il existe plusieurs façons de coder l'algorithme, mais nous nous en tiendrons à celle basée sur la récursivité, qui est sans doute la plus facile à comprendre et qui nécessite moins de lignes de code que les autres alternatives basées sur l'itération.

Comprendre la récursivité dans le tri par fusion

Si vous êtes novice en la matière, sachez qu'en programmation, la récursivité se produit lorsqu'une fonction s'appelle elle-même. Vous pouvez consulter notre tutoriel Comprendre les fonctions récursives en Python pour tout savoir sur ces puissantes fonctions.

Pour mettre en œuvre le tri par fusion, nous définissons d'abord le cas de base: si la liste n'a qu'un seul élément, elle est déjà triée, et nous retournons donc immédiatement. Sinon, nous divisons la liste en deux moitiés, left_half et right_half, et appelons merge_sort() récursivement sur chacune d'entre elles. Ce processus se poursuit jusqu'à ce que toutes les sous-listes contiennent un seul élément.

Une fois ces sous-listes triées, nous entamons le processus de fusion. Pour ce faire, nous initialisons trois variables d'index : i pour le cursus de la position dans left_half, j pour right_half, et k pour la liste fusionnée finale. Nous comparons ensuite les éléments des deux moitiés. Si l'élément actuel de left_half est plus petit, nous le plaçons dans my_list[k] et faisons avancer i. Sinon, nous prenons l'élément de right_half, nous le plaçons dans my_list[k] et nous incrémentons j. Après chaque comparaison, nous faisons passer k à la position suivante dans la liste finale.

Ce processus se poursuit jusqu'à ce que nous ayons comparé tous les éléments de l'une des moitiés. S'il reste des éléments dans left_half ou right_half, nous les ajoutons directement à la liste finale, en veillant à ce qu'aucune donnée ne soit oubliée. Comme le tri par fusion fonctionne de manière récursive, ce processus de fusion est exécuté à chaque niveau de récursivité jusqu'à ce que la liste entière soit triée.

Mise en œuvre de Python

Vous trouverez ci-dessous le code utilisant comme exemple la liste non triée du diagramme précédent :

def merge_sort(my_list):
    if len(my_list) > 1: 
        mid = len(my_list)//2
        left_half = my_list[:mid]
        right_half = my_list[mid:]
       
        merge_sort(left_half)
        merge_sort(right_half)

        i = j = k = 0
 
        while i < len(left_half) and j < len(right_half):
            if left_half[i] < right_half[j]:
                my_list[k] = left_half[i]                
                i += 1
            else:
                my_list[k] = right_half[j]
                j += 1
            k += 1
     
        while i < len(left_half):
            my_list[k] = left_half[i]
            i += 1
            k += 1
 
        while j < len(right_half):
            my_list[k] = right_half[j]
            j += 1
            k += 1

my_list = [35,22,90,4,50,20,30,40,1]
merge_sort(my_list)
print(my_list)
>>> [1, 4, 20, 22, 30, 35, 40, 50, 90]

Tri par fusion et autres algorithmes de tri

Le tri par fusion est un algorithme de tri assez rapide, particulièrement adapté aux grandes bases de données, et il est souvent utilisé comme référence pour d'autres algorithmes. Toutefois, lorsqu'il s'agit de listes plus courtes, ses performances tendent à être inférieures à celles des autres algorithmes de tri.

Dans le tableau suivant, vous trouverez une comparaison du tri par fusion avec d'autres algorithmes de tri populaires.

 

Fusionner les tris

Tri rapide

Tri des bulles

Tri par insertion

Stratégie de tri

Diviser pour mieux régner

Diviser pour mieux régner

Intervertir à plusieurs reprises les éléments adjacents s'ils sont dans le mauvais ordre.

Construit la liste finale triée un élément à la fois par comparaisons. 

Stratégie de partition

Partition en deux moitiés

En fonction de la position de l'élément pivot

Ne nécessite pas de partitions

Ne nécessite pas de partitions

Complexité temporelle dans le pire des cas

O(N log N)

O(N^2)

O(N^2)

O(N^2)

Performance

Bon pour tout type de base de données, mais meilleur pour les bases de données plus importantes

Bon pour les petites bases de données

Bon pour les petits ensembles de données

Très bien pour une liste réduite et presque triée. Moins efficace que les autres algorithmes de tri

Stabilité

Stable

Pas stable

Stable

Stable

Espace nécessaire

Nécessite de la mémoire pour les sous-réseaux triés temporairement

Ne nécessite pas de mémoire supplémentaire

Ne nécessite pas de mémoire supplémentaire

Ne nécessite pas de mémoire supplémentaire

Applications pratiques du tri par fusion

Le tri par fusion est très performant lorsqu'il s'agit de trier de grandes listes, mais son efficacité diminue lorsqu'il s'agit de petites listes. De même, il tend à être moins efficace dans les scénarios où il existe déjà un certain degré ou ordre dans les listes d'entrée, car le tri par fusion effectue les mêmes étapes quel que soit l'ordre de la liste.

Les listes chaînées constituent un cas d'utilisation idéal où le tri par fusion s'avère particulièrement pratique. Une liste chaînée est une structure de données qui comprend une connexion de nœuds linéairement liés les uns aux autres. Chaque nœud contient les données et le lien qui le relie au nœud suivant.

Le tri par fusion est préféré pour les listes chaînées car il ne nécessite qu'un accès séquentiel aux données, ce qui correspond bien à la nature des listes chaînées. En outre, le tri par fusion est un algorithme de tri stable (c'est-à-dire qu'il préserve l'ordre relatif des éléments égaux dans la sortie triée), ce qui est très important pour maintenir l'ordre des listes chaînées.

Erreurs courantes et dépannage

L'algorithme de tri par fusion est assez simple et les possibilités d'amélioration du code sont limitées. Toutefois, vous pouvez accroître la complexité de votre stratégie de tri en tenant compte de la taille des données d'entrée. 

Nous avons déjà établi que le tri par fusion fonctionne mieux avec les grands ensembles de données. Pour les ensembles de données plus petits, d'autres algorithmes de tri ayant une complexité temporelle de O(N^2), comme le tri par insertion, donnent de meilleurs résultats. Dans ce cas, il vous suffit de créer un seuil de taille en dessous duquel vous utiliserez l'algorithme de tri par insertion au lieu de l'algorithme de fusion et de tri.

À part cela, une bonne idée à explorer serait la parallélisation. Les étapes du tri par fusion peuvent être facilement parallélisées avec la puissance de calcul adéquate, ce qui permet de réduire le temps d'exécution. Lisez notre guide CPU vs GPU pour en savoir plus sur l'informatique parallèle. 

Conclusion

Le tri par fusion est l'un des algorithmes de tri les plus efficaces et les plus populaires, mais il y a bien d'autres choses à apprendre dans l'univers merveilleux et toujours en expansion des algorithmes. Si vous vous intéressez aux aspects techniques des algorithmes, à leur fonctionnement et à la complexité, aux vertus et aux inconvénients qui leur sont associés, ces ressources de DataCamp peuvent vous aider à poursuivre votre apprentissage :


Javier Canales Luna's photo
Author
Javier Canales Luna
LinkedIn

Je suis analyste de données indépendant et je collabore avec des entreprises et des organisations du monde entier dans le cadre de projets de science des données. Je suis également formateur en science des données avec plus de 2 ans d'expérience. Je rédige régulièrement des articles sur les sciences des données en anglais et en espagnol, dont certains ont été publiés sur des sites web réputés tels que DataCamp, Towards Data Science et Analytics Vidhya En tant que scientifique des données ayant une formation en sciences politiques et en droit, mon objectif est de travailler à l'interaction des politiques publiques, du droit et de la technologie, en tirant parti du pouvoir des idées pour faire avancer des solutions et des récits innovants qui peuvent nous aider à relever des défis urgents, à savoir la crise climatique. Je me considère comme un autodidacte, un apprenant permanent et un fervent partisan de la pluridisciplinarité. Il n'est jamais trop tard pour apprendre de nouvelles choses.

Sujets

Les meilleurs cours de DataCamp

cursus

Python Data Fundamentals

28hrs hr
Grow your data skills, discover how to manipulate and visualize data, and apply advanced analytics to make data-driven decisions.
Afficher les détailsRight Arrow
Commencer le cours
Voir plusRight Arrow
Apparenté

blog

Les 20 meilleures questions d'entretien pour les flocons de neige, à tous les niveaux

Vous êtes actuellement à la recherche d'un emploi qui utilise Snowflake ? Préparez-vous à répondre à ces 20 questions d'entretien sur le flocon de neige pour décrocher le poste !
Nisha Arya Ahmed's photo

Nisha Arya Ahmed

20 min

blog

Q2 2023 DataCamp Donates Digest

DataCamp Donates a offert plus de 20k bourses d'études à nos partenaires à but non lucratif au deuxième trimestre 2023. Découvrez comment des apprenants défavorisés et assidus ont transformé ces opportunités en réussites professionnelles qui ont changé leur vie.
Nathaniel Taylor-Leach's photo

Nathaniel Taylor-Leach

blog

2022-2023 Rapport annuel DataCamp Classrooms

À l'aube de la nouvelle année scolaire, DataCamp Classrooms est plus motivé que jamais pour démocratiser l'apprentissage des données, avec plus de 7 650 nouveaux Classrooms ajoutés au cours des 12 derniers mois.
Nathaniel Taylor-Leach's photo

Nathaniel Taylor-Leach

8 min

blog

Nous avons fait don de bourses DataCamp Premium à un million de personnes, et ce n'est pas fini.

Réparties entre nos deux programmes d'impact social, DataCamp Classrooms et #DCDonates, les bourses offrent un accès illimité à tout ce que DataCamp Premium a à offrir.
Nathaniel Taylor-Leach's photo

Nathaniel Taylor-Leach

blog

Célébration de Saghar Hazinyar : Une boursière de DataCamp Donates et une diplômée de Code to Inspire

Découvrez le parcours inspirant de Saghar Hazinyar, diplômée de Code to Inspire, qui a surmonté les défis en Afghanistan et s'est épanouie grâce à une bourse de DataCamp Donates.
Fereshteh Forough's photo

Fereshteh Forough

4 min

Voir plusVoir plus