La présentation est en train de télécharger. S'il vous plaît, attendez

La présentation est en train de télécharger. S'il vous plaît, attendez

Cours 4 : Tris de Tableaux

Présentations similaires


Présentation au sujet: "Cours 4 : Tris de Tableaux"— Transcription de la présentation:

1 Cours 4 : Tris de Tableaux

2 1. INTRODUCTION 2. LES METHODES « SIMPLES » 2.1. Tri par sélection 2.2. Tri à bulles (Bubble sort) 2.3. Tri par insertion 3. LE TRI RAPIDE « QUICK SORT » 4. LE TRI FUSION LE TRI TAS … ARBRE DE HUFFMAN SYNTHESE

3 1. Introduction  , Un algorithme de tri permet d'organiser une collection d'objets selon un ordre déterminé.  faciliter les recherches ultérieures d’un élément dans une liste (recherche dichotomique) de valeurs numériques = tableau à une dimension. Programme : tri par insertion, du tri rapide et du tri fusion. Pour trier des chaînes de caractères (mots), il suffit d’associer une valeur numérique à chaque caractère (code ASCII par exemple). La plupart des algorithmes de tri sont fondés sur des comparaisons successives  la complexité de l’algorithme a le même ordre de grandeur que le nombre de comparaisons entre les données faites par l’algorithme.

4 2. Les méthodes « simples »
, 2. Les méthodes « simples »  2.1. Tri par sélection On recherche le plus grand élément que l'on va replacer à sa position finale, c'est-à-dire en dernière position. Puis on recherche le second plus grand élément que l'on va placer en avant-dernière position, etc., jusqu'à ce que le tableau soit entièrement trié. Données : tableau T entre les indices 1 et n. PYTHO N def echange(l,i,j): # echange 2 valeurs d'une liste l[i],l[j] = l[j], l[i] def tri_selection(l):

5 2. Les méthodes « simples »
, 2. Les méthodes « simples »  2.1. Tri par sélection On recherche le plus grand élément que l'on va replacer à sa position finale, c'est-à-dire en dernière position. Puis on recherche le second plus grand élément que l'on va placer en avant-dernière position, etc., jusqu'à ce que le tableau soit entièrement trié. PYTHO N def echange(l,i,j): # echange 2 valeurs d'une liste l[i],l[j] = l[j], l[i] def tri_selection(l): for i in range(len(l)-1): mini=i for j in range(i+1,len(l)): if l[j]<l[mini]: mini=j echange(l,i,mini)

6 2. Les méthodes « simples »
, 2.1. Tri par sélection Complexité Meilleur des cas : O(n2 ) quand le tableau est déjà trié. Pire cas : O(n2 ) quand le tableau est trié en ordre inverse. En moyenne : O(n2 ) Ce n’est donc pas un tri très efficace, mais en revanche c’est un tri très simple.

7 2. Les méthodes « simples »
, 2. Les méthodes « simples »  2.2. Tri bulles L'algorithme parcourt la liste, et compare les couples d'éléments successifs Lorsque deux éléments successifs ne sont pas dans l’ordre croissant, ils sont échangés. On fait ainsi remonter le terme le plus petit (les bulles les plus légéres remontent le plus vite à la surface ...). PYTHO N def echange(l,i,j): # echange 2 valeurs d'une liste l[i],l[j] = l[j], l[i] def tri_abulles(l):

8 2. Les méthodes « simples »
, 2. Les méthodes « simples »  2.2. Tri bulles L'algorithme parcourt la liste, et compare les couples d'éléments successifs en commençant par la fin de la liste Lorsque deux éléments successifs ne sont pas dans l’ordre croissant, ils sont échangés. On fait ainsi remonter le terme le plus petit (les bulles les plus légéres remontent le plus vite à la surface ...). PYTHO N def echange(l,i,j): # echange 2 valeurs d'une liste l[i],l[j] = l[j], l[i] def tri_abulles(l):

9 2. Les méthodes « simples »
, 2. Les méthodes « simples »  2.2. Tri bulles L'algorithme parcourt la liste, et compare les couples d'éléments successifs. Lorsque deux éléments successifs ne sont pas dans l'ordre croissant, ils sont échangés. PYTHO N def echange(l,i,j): # echange 2 valeurs d'une liste l[i],l[j] = l[j], l[i] def tri_abulles(l): for i in range(len(l)): for j in reversed(range(i,len(l))) : #range(len(l)-1,i-1,-1) if l[j]<l[j-1]: echange(l,j-1,j)

10 2. Les méthodes « simples »
, 2.2. Tri bulles Cet algorithme est souvent enseigné en tant qu'exemple algorithmique.  complexité en O(n2 ) dans le pire des cas (où n est la longueur de la liste),  parmi les mauvais algorithmes de tri. Il n'est donc quasiment pas utilisé en pratique Complexité Meilleur cas : O(n) quand le tableau est trié. Il ne fait que n comparaisons pour n valeurs à trier (en réalité, pour des raisons d'intervalles, il n'en fait que n-1). Pire des cas : O(n2 ) quand le tableau est trié en ordre inverse (n−1)·(n−1) = O(n²)

11 2. Les méthodes « simples »
, 2.3. Tri par insertion Soit un paquet de « n » cartes. On prend la première dans une main. On saisie la seconde carte et on l’insère avant ou après la première selon le cas. A l’étape « i », la ième carte est insérée à sa place dans le paquet déjà trié. Pour cela, on peut : méthode 1 : partir du début du tas déjà trié et s’arrêter lorsque l’on rencontre une carte plus grande que la ième , méthode 2 : partir de la fin du tas déjà trié, et s’arrêter si l’on rencontre une carte plus petite que la ième. Le paquet contient alors « i » cartes triées. On procède ainsi de suite jusqu’à la dernière carte.

12 2. Les méthodes « simples »
, 2.3. Tri par insertion

13 2. Les méthodes « simples »
, 2. Les méthodes « simples »  2.3. Tri par insertion Algorithme : Tri par insertion (fonction Tri_insertion) Données : T : un tableau de valeurs num [1..n] ; Résultat : le tableau T trié par ordre croissant PYTHO N def Tri_insertion( ) :

14 2. Les méthodes « simples »
, 2. Les méthodes « simples »  2.3. Tri par insertion Algorithme : Tri par insertion (fonction Tri_insertion) Données : T : un tableau de valeurs num [1..n] ; Résultat : le tableau T trié par ordre croissant PYTHO N def Tri_insertion( L ) : for i in range(1,len(L)): x=L[i] j=0 while j<=i-1 and L[j]<x: j=j+1 for k in range(i-1, j-1,-1): #on echange les positions L[k+1]=L[k] L[j]=x return L

15 2. Les méthodes « simples »
, 2. Les méthodes « simples »  2.3. Tri par insertion Complexité : Meilleur des cas : le tableau est déjà trié. Il y a donc n – 1 comparaisons à effectuer. La complexité est donc de classe linéaire : C(n)=O(n). Dans le pire des cas, le tableau est trié à l’envers. Il y a alors une comparaison à effectuer à la première étape, puis deux, … puis n-1. On en déduit donc un nombre total de comparaisons. La complexité est donc de classe quadratique : C(n)=O(n2).

16 2. Les méthodes « simples »
, 2. Les méthodes « simples »  2.3. Tri par insertion Algorithme : Tri par insertion méthode2 (Tri_inser2) Données : T : un tableau de valeurs num [1..n] ; Résultat : le tableau T trié par ordre croissant PYTHO N def Tri_inser2( L ) : for i in range(1,len(L)): x=L[i] j=i while j>0 and L[j-1]>x: L[j]=L[j-1] j=j-1 L[j]=x return L

17 2. Les méthodes « simples »
, 2.3. Tri par insertion On peut aussi montrer que la complexité en moyenne est de classe quadratique lorsque les permutations sont équiprobables. L’efficacité du tri par insertion est excellente lorsque le tableau est déjà trié ou « presque trié » (C(n)=O(n)). Il surpasse alors toutes les autres méthodes de tri qui sont au mieux en O(n ln(n)).

18 3. Tri rapide « Quick sort »
, Tri de valeurs numériques

19 3. Tri rapide « Quick sort »
, Dans le pire des cas, un des deux segments est vide à chaque appel de la fonction de tri. Cela arrive lorsque le tableau est déjà trié. Le nombre de données à traiter pour le ième appel, est n – i + 1. On peut aussi écrire une relation de récurrence du type C(n) = C(n-1) + n - 1 La complexité est donc de classe quadratique C(n) = O(n2). Dans le meilleur des cas, les deux segments sont de taille égale. Pour un nombre de données à traiter n, chacun des segments suivant a donc au plus (n-1)/2 éléments (on retire le pivot). On répète ainsi la segmentation des tableaux jusqu’à arriver au plus à un seul élément. On peut écrire une relation de récurrence du type C(n) = 2 C((n - 1) / 2) + n - 1. La complexité est donc de classe quasi linéaire C(n)=O(n ln(n)).

20 3. Tri rapide « Quick sort »
, Dans le pire des cas, un des deux segments est vide à chaque appel de la fonction de tri. Cela arrive lorsque le tableau est déjà trié. Le nombre de données à traiter pour le ième appel, est n – i + 1. On peut aussi écrire une relation de récurrence du type C(n) = C(n-1) + n - 1 La complexité est donc de classe quadratique C(n) = O(n2). Dans le meilleur des cas, les deux segments sont de taille égale. Pour un nombre de données à traiter n, chacun des segments suivant a donc au plus (n-1)/2 éléments (on retire le pivot). On répète ainsi la segmentation des tableaux jusqu’à arriver au plus à un seul élément. On peut écrire une relation de récurrence du type C(n) = 2 C((n - 1) / 2) + n - 1. La complexité est donc de classe quasi linéaire C(n)=O(n ln(n)).

21 3. Tri rapide « Quick sort »
, Dans le pire des cas, un des deux segments est vide à chaque appel de la fonction de tri. Cela arrive lorsque le tableau est déjà trié. Le nombre de données à traiter pour le ième appel, est n – i + 1. On peut aussi écrire une relation de récurrence du type C(n) = C(n-1) + n - 1 La complexité est donc de classe quadratique C(n) = O(n2). Dans le meilleur des cas, les deux segments sont de taille égale. Pour un nombre de données à traiter n, chacun des segments suivant a donc au plus (n-1)/2 éléments (on retire le pivot). On répète ainsi la segmentation des tableaux jusqu’à arriver au plus à un seul élément. On peut écrire une relation de récurrence du type C(n) = 2 C((n - 1) / 2) + n - 1. La complexité est donc de classe quasi linéaire C(n)=O(n ln(n)).

22 3. Tri rapide « Quick sort »
, Notion de complexité

23 3. Tri rapide « Quick sort »
, Dans le pire des cas, un des deux segments est vide à chaque appel de la fonction de tri. Cela arrive lorsque le tableau est déjà trié. Le nombre de données à traiter pour le ième appel, est n – i + 1. On peut aussi écrire une relation de récurrence du type C(n) = C(n-1) + n - 1 La complexité est donc de classe quadratique C(n) = O(n2). Dans le meilleur des cas, les deux segments sont de taille égale. Pour un nombre de données à traiter n, chacun des segments suivant a donc au plus (n-1)/2 éléments (on retire le pivot). On répète ainsi la segmentation des tableaux jusqu’à arriver au plus à un seul élément. On peut écrire une relation de récurrence du type C(n) = 2 C((n - 1) / 2) + n - 1. La complexité est donc de classe quasi linéaire C(n)=O(n ln(n)).

24 3. Tri rapide « Quick sort »
,

25 3. Tri rapide « Quick sort »
, Algorithme : Segmentation (fonction Segmente) Données : T : un tableau de valeurs num [1..n] ; i, j : les indices de début et de fin de la segmentation à effectuer Résultat : le tableau T « segmenté » avec le pivot à sa place définitive, l’indice de la place du pivot PYTHO N def Segmente( T ,i ,j ) :

26 3. Tri rapide « Quick sort »
, Algorithme : Segmentation (fonction Segmente) Données : T : un tableau de valeurs num [1..n] ; I , j : les indices de début et de fin de la segmentation à effectuer Résultat : le tableau T « segmenté » avec le pivot à sa place définitive, l’indice de la place du pivot PYTHO N def Segmente( T ,i ,j ) : g=i+1 d=j p=T[i] while g<=d : while d>=0 and T[d]>p: d=d-1 while g<=j and T[g]<=p: g=g+1 if g<d: echange(T,g,d) k=d echange(T,i,d) return k

27 3. Tri rapide « Quick sort »
, Complexité : Le nombre de comparaisons : égal dans meilleur des cas à n – 1. La complexité de cet algorithme est donc au mieux de classe linéaire : C(n)=O(n). Dans le pire des cas, tous les éléments sont identiques. La complexité est alors quadratique : C(n)=O(n2).

28 3. Tri rapide « Quick sort »
, Algorithme : Tri rapide (fonction Tri_rapide) Données : T : un tableau de valeurs num [1..n] ; i, j : les indices de début et de fin de la segmentation à effectuer Résultat : le tableau T trié entre les indices i et j compris PYTHO N def Tri_rapide( ) :

29 3. Tri rapide « Quick sort »
, Algorithme : Tri rapide (fonction Tri_rapide) Données : T : un tableau de valeurs num [1..n] ; i, j : les indices de début et de fin de la segmentation à effectuer Résultat : le tableau T trié entre les indices i et j compris PYTHO N def Tri_rapide(T, i, j): if i<j: k=segmente(T,i,j) Tri_rapide(T,i,k-1) Tri_rapide(T,k+1,j) return T

30 3. Tri rapide « Quick sort »
, Cette méthode de tri est très efficace lorsque les données sont distinctes et non ordonnées. La complexité est alors globalement en O(n ln(n)). Lorsque le nombre de données devient petit (<15) lors des appels récursifs de la fonction de tri, on peut avantageusement le remplacer par un tri par insertion dont la complexité est linéaire lorsque les données sont triées ou presque.

31 3. Tri rapide « Quick sort »
, Algorithme : Tri rapide (fonction Tri_rapide) Données : T : un tableau de valeurs num [1..n] ; i, j : les indices de début et de fin de la segmentation à effectuer Résultat : le tableau T trié entre les indices i et j compris

32 3. Tri rapide « Quick sort »
, Algorithme : Tri rapide optimisé (fonction Tri_rapide2) Données : T : un tableau de valeurs num [1..n] ; i, j : les indices de début et de fin de la segmentation à effectuer Résultat : le tableau T trié entre les indices i et j compris

33 4. Tri Fusion  , On coupe en deux parties à peu près égales les données à trier. On trie les données de chaque partie par la méthode de tri fusion. On fusionne les deux parties en interclassant les données. L’algorithme est donc récursif. Il fait partie des algorithmes « diviser pour régner ».

34 4. Tri Fusion  , Tri de valeurs numériques

35 4. Tri Fusion  , Algorithme : fusion de 2 listes trièes (fonction Fusion) Données : T : un tableau de valeurs numériques [g..d] les sous-tableaux T[g..m] et T[m+1..d] sont ordonnés Résultat : le tableau T de valeurs numériques [g..d] ordonnées

36 4. Tri Fusion def Tri_fusion( ) : PYTHO N 1. 2. 3. 4. 5. 6,
Complexité : Cet algorithme a une complexité en temps de classe linéaire : C(n)=O(n). Par contre, il oblige à utiliser un espace supplémentaire égal à la taille du tableau original T.  algorithme récursif de tri fusion : Algorithme : Tri fusion (fonction Tri_fusion) Données : T : un tableau de valeurs numériques non triées [g..d] g, d : les indices de début et de fin de tableau Résultat : le tableau T avec les mêmes valeurs mais triées PYTHO N def Tri_fusion( ) :

37 4. Tri Fusion def Tri_fusion( T, g , d ) : if g<d: m=(g+d)//2
, Algorithme : Tri fusion (fonction Tri_fusion) Données : T : un tableau de valeurs numériques non triées [g..d] g, d : les indices de début et de fin de tableau Résultat : le tableau T avec les mêmes valeurs mais triées PYTHO N def Tri_fusion( T, g , d ) : if g<d: m=(g+d)//2 Tri_fusion(T,g,m) Tri_fusion(T,m+1,d) Fusion(T,g,d,m) return T

38 4. Tri Fusion  , Si l’on s’intéresse au nombre de données à traiter à chaque appel de fonction, la relation de récurrence est du type : C(n) = 2 C(n / 2) + n. La méthode de tri fusion a donc une efficacité temporelle comparable au tri rapide en O(n ln(n)). Par contre, elle n'opère pas en place : une zone temporaire de données supplémentaire de taille égale à celle de l'entrée est nécessaire. Des versions plus complexes peuvent être effectuées sur place mais sont moins rapides.

39 5. Arbre et Tri Tas 1. 2. 3. 4. 5. 6, Un arbre binaire de recherche
Les noeuds appartiennent à un ensemble ordonné  Pour tout noeud interne a, les données du sous-arbre gauche de a <= donnée contenue dans le noeud a, qui est elle-même <= aux données contenues dans le sous-arbre droit de a.

40 5. Arbre et Tri Tas La complexité :
, 5. Arbre et Tri Tas Un arbre binaire de recherche Les noeuds appartiennent à un ensemble ordonné  Pour tout noeud interne a, les données du sous-arbre gauche de a <= donnée contenue dans le noeud a, qui est elle-même <= aux données contenues dans le sous-arbre droit de a. La complexité : dans le pire des cas égale à la profondeur de l’arbre binaire en moyenne égale à la profondeur moyenne des feuilles de l’arbre binaire. Le tri par arbre binaire de recherche est donc au pire en O(n2) et en moyenne en O(n ln(n)).

41 5. Tri Tas (Huffman) 1. 2. 3. 4. 5. 6, from heapq import *
def table_frequences(texte): table = {} for caractere in texte: if caractere in table: table[caractere] = table[caractere] + 1 else: table[caractere] = 1 return table from heapq import * def arbre_huffman (occurrences): # Construction d'un tas avec les lettres sous forme de feuilles tas = [(occ, lettre) for (lettre, occ) in occurrences.items()] heapify(tas)   # Création de l'arbre while len(tas) >= 2: occ1, noeud1 = heappop(tas) # noeud de plus petit poids occ1 occ2, noeud2 = heappop(tas) # noeud de deuxième plus petit poids occ2 heappush(tas, (occ1 + occ2, {0: noeud1, 1: noeud2})) # ajoute au tas le noeud de poids occ1+occ2 et avec les fils noeud1 et noeud2   return heappop(tas)[1]

42 5. Tri Tas (Huffman) 1. 2. 3. 4. 5. 6, from heapq import *
def table_frequences(texte): table = {} for caractere in texte: if caractere in table: table[caractere] = table[caractere] + 1 else: table[caractere] = 1 return table from heapq import * def arbre_huffman (occurrences): # Construction d'un tas avec les lettres sous forme de feuilles tas = [(occ, lettre) for (lettre, occ) in occurrences.items()] heapify(tas)   # Création de l'arbre while len(tas) >= 2: occ1, noeud1 = heappop(tas) # noeud de plus petit poids occ1 occ2, noeud2 = heappop(tas) # noeud de deuxième plus petit poids occ2 heappush(tas, (occ1 + occ2, {0: noeud1, 1: noeud2})) # ajoute au tas le noeud de poids occ1+occ2 et avec les fils noeud1 et noeud2   return heappop(tas)[1]

43 , 5. Tri Tas (Huffman) def code_huffman_parcours(arbre,prefixe,code): for noeud in arbre: if len(arbre[noeud]) == 1: code[prefixe+str(noeud)] = arbre[noeud] else: code_huffman_parcours(arbre[noeud],prefixe+str(noeud),code) def code_huffman(arbre): code = {} code_huffman_parcours(arbre,'',code) return code def encodage(texte,code): code_inv = dict((code[str(bits)], bits) for bits in code) # construit le dictionnaire inverse texte_binaire = ' ' for c in texte: texte_binaire = texte_binaire + code_inv[c] return texte_binaire def decodage(code,texte_binaire): texte = '' tampon = '' for b in texte_binaire: tampon = tampon+b if tampon in code: texte = texte+code[tampon] return texte

44 6. Synthèse Tri de valeurs numériques générées aléatoirement La simulation a été effectuée pour un tableau de valeurs numériques générées aléatoirement. Temps en secondes Tri Bulle Tri par Insertion Tri par Sélection Tri Fusion Tri Rapide Tri Natif Python (méthode sort) :

45 6. Synthèse Tri de valeurs numériques générées aléatoirement La simulation a été effectuée pour un tableau de valeurs numériques générées aléatoirement. Temps en secondes Tri Bulle Tri par Insertion Tri par Sélection Tri Fusion Tri Rapide Tri Natif Python (méthode sort) : Module time

46 6. Synthèse

47 6. Synthèse DISTINGUER PAR LEURS COMPLEXITÉS DEUX ALGORITHMES RÉSOLVANT UN MÊME PROBLÈME : La première étape consiste à vérifier que les algorithmes résolvent exactement le même problème. On compare la complexité en temps dans le pire des cas (préférable à l’utilisation du module Time car indépendant de la machine). Il faut vérifier que le pire des cas peut arriver en situation réelle Penser à comparer la complexité en espace qui peut permettre de départager des algorithmes équivalents

48 6. Synthèse DISTINGUER PAR LEURS COMPLEXITÉS DEUX ALGORITHMES RÉSOLVANT UN MÊME PROBLÈME : La première étape consiste à vérifier que les algorithmes résolvent exactement le même problème. On compare la complexité en temps dans le pire des cas (préférable à l’utilisation du module Time car indépendant de la machine). Il faut vérifier que le pire des cas peut arriver en situation réelle Penser à comparer la complexité en espace qui peut permettre de départager des algorithmes équivalents

49 6. Synthèse DISTINGUER PAR LEURS COMPLEXITÉS DEUX ALGORITHMES RÉSOLVANT UN MÊME PROBLÈME : La première étape consiste à vérifier que les algorithmes résolvent exactement le même problème. On compare la complexité en temps dans le pire des cas (préférable à l’utilisation du module Time car indépendant de la machine). Il faut vérifier que le pire des cas peut arriver en situation réelle Penser à comparer la complexité en espace qui peut permettre de départager des algorithmes équivalents


Télécharger ppt "Cours 4 : Tris de Tableaux"

Présentations similaires


Annonces Google