Algorithme de tri.

Pourquoi trier ?

Déjà avoir des données dans l'ordre croissant ou décroissant est un plus pour l'utilisateur, il est intéressant de savoir qui est en tête de classe par exemple.

Même sans chercher les extrêmes, quand des données sont triées la recherche d'un élément est très rapide à l'aide de la recherche dichotomique (on rappelle que le coût pour trouver un élément dans n données est de l'ordre de ln(n) pour des données triées contre n pour des données non triées). Imaginez un dictionnaire où les mots sont rangés de manière aléatoire !
Pour revenir sur la vitesse de l'algorithme dichotomique : si chercher une donnée dans un tableau de taille 1000 se fait en une seconde, alors chercher une donnée dans un tableau de taille 1000000 se fait en 1000 s si l'algorithme de recherche est naïf et en 2s avec l'algorithme dichotomique !

Un grand nombre d'algorithmes.

Il existe un grand nombre d'algorithmes de tri (et on en cherche encore), car souvent les problématiques peuvent légèrement différées :

Le programme propose deux algortihmes de tri, ils ne sont pas efficaces pour des grandes valeurs mais sont classiques et simples à comprendre.

Tri par sélection.

Le principe de la méthode est le suivant : on trouve le plus grand nombre puis on le met à la fin puis le deuxième plus grand que l'on met en avant dernière position et ainsi de suite.


Algo

		

On peut aussi rechercher l'elèment minimal, comme sur l'animation de wikipédia suivante :

Sélection-Sort-Animation.gif
Par Joestape89, CC BY-SA 3.0, Lien

proposition

La complexité en comparaisons d'un tableau de taille n est de \((n-1) + (n-2) + ... + 2 + 1 = \frac{n(n-1)}{2} = \Theta(n²) \). Donc trier un tableau dix fois plus grand prendra 100 fois plus de comparaisons.

Le nombre d'échange est au maximum de n-1 (rangé dans l'ordre inverse) au minimum nul (rangé).

Tri par insertion.

Le tri par insertion prend le principe du tri du joueur de carte, on prend une carte puis la suivante et on l'insert (c'est à dire on la met à sa place), puis la suivante et on l'insert,... ainsi de suite jusqu'à la derniére.

Le tri par insertion est très efficace pour des petits tableaux.

Algo

		
proposition

La complexité en comparaisons d'un tableau de taille n est au pire de \((n-1) + (n-2) + ... + 2 + 1 = \frac{n(n-1)}{2} = \Theta(n²) \).Au minimum il est de n-1.

Le nombre d'échanges est au pire de \((n-1) + (n-2) + ... + 2 + 1 = \frac{n(n-1)}{2} = \Theta(n²) \) au minimum il est nul.

Il existe une meilleure implémentation de l'algorithme qui fait gagner des échanges (grosso modo une division par 2 ce qui ne change pas le theta de complexité) mais pas des comparaisons, celle qui est dans l'épreuve pratique :


 def tri_insertion(L):
	n = len(L)
	# cas du tableau vide
	if n == 0 :
		return L
	for j in range(1,n):
		e = L[j]
		i = j
		# A l'étape j, le sous-tableau L[0,j-1] est trié
		# et on insère L[j] dans ce sous-tableau en déterminant3 / 3
		# le plus petit i tel que 0 <= i <= j et L[i-1] > L[j].
		while i > 0 and L[i-1] > e :
			i = i - 1
		# si i != j, on décale le sous tableau L[i,j-1] d’un cran
		# vers la droite et on place L[j] en position i
		if i != j:
			for k in range(j,i,-1):
				L[k] = L[k-1]
			L[i] = e
	return L
		
		
		
		
		

Regardons le déroulement sur un exemple :


Lnejik
4271563
?????

	n = len(L)

		
		
		
		

n contient la longueur du tableau.

Tri par bulles.

Le tri par bulle est très simple et rapide à programmer. Pour des petits tableaux (taille 4 ou 5) il est acceptable.

Algo

		
proposition

La complexité en comparaisons (sans compter la validation de l'indice) d'un tableau de taille n est de \((n-1) + (n-2) + ... + 2 + 1 = \frac{n(n-1)}{2} = \Theta(n²)\).

Le nombre d'échanges est au pire de \((n-1) + (n-2) + ... + 2 + 1 = \frac{n(n-1)}{2} = \Theta(n²) \) au minimum il est nul.

Dans des cas particuliers : Tri casier.

Si on veut classer des nombres sur un ensemble fini est limité (par exemple des notes sur 10) alors il existe un tri casier (ou comptage) qui le fait en \(\Theta(n) \).Il n'y a pas de contradiction avec le fait que les meilleurs tris par comparaisons sont en nln(n) car le tri casier n'est pas un tri par comparaisons !

503710976528910 20108654632310

012345678910
00000000000

Les tris de python.

Python offre la possibilité de classer des tableaux de deux manières différentes (et avec des performances meilleures sur des grands tableaux).

Cependant Les tris par insertion et sélection sont au programme, alors habituez vous à les utiliser !



		

La fonction sorted retourne une nouvelle liste triée, la liste d'origine n'est pas modifiée.

Sorted classe des nombres, des chaines de caractères et des tableaux.

Si on veut classer selon les prénoms (ou selon d'autre critères) il faut lui indiquer clairement. De même on peut indiquer croissant ou décroissant.



Le tri utilisé par Python est stable ce qui est très pratique, par exemple si on veut classer selon les notes puis selon les noms. :



Enfin python permet de trier directement le tableau lui même sans créer un autre tableau (avec les mêmes options que sorted) :





		
		

Exercices.

Q.C.M.

Le tri par sélection d'un tableau de taille n est en :





Q.C.M.

En moyenne, par rapport à un tableau de taille n, le tri par insertion d'un tableau de taille 2n mettra combien de fois plus de temps.





Q.C.M.

On a le tableau suivant [2,1,7,6,3] le tri par sélection va transformer le tableau successivement en :





Q.C.M.

Il faut combien de changement du tableau pour trier le tableau [5,1,3,4] avec le tri par insertion ? (si une etape ne change pas le tableau il ne faut pas la compter).





Q.C.M.

La limite théorique de la complexité du tri par un algorithme par comparaison par rapport à la taille d'un tableau est :.





Q.C.M.

Il faut combien de comparaison pour trier [2,1,5,4] par insertion ?






Exercices
  1. Classer (par ordre alphabétique croissant) le tableaux suivants :
    • ["Arbre","Fleur","Ammande","Figue","Fleuriste"]
    • [8,5,6,1,3]
    • ["11","103","5","19"]
  2. Faire une fonction qui teste si un tableau est trié (elle retourne True si le tableau est trié par exemple), donner son ordre de complexité par rapport à la longueur du tableau.
  3. Donner les changements successifs du tableau suivant [3,2,1,5,8,7] par la méthode du tri par sélection.
  4. Donner les changements successifs du tableau suivant [3,2,1,5,8,7] par la méthode du tri par insertion.
  5. Donner les changements successifs du tableau suivant [3,2,1,5,8,7] par la méthode du tri par bulles.
  6. Il faut combien de comparaisons pour trier le tableau [4,1,5,3] par sélection ?
  7. Il faut combien de comparaisons pour trier le tableau [4,1,5,3] par sélection ?
  8. On dit qu'un algorithme est stable s'il conserve l'ordre des élèments égaux, par exemple si on ordonne [[2,1],[1,0],[2,2],[3,0],[2,0]] selon le premier élèments de chaque liste un tri stable doit donner [[1,0],[2,1],[2,2],[2,0],[3,0]] ([2,1] était avant [2,0] au début il doit le rester après le tri) un tri instable peut donner [[1,0],[2,2],[2,0],[2,1],[3,0]]. Dire si les algorithmes de tri du chapitre sont stables.
  9. On donne le tableau de coordonnées suivants [[1,2],[1,4],[2,0],[3,-5],[1,2]] :
    1. Écrire un algorithme de tri par sélection pour le classer par ordre croissant des ordonnées.
    2. Écrire un algorithme de tri par insertion pour le classer par ordre croissant des ordonnées.
    3. Utiliser les tris intégrés à python pour le classer par ordre croissant des ordonnées.
  10. Au lieu de donner les coordonnées des points comme l'exercice précédent on les donne sous la forme suivante : [[1,1,2,3,1],[2,4,0,-5,2]] (premiére ligne comporte les abscisses et deuxiéme les ordonnées. Faire un algorithme qui permet de trier selon l'ordonnées.
  11. Epreuve pratique : compléter et jouter des fonctions de test :
    
    		
    
    		
    
    		

Un lien vers d'autres algorithmes de tri.