• Aucun résultat trouvé

Tri par insertion Tri fusion Tri rapide

N/A
N/A
Protected

Academic year: 2022

Partager "Tri par insertion Tri fusion Tri rapide"

Copied!
1
0
0

Texte intégral

(1)

Tri par sélection Tri par insertion Tri fusion Tri rapide Principe : Comme une photo de classe, la liste est lue

afin de repérer le plus petit élément qui est placé en début de liste. Ici tri en place et stable (>)

Principe du jeu de cartes : Pour une sous-liste déjà triée, on compare l’élément à trier (clé) aux valeurs précédentes. Ici tri en place et stable (>)

Principe du diviser pour régner : on divise la liste par deux jusqu’à obtenir une liste de longueur unitaire (ou nulle) facile à classer. On utilise une autre fonction pour trier des sous listes triées. Ici tri pas en place et non stable.

Principe « diviser pour régner » : On prend un pivot 𝑝 (1e élément) et on crée une liste dont les éléments sont inférieurs à 𝑝 et une autre liste dont les éléments sont supérieurs (ou égale) à 𝑝. Par récursivité, on aboutit au cas trivial. Ici tri qui n’est pas en place et pas stable def selection(L):

for i in range(len(L)-1):

index_min=i

for j in range(i+1,len(L)):

if L[index_min]>L[j]:

index_min=j

L[i],L[index_min]=L[index_min],L[i]

return L

def insertion(L):

for i in range(1,len(L)):

j=i-1 cle=L[i]

while cle<L[j] and j>=0:

j=j-1

L[j+2:i+1]=L[j+1:i]

L[j+1]=cle return L

def fusion1(L1,L2):

n1,n2=len(L1)-1,len(L2)-1 L=[]

i1,i2=0,0

while i1<=n1 and i2<=n2 : if L1[i1]<L2[i2]:

L.append(L1[i1]) i1=i1+1

else :

L.append(L2[i2]) i2=i2+1

if i2>n2 :

return L+L1[i1:]

else :

return L+L2[i2:]

def fusion2(L):

if len(L)==0 : return L else :

L1=fusion2(L[:len(L)//2]) L2=fusion2(L[len(L)//2:]) return fusion1(L1,L2)

def rapide(L):

if len(L)==0 or len(L)==1:

return L else : L1=[]

L2=[]

for i in range(1,len(L)):

if L[i]<L[0]:

L1.append(L[i]) else :

L2.append(L[i])

return rapide(L1)+[L[0]]+rapide(L2)

Terminaison :

Evidente car il s’agit de deux boucles for

Terminaison :

𝑗 est le variant de boucle amenant à la terminaison de la boucle while

Terminaison :

- La 1e fonction présente un variant de boucle qui augmente forcément jusqu’à atteindre l’index max d’une des deux listes - La 2e fonction converge également vers la

situation triviale

Terminaison :

La boucle for se termine forcément et les appels récursifs convergent vers les deux situations triviales

Correction :

La propriété 𝐿[: 𝑖] est une liste triée est l’invariant de boucles :

- Initialisation : évident en entrée de boucle lorsque 𝑖 = 0

- Continuité : Si 𝐿[: 𝑖] est bien triée alors la prochaine recherche conduit nécessairement à rajouter 𝐿[𝑖] ≥ 𝐿[𝑖 − 1]

- Terminaison : La dernière itération conduit à la comparaison des deux derniers éléments (inévitablement les plus grands de 𝐿)

Correction :

La propriété 𝐿[: 𝑖] est une liste triée est l’invariant de boucles :

- Initialisation : évident en entrée de boucle lorsque 𝑖 = 1

- Continuité : Si 𝐿[: 𝑖] est bien triée alors la prochaine recherche conduit nécessairement à rajouter 𝐿[𝑖] ≥ 𝐿[𝑖 − 1]

- Terminaison : Le dernier élément est comparé aux éléments déjà triés

Correction :

Le cas trivial d’une liste à un élément renvoie cet élément : ce qui est juste.

Supposons cet algorithme vrai pour toute liste de longueur 𝑛.

Si on considère deux listes 𝐿1 et 𝐿2 de longueur 𝑛 et donc triables et une une liste 𝐿 = [𝐿1] + [𝐿2] . Tous les éléments de 𝐿1 sont plus petits que tous les éléments de 𝐿2

𝑓𝑢𝑠𝑖𝑜𝑛2(𝐿) => 𝑓𝑢𝑠𝑖𝑜𝑛2(𝐿1, 𝐿2) Ce qui conduit effectivement à une liste triée.

Correction : Par récurrence :

- Si 𝑙𝑒𝑛(𝐿) = 𝑛 = 0,1 alors la liste est bien triée - Supposons cet algorithme vrai pour toute liste de longueur 𝑛. Si on considère deux listes 𝐿1 et 𝐿2 de longueur 𝑛 et donc triables et une liste 𝐿 = [𝐿1] + [𝑝] + [𝐿2] où 𝑝 est une liste à un élément pour lequel tous les éléments de 𝐿1 sont plus petit et tous les éléments de 𝐿2 sont plus grands. Alors l’algorithme de tri rapide de pivot 𝑝 conduit à :

𝑡𝑟𝑖(𝐿) = 𝑡𝑟𝑖(𝐿1) + [𝑝] + 𝑡𝑟𝑖(𝐿2) Complexité :

Dans tous les cas, le nombre de comparaison est : 𝑇(𝑛) = (𝑛 − 1) + (𝑛 − 2) + ⋯ 1 =𝑛(𝑛 − 1)

2 𝑇(𝑛) = 𝑂(𝑛2)

Complexité (unité de cout est la comparaison) : - Dans le pire des cas (liste inversée) :

𝑇(𝑛) =𝑛(𝑛 − 1) 2 = 𝑂(𝑛2) - Dans le meilleur des cas (liste déjà triée) :

𝑇(𝑛) = 𝑂(𝑛)

C’est cette linéarité qui fait l’efficacité de cette méthode pour une liste presque triée.

Complexité :

On peut remarquer que l’on a 𝑙𝑜𝑔2(𝑛) niveaux et sur chaque niveau, on va comparer typiquement 𝑛 valeurs : 𝑇(𝑛) = 𝑛𝑙𝑜𝑔2(𝑛) la complexité est quasi-linéaire.

Complexité :

- Pire cas (liste triée et pivot au départ) : 𝐿1 vide, donc 𝑛 − 1 + 𝑛 − 2+. .1 appels et 𝑇(𝑛) = 𝑂(𝑛2)

- Meilleur cas : 𝐿1 et 𝐿2 sont (quasi) de même taille : donc log2(𝑛) appels amenant à chaque étape 𝑛 comparaisons (en ordre de grandeur):

𝑇(𝑛) ≈ 𝑛𝑙𝑜𝑔2(𝑛)

Références

Documents relatifs

[r]

Or pour que l’élément de rang i et l’élément de rang j soient comparés il faut que le pivot ne soit jamais choisi entre l’élément de rang i et de rang j avant le choix de i ou

Il sut que l'ensemble soit muni d'une relation d'ordre total : chaînes de caractères pour l'ordre lexicographique par

Couper le tableau en son milieu, trier récursivement les deux moitiés, puis fusionner les deux en une liste unique triée.. Il s'agit d'un tri 'rapide', comme 'quicksort', et comme

L’après midi, Paul DEFFONTAINE, président du Cercle National du Recyclage et Vice-président de Lille Mé- tropole Communauté urbaine, animera les débats consacrés aux avancées

Lorsqu’une base de données est très volumineuse et non ordonnée, trouver une information dans cette base est très long et très ingrat.. En effet la seule solution est

Dans le tri rapide, après les 2 tris partiels, tous les éléments de la partie gauche sont inférieurs au pivot, alors que tous les éléments de la partie droite... naturelle, et

3) Combiner : les deux sous-listes triées sont alors combinées de sorte à ce que la liste résultat soit triée... Il nécéssite de l’ordre de n log(n) comparaisons/affectations