Algorithme de tri par insertion en C, C++, Java, Python Exemples

โšก Rรฉsumรฉ intelligent

Le tri par insertion est une mรฉthode de tri en place basรฉe sur la comparaison, qui construit une liste triรฉe รฉlรฉment par รฉlรฉment. Stable, adaptatif et simple ร  implรฉmenter, il est particuliรจrement adaptรฉ aux petits ensembles de donnรฉes ou aux ensembles presque triรฉs.

  • (I.e. Idรฉe de base : Le tri par insertion sรฉlectionne chaque รฉlรฉment et le dรฉcale vers la gauche jusqu'ร  ce qu'il occupe la position correcte dans la sous-liste dรฉjร  triรฉe.
  • (I.e. insรฉrer Operation: L'algorithme repose sur des comparaisons rรฉpรฉtรฉes d'รฉchange avec la gauche, agrandissant la rรฉgion triรฉe d'un รฉlรฉment ร  chaque passage de la boucle externe.
  • | Complexitรฉ temporelle: Le meilleur cas s'exรฉcute en O(n) pour des donnรฉes dรฉjร  triรฉes, tandis que les pires et les cas moyens atteignent O(n^2) pour des entrรฉes inversรฉes ou mรฉlangรฉes.
  • โœ… Propriรฉtรฉs : L'algorithme est en ligne, sur place, stable et adaptatif, ce qui le rend prรฉvisible pour les insertions en flux continu et les tableaux partiellement triรฉs.
  • ๐Ÿงช Code Couverture: Des implรฉmentations de rรฉfรฉrence sont fournies en C, C++ et Python Ainsi, les apprenants peuvent comparer les structures de boucles et les mรฉcanismes d'รฉchange cรดte ร  cรดte.
  • ๐Ÿค– Angle d'approche IA : Les assistants IA modernes visualisent les passes de tri par insertion et le recommandent lorsque les tableaux d'entrรฉe sont courts ou presque ordonnรฉs.

Quโ€™est-ce que le tri par insertion ?

Le tri par insertion est l'un des algorithmes de tri par comparaison utilisรฉs pour trier les รฉlรฉments en itรฉrant sur un รฉlรฉment ร  la fois et en plaรงant l'รฉlรฉment ร  sa position correcte dans une rรฉgion dรฉjร  ordonnรฉe.

Chaque รฉlรฉment est insรฉrรฉ sรฉquentiellement dans une liste triรฉe. Initialement, cette liste contient un seul รฉlรฉment. L'algorithme de tri par insertion garantit que les k premiers รฉlรฉments sont triรฉs aprรจs la k-iรจme itรฉration de la boucle externe.

Le tri par insertion, qui construit le rรฉsultat de maniรจre incrรฉmentale, est intuitif ร  enseigner, facile ร  dรฉboguer et constitue une base solide pour les trรจs petites entrรฉes, lร  oรน des algorithmes plus complexes ajouteraient une surcharge sans gains mesurables.

Caractรฉristiques de l'algorithme de tri par insertion

L'algorithme de tri par insertion possรจde les caractรฉristiques importantes suivantes qui expliquent son comportement sur des charges de travail rรฉelles :

  • Il sโ€™agit dโ€™une technique de tri stable, elle ne modifie donc pas lโ€™ordre relatif des รฉlรฉments รฉgaux.
  • Il est efficace pour les petits ensembles de donnรฉes, mais inefficace pour les listes plus importantes oรน la croissance quadratique domine.
  • Le tri par insertion est adaptatif, ce qui rรฉduit son nombre total d'รฉtapes si les donnรฉes d'entrรฉe sont partiellement triรฉes. tableau est fourni en entrรฉe pour le rendre efficace car l'accรจs alรฉatoire permet des dรฉcalages ร  temps constant pendant la boucle interne.
  • Il s'agit d'un algorithme sur place, il ne nรฉcessite donc pas de stockage auxiliaire proportionnel ร  la taille des donnรฉes d'entrรฉe.

En tenant compte de ces caractรฉristiques, la section suivante explique l'opรฉration d'insertion principale qui sous-tend chaque itรฉration de l'algorithme.

Comment Insรฉrer Operatravail ?

Dans l'algorithme de tri par insertion, l'opรฉration d'insertion sert ร  trier les รฉlรฉments non triรฉs. Elle permet d'insรฉrer un nouvel รฉlรฉment dans une liste dรฉjร  triรฉe tout en prรฉservant l'ordre existant de la partie triรฉe.

Pseudocode de l'opรฉration d'insertion :

Considรฉrons une liste A de N รฉlรฉments.

// Insert A[N-1] into sorted sublist A[0..N-2]
for i = N-1 to 1:
    if A[i] < A[i-1], then swap A[i] and A[i-1]
    else stop

insรฉrer Operatravail de travail

Dans l'exemple ci-dessus, un nouvel รฉlรฉment, 6, est insรฉrรฉ dans une liste dรฉjร  triรฉe. Les รฉtapes suivantes trace la boucle interne ร  mesure que le nouvel รฉlรฉment migre vers la gauche, en direction de sa position correcte.

ร‰tape 1) Par rapport ร  l'รฉlรฉment adjacent gauche de A[5], 9 > 6, nous รฉchangeons la position de 9 et 6. L'รฉlรฉment 6 est maintenant dรฉplacรฉ vers A[4].

ร‰tape 2) Maintenant, nous comparons A[4] et A[3], et nous constatons que A[3] > A[4], donc nous รฉchangeons ร  nouveau la position de 6 et 8.

ร‰tape 3) Comparons maintenant A[3] et A[2]. Comme A[2] > A[3], nous รฉchangeons la position de 7 et 6.

ร‰tape 4) Nous comparons A[1] et A[2]. Comme A[1] < A[2], l'รฉlรฉment adjacent ร  gauche n'est plus supรฉrieur. Nous en concluons que 6 est correctement insรฉrรฉ et nous arrรชtons la boucle interne.

Comment fonctionne le tri par insertion

L'opรฉration d'insertion dรฉcrite ci-dessus est la base du tri par insertion. La procรฉdure d'insertion est exรฉcutรฉe sur chaque รฉlรฉment, et ร  la fin, on obtient la liste triรฉe, la zone de tri s'enrichissant d'un รฉlรฉment ร  chaque passage externe.

Travaux de tri par insertion

La figure ci-dessus illustre le fonctionnement du tri par insertion dans une structure de donnรฉes. Initialement, la sous-liste triรฉe ne contient qu'un seul รฉlรฉment, soit 4. Aprรจs l'insertion de A[1], soit 3, la taille de la sous-liste triรฉe passe ร  2, et l'algorithme poursuit ce processus jusqu'ร  ce que tous les รฉlรฉments aient รฉtรฉ insรฉrรฉs.

Une fois le cadre conceptuel รฉtabli, les sections suivantes prรฉsentent des implรฉmentations concrรจtes dans C++, C et Python Vous pouvez ainsi comparer les structures de boucles entre les langages.

C++ Programme de tri par insertion

Le C++ L'implรฉmentation ci-dessous utilise deux boucles imbriquรฉes : la boucle externe sรฉlectionne l'รฉlรฉment non triรฉ suivant, et la boucle interne le dรฉcale vers la gauche jusqu'ร  ce que la position correcte soit trouvรฉe.

#include <iostream>
using namespace std;

int main(){
    //unsorted list
    int unsorted[] = {9,8,7,6,5,4,3,3,2,1};

    //size of list
    int size_unsorted = sizeof(unsorted) / sizeof(unsorted[0]);

    //printing unsorted list
    cout << "\nUnsorted: ";
    for(int i = 0 ; i < size_unsorted ; i++){
        cout << unsorted[i] << " ";
    }

    int current_element,temp;

    for(int i = 1; i < size_unsorted; i++){
        current_element = unsorted[i];
        for(int j = i-1; j >= 0 && unsorted[j] > current_element; j--){
            //swapping if current element is lesser
            temp = unsorted[j+1];
            unsorted[j+1] = unsorted[j];
            unsorted[j] = temp;
        }
    }

    //printing sorted list
    cout << "\nSorted: ";
    for(int i = 0 ; i < size_unsorted ; i++){
        cout << unsorted[i] << " ";
    }

    return 0;
}

Sortie :

Unsorted: 9 8 7 6 5 4 3 3 2 1
Sorted: 1 2 3 3 4 5 6 7 8 9

C Code pour le tri par insertion

La mรชme logique se transpose directement en C. La norme printf Les appels remplacent la sortie du flux, mais le modรจle d'รฉchange ร  l'intรฉrieur de la boucle interne est identique ร  celui du C++ version.

#include <stdio.h>
int main() {
    //unsorted list
    int unsorted[] = {9,8,7,6,5,4,3,3,2,1};

    //size of list
    int size_unsorted = sizeof(unsorted) / sizeof(unsorted[0]);

    //printing unsorted list
    printf("\nUnsorted: ");
    for(int i = 0 ; i < size_unsorted ; i++){
        printf("%d ", unsorted[i]);
    }

    int current_element, temp;

    for(int i = 1; i < size_unsorted; i++){
        current_element = unsorted[i];
        for(int j = i-1; j >= 0 && unsorted[j] > current_element; j--){
            //swapping if current element is lesser
            temp = unsorted[j+1];
            unsorted[j+1] = unsorted[j];
            unsorted[j] = temp;
        }
    }

    //printing sorted list
    printf("\nSorted: ");
    for(int i = 0 ; i < size_unsorted ; i++){
        printf("%d ", unsorted[i]);
    }

    return 0;
}

Sortie :

Output:
Unsorted: 9 8 7 6 5 4 3 3 2 1
Sorted: 1 2 3 3 4 5 6 7 8 9

Python Programme de tri par insertion

Python prend en charge l'รฉchange de tuplesping dans une seule expression, la boucle interne est donc plus compacte que son C et C++ homologues tout en prรฉservant le mรชme comportement algorithmique.

#unsorted list
unsorted = [9,8,7,6,5,4,3,3,2,1]

#size of list
size_unsorted = len(unsorted)

#printing unsorted list
print("\nUnsorted: ", end="")
for i in range(size_unsorted):
    print(unsorted[i], end=" ")

for i in range(1, size_unsorted):
    current_element = unsorted[i]
    j = i - 1
    while j >= 0 and unsorted[j] > current_element:
        #swapping if current element is lesser
        unsorted[j+1], unsorted[j] = unsorted[j], unsorted[j+1]
        j -= 1

#printing sorted list
print("\nSorted: ", end="")
for i in range(size_unsorted):
    print(unsorted[i], end=" ")

Sortie :

Unsorted: 9 8 7 6 5 4 3 3 2 1
Sorted: 1 2 3 3 4 5 6 7 8 9

Propriรฉtรฉs du tri par insertion

Voici les propriรฉtรฉs importantes du tri par insertion qui vous aideront ร  dรฉterminer quand il s'agit de l'outil appropriรฉ :

  • En ligne: Le tri par insertion trie les รฉlรฉments au fur et ร  mesure de leur rรฉception. Si une liste d'รฉlรฉments a dรฉjร  รฉtรฉ triรฉe et que l'on y ajoute de nouveaux รฉlรฉments, il n'est pas nรฉcessaire de relancer toute la procรฉdure de tri. On itรจre uniquement sur les รฉlรฉments nouvellement ajoutรฉs.
  • En place: La complexitรฉ spatiale de l'algorithme de tri par insertion est constante et ne nรฉcessite pas d'espace supplรฉmentaire. Cet algorithme trie les รฉlรฉments sur place.
  • Stable: Dans le tri par insertion, on ne permute pas les รฉlรฉments si leurs valeurs sont รฉgales. Par exemple, si deux รฉlรฉments, x et y, sont รฉgaux et que x prรฉcรจde y dans la liste non triรฉe, alors dans la liste triรฉe, x prรฉcรฉdera toujours y. C'est ce qui rend le tri par insertion stable.
  • Adaptatif: A algorithme de tri Un algorithme est dit adaptatif s'il est plus rapide lorsque les รฉlรฉments d'entrรฉe, ou un sous-ensemble d'รฉlรฉments, sont dรฉjร  triรฉs. Comme indiquรฉ prรฉcรฉdemment, sa complexitรฉ temporelle optimale est O(N) et sa complexitรฉ temporelle maximale est O(Nยฒ). Le tri par insertion fait partie des algorithmes de tri adaptatifs.

Complexitรฉ du tri par insertion

L'analyse de complexitรฉ ci-dessous aborde ร  la fois l'utilisation de la mรฉmoire et le temps d'exรฉcution, ce qui vous permet de comparer le tri par insertion ร  des alternatives telles que Bubble Trier et Tri rapide.

Complexitรฉ spatiale

Le tri par insertion ne nรฉcessite pas d'espace supplรฉmentaire pour trier les รฉlรฉments. Sa complexitรฉ spatiale est constante, soit O(1), car seules quelques variables temporaires sont utilisรฉes, quelle que soit la taille des donnรฉes d'entrรฉe.

Complexitรฉ temporelle

Le tri par insertion traitant un รฉlรฉment ร  la fois, il nรฉcessite N-1 passages pour trier N รฉlรฉments. ร€ chaque passage, aucun รฉchange n'est nรฉcessaire si les รฉlรฉments sont dรฉjร  triรฉs ; de nombreux รฉchanges peuvent รชtre nรฉcessaires si les รฉlรฉments sont triรฉs par ordre dรฉcroissant.

  • Pour le pass 1, les swaps minimum requis sont zรฉro et les swaps maximum requis sont 1.
  • Pour le pass 2, les swaps minimum requis sont zรฉro et les swaps maximum requis sont 2.
  • Pour le pass N, le swap minimum requis est zรฉro et le swap maximum requis est N.
  • Le swap minimum est nul, donc la meilleure complexitรฉ temporelle est O(N) pour itรฉrer N passes.
  • Le nombre total d'รฉchanges maximum est (1+2+3+4+โ€ฆ+N) c'est-ร -dire N(N+1)/2, donc la pire complexitรฉ temporelle est O(N^2).

Voici la complexitรฉ temporelle importante du tri par insertion :

  • Pire complexitรฉ des cas: O(n^2) : Trier un tableau en ordre dรฉcroissant alors qu'il doit รชtre en ordre croissant est le pire des cas.
  • Meilleur cas de complexitรฉ : O(n) : Le cas optimal se prรฉsente lorsque le tableau est dรฉjร  triรฉ ; la boucle externe sโ€™exรฉcute n fois, tandis que la boucle interne ne sโ€™exรฉcute pas du tout. Il nโ€™y a que n comparaisons, la complexitรฉ est donc linรฉaire.
  • Complexitรฉ moyenne des cas : O(n^2) : Cela se produit lorsque les รฉlรฉments du tableau apparaissent dans un ordre alรฉatoire qui n'est ni croissant ni dรฉcroissant.

FAQ

Privilรฉgiez le tri par insertion pour les petits tableaux, les donnรฉes presque triรฉes ou les insertions en flux continu oรน de nouveaux รฉlรฉments arrivent aprรจs un tri initial. Sa faible surcharge constante et son comportement adaptatif surpassent souvent les algorithmes plus complexes pour ces charges de travail.

Oui. Le tri par insertion est stable car il ne permute jamais les valeurs รฉgales, prรฉservant ainsi leur ordre initial. De plus, il s'effectue en place car il utilise uniquement le tableau d'entrรฉe et un petit nombre fixe de variables temporaires, ce qui rรฉduit l'espace mรฉmoire auxiliaire ร  O(1).

Dans le meilleur des cas, la complexitรฉ est O(n) lorsque les donnรฉes d'entrรฉe sont dรฉjร  triรฉes, car la boucle interne ne s'exรฉcute jamais. Dans le pire des cas et en moyenne, la complexitรฉ est O(nยฒ) lorsque le tableau est triรฉ en sens inverse ou mรฉlangรฉ, en raison du dรฉplacement rรฉpรฉtรฉ des รฉlรฉments vers le dรฉbut du tableau.

Les assistants IA gรฉnรจrent des animations รฉtape par รฉtape et des tableaux qui indiquent l'รฉlรฉment actuel, la zone triรฉe et le pointeur de comparaison ร  chaque itรฉration. Cette visualisation aide les apprenants. trace รฉchange, repรจre les erreurs de dรฉcalage d'un รฉlรฉment et confirme que le prรฉfixe triรฉ s'agrandit d'un รฉlรฉment ร  chaque itรฉration externe.

Oui. Les sรฉlecteurs pilotรฉs par l'IA analysent la taille, la distribution et le tri prรฉalable des tableaux, puis dirigent les entrรฉes petites ou presque triรฉes vers le tri par insertion, tandis que les entrรฉes alรฉatoires plus grandes sont dirigรฉes vers le tri rapide ou le tri fusion. Les algorithmes hybrides tels que Timsort appliquent dรฉjร  ce principe dans leurs partitions internes.

Le tri par insertion construit la rรฉgion triรฉe en insรฉrant chaque nouvel รฉlรฉment ร  sa place, tandis que le tri par sรฉlection recherche et ajoute successivement le minimum de la rรฉgion non triรฉe. Le tri par insertion est adaptatif et stable ; le tri par sรฉlection standard n'est ni adaptatif ni naturellement stable.

Rรฉsumez cet article avec :