Complexité des algorithmes et tri
Définition : complexité. La complexité est le nombre d'exécutions d'instructions élémentaires nécessaires pour obtenir la réponse (exacte) au pire cas, en fonction de la taille d'entrée.
Algorithme type.
- Entrée : une suite (une liste) d'objets comparables (entiers, réels, mots...)
- Sortie : une suite (une liste) des mêmes objets triés
Définition : opération élémentaire. Une opération élémentaire est une comparaison de deux objets, une addition de deux scalaires, etc.
def triNaif(L):
Trie=[]
while len(L)>0:
m=L[0]
for e in L:
if e>m:
m=e
Trie=Trie+[m]
L.remove(m)
return Trie
Calculons la complexité :
- La création de liste et le
returnont une complexité constante. - La boucle
whilese répète fois. - Les opérations dans la boucle
whilese répètent fois. - La boucle
fora un nombre constant d'opérations par élément de : c'est donc une complexité linéaire par rapport à .
Ainsi on a
Outils de comparaison
. On dit que est de si et seulement si
c'est-à-dire .
. On dit que est de si et seulement si
. On dit que est de si et seulement si
On remarque que est en de si et seulement si est en et en de .
Rappel. On rappelle que le nombre d'ordres possibles pour une liste de éléments vaut .
Quick sort
Principe.

Réalisation.
def quickSort(L, début=0, fin=None):
if fin==None:
fin=len(L)-1
if début>=fin:
return
pivot=L[randint(début,fin)]
seuil=partitionner(L,début,fin,pivot)
quickSort(L,début,seuil-1)
quickSort(L,seuil,fin)
def partitionner(L,début,fin,pivot):
i=début
j=fin
while i<j:
while L[i]<pivot:
i=i+1
while L[j]>pivot:
j=j-1
if i<j:
a=L[i]
L[i]=L[j]
L[j]=a
return i
Merge sort
Principe.

def fusion(L1,L2):
i=0
j=0
L=[]
while i<len(L1) and j<len(L2):
if L1[i]<L2[j]:
L.append(L1[i])
i=i+1
else:
L.append(L2[j])
j=j+1
while len(L1)>i:
L.append(L1[i])
i=i+1
while len(L2)>j:
L.append(L2[j])
j=j+1
return L
def casser(L):
L_c=[]
i=0
while len(L)>0:
x=L.pop(i)
L_c=L_c+[[x]]
return L_c
def mergeSort(L):
cpt=0
L=casser(L)
while len(L)>2:
x=L.pop(0)
y=L.pop(1)
L.append(fusion(x,y))
if len(L)==2:
x=L.pop(0)
y=L.pop(0)
return fusion(x,y)
Analyse de la complexité. On cherche la complexité de mergeSort, définie par la complexité pour trier 2 listes à éléments et la complexité pour fusionner les 2 listes. On a donc :
Par récurrence on obtient
Donc .
Master Theorem
Quelle est la complexité d'une procédure définie ainsi :
p(entrée de taille n) :
si n<n_0 :
trouver la réponse directement
sinon
décomposer l'entrée en a objets, chacun de taille n/b
appeler p() pour chacun de ces objets
combiner les résultats partiels pour trouver la réponse à retourner
La complexité d'un tel algorithme est la somme de la complexité des appels récursifs de et de celle de la combinaison des résultats partiels.
Master Theorem. Soit .
- Si avec , alors
- Si avec , alors
- Sinon : et
- si , alors
- si , alors
- si , alors