Quelques algorithmes de tri

publicité
Préparation à l’agrégation 2009/2010
Algèbre et Calcul Formel
Quelques algorithmes de tri
1
Structure de données
On choisit le type list (> ?list ;) pour représenter les listes à trier.
Exercice 1 Écrire une procédure swap qui prend en entrée une liste 𝑙, deux entiers 𝑖
et 𝑗, et renvoie 𝑙 où 𝑙[𝑖] et 𝑙[𝑗] ont été échangés (on suppose que la taille 𝑛 de 𝑙 est telle
que 𝑛 ≥ max (𝑖, 𝑗)).
Exercice 2 Utiliser RandomTools[Generate] pour générer des listes d’entiers
choisis aléatoirement entre 1 et 1 000 de tailles variées.
2
Tris en vrac
Pour chacun des algorithmes de tri présentés ci-dessous, on demande de calculer :
1. sa complexité dans le meilleur cas
2. sa complexité dans le pire cas
3. une implémentation de l’algorithme en Maple.
2.1
Tri à bulles
On parcourt la liste à trier. Chaque fois que deux éléments consécutifs sont dans
le désordre, on les inverse et on continue le parcours de la liste. On répète ce parcours
tant que la liste n’est pas triée. Notez qu’à la fin du 𝑖-ème parcours, 𝐿[(𝑛 − 𝑖 + 1)..𝑛]
est triée et contient les 𝑖 plus grands éléments de la liste.
2.2
Tri par insertion
C’est le tri du joueur de carte : à chaque élément qui n’est pas à sa place dans la
liste, on parcours la liste qui le précède dont on décale les éléments d’une case vers la
droite chacun jusqu’à en trouver un qui est plus petit que l’élément que l’on traite. On
insère alors celui-ci à l’emplacement laissé libre dans le tableau.
2.3
Tri fusion
Cet algorithme utilise le paradigme « diviser pour régner » : pour trier une liste 𝐿
de taille 𝑛, on trie d’abord 𝐿[1..𝑛/2 − 1], 𝐿[𝑛/2..𝑛], puis on fusionne les deux listes
triées. Pour faciliter l’implémentation de cette dernière procédure, on pourra rajouter
une valeur +∞, dite « sentinelle » à la fin de chaque liste.
On peut montrer que la complexité asymptotique de cet algorithme est optimale.
Pour cela, on considère la structure d’arbre de décision, qui va nous permettre d’estimer le nombre de comparaisons qu’un algorithme de tri doit effectuer pour trier une
liste, et ainsi fournir une borne inférieure pour celui-ci.
C. Picaronny & J. Villard
1
E.N.S. de Cachan
Préparation à l’agrégation 2009/2010
Algèbre et Calcul Formel
Définition 1 Un arbre de décision est un arbre binaire complet dont chaque nœud est
étiqueté par une comparaison 𝑎𝑖 : 𝑎𝑗 entre deux éléments de la liste (on suppose la
liste composée d’éléments tous distincts), et dont les feuilles correspondent aux permutations de la liste de départ.
Un algorithme de tri devant être capable de produire toutes les permutations de son
entrée, le nombre de feuilles d’un tel arbre doit être au moins 𝑛!. Le temps d’exécution
dans le cas le plus défavorable correspond à la hauteur de l’arbre, c’est-à-dire au plus
long chemin de la racine à une feuille. On en déduit le théorème suivant :
Théorème 1 Un algorithme de tri par comparaison nécessite au moins 𝑂(𝑛 lg 𝑛) comparaisons dans le pire cas.
2.4
Tri rapide
Pour le tri rapide, on choisit un élément dans la liste qui va servir de pivot : on
le place alors à sa place définitive en mettant tous les éléments de la liste qui lui sont
inférieurs avant lui. On rappelle ensuite la procédure récursivement sur les deux souslistes obtenues.
C’est le tri le plus utilisé en pratique ; pourquoi ?
3
Tri par tas
Le tri par tas est un des algorithmes de tri les plus efficaces asymptotiquement,
puisqu’il est agit à la fois en place et en temps optimal. Pour cela, il faut avoir recours
à la structure de tas.
Définition 2 Un tas est un arbre binaire presque complet, c’est-à-dire dont tous les
niveaux sont remplis, à l’exception éventuelle du dernier qui se rempli de gauche à
droite.
Un tas-max est un tas dont chaque nœud a une valeur inférieure à celle de son
parent.
Il est facile de représenter un tas par un tableau en rangeant les éléments par profondeurs successives, car le calcul des positions du parent et des deux fils d’un nœud à
la position 𝑖 dans le tableau correspondent respectivement à ⌊𝑖/2⌋, 2𝑖 et 2𝑖 + 1.
Exercice 3 On suppose donné un tas max sous forme d’une liste 𝐿. Écrire une procédure Entasser(L,a) qui insère 𝑎 dans 𝐿 en préservant la structure de tas max.
Montrer que la complexité de votre procédure est en 𝑂(lg ∣𝐿∣).
Exercice 4 Donner une procédure pour transformer en place une liste en tas max.
Exercice 5 En déduire l’algorithme du tri par tas et montrer que sa complexité est en
𝑂(𝑛 lg 𝑛).
Bonus Refaire le TD en utilisant le type Array à la place du type list. On pourra
écrire des fonctions size, elements, . . . pour s’abstraire de nops, op, . . .
C. Picaronny & J. Villard
2
E.N.S. de Cachan
Téléchargement