Tri par tas

Si ce bandeau n'est plus pertinent, retirez-le. Cliquez ici pour en savoir plus.
Si ce bandeau n'est plus pertinent, retirez-le. Cliquez ici pour en savoir plus.

Cet article ne cite pas suffisamment ses sources ().

Si vous disposez d'ouvrages ou d'articles de référence ou si vous connaissez des sites web de qualité traitant du thème abordé ici, merci de compléter l'article en donnant les références utiles à sa vérifiabilité et en les liant à la section « Notes et références ».

En pratique : Quelles sources sont attendues ? Comment ajouter mes sources ?

Tri par tas
Une exécution de l'algorithme du tri par tas (Heapsort) trie une partie des valeurs permutées au hasard. Dans un premier temps, les éléments sont réarrangés pour respecter les conditions de tas. Avant le tri à proprement parler, la structure de l'arbre en tas est montrée brièvement par l'illustration.
Découvreur ou inventeur
J. W. J. Williams (en)Voir et modifier les données sur Wikidata
Date de découverte
Voir et modifier les données sur Wikidata
Problème lié
Algorithme de triVoir et modifier les données sur Wikidata
Structure des données
TableauVoir et modifier les données sur Wikidata
À l'origine de
SmoothsortVoir et modifier les données sur Wikidata
Complexité en temps
Pire cas
O ( n log ( n ) ) {\displaystyle O(n\log(n))} Voir et modifier les données sur Wikidata
Moyenne
O ( n log ( n ) ) {\displaystyle O(n\log(n))} Voir et modifier les données sur Wikidata
Meilleur cas
O ( n log ( n ) ) {\displaystyle O(n\log(n))} Voir et modifier les données sur Wikidata
Complexité en espace
Pire cas
O ( 1 ) {\displaystyle O(1)} Voir et modifier les données sur Wikidata

modifier - modifier le code - modifier WikidataDocumentation du modèle

Animation montrant le fonctionnement du tri par tas (Heapsort).

En informatique, le tri par tas est un algorithme de tri par comparaisons. Cet algorithme est de complexité asymptotiquement optimale, c'est-à-dire que l'on démontre qu'aucun algorithme de tri par comparaison ne peut avoir de complexité asymptotiquement meilleure. Sa complexité est proportionnelle à n log n {\displaystyle n\log n} n {\displaystyle n} est la longueur du tableau à trier. Le tri par tas se fait en place, c’est-à-dire qu’il ne nécessite pas l'allocation d'une zone mémoire supplémentaire (plus précisément il ne nécessite qu'une allocation d'une zone mémoire de taille O ( 1 ) {\displaystyle O(1)} ). Par contre, il n'est pas stable.

Son inconvénient majeur est sa lenteur comparé au tri rapide (qui est en moyenne deux fois plus rapide[réf. nécessaire]) : sur un tableau de taille importante, il sera amené à traiter un nombre élevé d'emplacements mémoire dont l’éloignement peut dépasser la capacité du cache, ce qui ralentit l'accès à la mémoire et l’exécution de l’algorithme.

Principe

L'idée qui sous-tend cet algorithme consiste à voir le tableau comme un arbre binaire. Le premier élément est la racine, le deuxième et le troisième sont les deux descendants du premier élément, etc. Ainsi le n {\displaystyle n} e élément a pour enfants les éléments 2 n {\displaystyle 2n} et 2 n + 1 {\displaystyle 2n+1} si l'indexation se fait à partir de 1 ( 2 n + 1 {\displaystyle 2n+1} et 2 n + 2 {\displaystyle 2n+2} si l'indexation se fait à partir de 0). Si le tableau n'est pas de taille ( 2 n 1 ) {\displaystyle (2^{n}-1)} , les branches ne se finissent pas toutes à la même profondeur.

Dans l'algorithme, on cherche à obtenir un tas, c'est-à-dire un arbre binaire vérifiant les propriétés suivantes (les deux premières propriétés découlent de la manière dont on considère les éléments du tableau) :

  • la différence maximale de profondeur entre deux feuilles est de 1 (i.e. toutes les feuilles se trouvent sur la dernière ou sur l'avant-dernière ligne) ;
  • les feuilles de profondeur maximale sont « tassées » sur la gauche.
  • chaque nœud est de valeur supérieure (resp. inférieure) à celles de ses deux fils, pour un tri ascendant (resp. descendant).

Il en découle que la racine du tas (le premier élément) contient la valeur maximale (resp. minimale) de l'arbre. Le tri est fondé sur cette propriété.

Comme expliqué plus haut, un tas ou un arbre binaire presque complet peut être stocké dans un tableau, en posant que les deux descendants de l'élément d'indice n {\displaystyle n} sont les éléments d'indices 2 n {\displaystyle 2n} et 2 n + 1 {\displaystyle 2n+1} (pour un tableau indicé à partir de 1). En d'autres termes, les nœuds de l'arbre sont placés dans le tableau ligne par ligne, chaque ligne étant décrite de gauche à droite. Pour la suite, nous considérons que l'on trie par ordre croissant.

L'opération de base de ce tri est le tamisage, ou percolation, d'un élément, supposé le seul « mal placé » dans un arbre qui est presque un tas. Plus précisément, considérons un arbre A = A [ 1 ] {\displaystyle A=A[1]} dont les deux sous-arbres ( A [ 2 ] {\displaystyle A[2]} et A [ 3 ] {\displaystyle A[3]} ) sont des tas, tandis que la racine est éventuellement plus petite que ses fils. L'opération de tamisage consiste à échanger la racine avec le plus grand de ses fils, et ainsi de suite récursivement jusqu'à ce qu'elle soit à sa place. Pour construire un tas à partir d'un arbre quelconque, on tamise les racines de chaque sous-tas, de bas en haut et de droite à gauche. On commence donc par les sous-arbres « élémentaires » — contenant deux ou trois nœuds, donc situés en bas de l'arbre. La racine de ce tas est donc la valeur maximale du tableau. Puis on échange la racine avec le dernier élément du tableau, et on restreint le tas en ne touchant plus au dernier élément, c'est-à-dire à l'ancienne racine ; on a donc ainsi placé la valeur la plus haute en fin de tableau (donc à sa place), et l'on n'y touche plus. Puis on tamise la racine pour créer de nouveau un tas, et on répète l'opération sur le tas restreint jusqu'à l'avoir vidé et remplacé par un tableau trié.

Pseudo-code

Application de l'algorithme.

On fait l'hypothèse que l'arbre est un tableau indexé entre 1 et longueur. arbre[i] désigne le i-ème élément de ce tableau.


 fonction tamiser(arbre, nœud, n) :
   (* descend arbre[nœud] à sa place, sans dépasser l'indice n *)
   k := nœud
   j := 2k
   tant que j ≤ n
      si j < n et arbre[j] < arbre[j+1]
         j := j+1
      fin si
      si arbre[k] < arbre[j]
         échanger arbre[k] et arbre[j]
         k := j
         j := 2k
      sinon
         j := n+1
      fin si
   fin tant que
fin fonction

fonction triParTas(arbre, longueur) :
   pour i := longueur/2 à 1
       tamiser(arbre, i, longueur)
   fin pour
   pour i := longueur à 2
       échanger arbre[i] et arbre[1]
       tamiser(arbre, 1, i-1)
   fin pour
fin fonction

À la fin de la fonction triParTas le tableau arbre est trié suivant l'ordre croissant. Il suffit d'inverser les opérateurs de comparaison pour obtenir un tri dans l'ordre décroissant.

Analyse

Cet algorithme permet de trier sur place les éléments d'un tableau en un temps de l'ordre de n log n {\displaystyle n\log n} , où n {\displaystyle n} est le nombre d'éléments à trier. La complexité entre le meilleur des cas et le pire des cas ne varie que d'un facteur constant[1]. L'étape la plus coûteuse de l'algorithme est la seconde boucle, c'est-à-dire l'extraction des éléments du tas. La première étape, consistant à construire le tas, est effectuée en temps linéaire en n.

Les principaux atouts de cette méthode sont la faible consommation mémoire et l'efficacité, optimale étant donné qu'on ne fait aucune hypothèse sur la nature des données à trier.

Amélioration possible

  • Quand le tableau est déjà trié, le tri par tas le mélange d'abord avant de le retrier. L'algorithme Smoothsort a pour but de pallier cet inconvénient.
  • À la fin du tri par tas, pour les 15 derniers éléments environ, l'algorithme effectue plusieurs fois de suite les mêmes inversions, ce qui est inutile. On peut à la place arrêter l'algorithme quand il n'y a plus beaucoup d'éléments et passer à un autre. Les données qui restent sont à peu près triées à l'envers. On peut donc, par exemple, retourner les données restantes (avec une inversion du 1er et du dernier, du 2e et de l'avant-dernier etc.) puis effectuer un tri par insertion.

Liens externes

  • (en) Illustration dynamique du tri par tas

Notes et références

Sur les autres projets Wikimedia :

  • Implémentations du tri par tas, sur Wikibooks
  1. The Analysis of Heapsort, Schaffer R. and Sedgewick R., 2002.
v · m
Algorithmes de tri
Tris par comparaisons
Sans hypothèse autre
Complexité moyenne O ( n log n ) {\displaystyle {\mathcal {O}}(n\log n)}
Complexité moyenne O ( n 2 ) {\displaystyle {\mathcal {O}}(n^{2})}
Complexité moyenne moins bonne que O ( n 2 ) {\displaystyle {\mathcal {O}}(n^{2})}
Avec hypothèse supplémentaire
Réseau de tri
Tri utilisant d'autres opérations
Applications
  • icône décorative Portail de l'informatique théorique