La notation Big O est un concept clé en programmation pour mesurer l'efficacité de votre code, en particulier dans les algorithmes. Elle permet de voir comment un algorithme va se comporter lorsque la quantité de données augmente.
Imaginez que vous avez un code qui fonctionne parfaitement pour quelques éléments, mais qu'il devient incroyablement lent lorsque le nombre d'éléments augmente. La notation Big O est là pour vous aider à comprendre et anticiper ce genre de situation.
# Accès direct à un élément - O(1)
mon_tableau = [10, 20, 30, 40]
print(mon_tableau[2]) # Accède directement à l'index 2
Explication : Ici, accéder à mon_tableau[2]
prend toujours le même temps, que le tableau contienne 10 éléments ou 1 million.
# Recherche binaire - O(log n)
def recherche_binaire(liste, element):
debut, fin = 0, len(liste) - 1
while debut <= fin:
milieu = (debut + fin) // 2
if liste[milieu] == element:
return milieu
elif liste[milieu] < element:
debut = milieu + 1
else:
fin = milieu - 1
return -1
Explication : À chaque itération, l'algorithme coupe la liste en deux, ce qui signifie qu'il ne travaille que sur la moitié des éléments restants. Cela le rend très rapide pour les grandes listes triées.
# Recherche linéaire - O(n)
def recherche_lineaire(liste, element):
for i in range(len(liste)):
if liste[i] == element:
return i
return -1
Explication : Ici, l'algorithme passe par chaque élément jusqu'à trouver celui qu'il cherche. Si la liste contient 10 éléments, cela prendra environ 10 vérifications; si elle en contient 1 000, cela prendra environ 1 000 vérifications.
# QuickSort - O(n log n)
def quicksort(liste):
if len(liste) <= 1:
return liste
pivot = liste[len(liste) // 2]
gauche = [x for x in liste if x < pivot]
milieu = [x for x in liste if x == pivot]
droite = [x for x in liste if x > pivot]
return quicksort(gauche) + milieu + quicksort(droite)
Explication : O(n log n) est plus rapide que O(n²) car l'algorithme divise les éléments en sous-ensembles plus petits pour les trier, ce qui permet d'obtenir une meilleure performance globale.
# Selection Sort - O(n²)
def selection_sort(liste):
for i in range(len(liste)):
min_index = i
for j in range(i+1, len(liste)):
if liste[j] < liste[min_index]:
min_index = j
liste[i], liste[min_index] = liste[min_index], liste[i]
return liste
Explication : Ici, pour chaque élément, l'algorithme doit parcourir toute la liste restante, ce qui le rend lent pour de grandes listes. Si vous doublez la taille de la liste, le temps d'exécution quadruple.
# Calcul des sous-ensembles - O(2ⁿ)
def sous_ensembles(ensemble):
if not ensemble:
return [[]]
premier, reste = ensemble[0], ensemble[1:]
subsets = sous_ensembles(reste)
return subsets + [[premier] + subset for subset in subsets]
Explication : L'algorithme doit calculer tous les sous-ensembles possibles, ce qui double le nombre de calculs pour chaque élément ajouté. Très peu efficace pour de grands ensembles.
La notation Big O vous aide à évaluer la performance de votre code, surtout en ce qui concerne les données volumineuses. Voici un résumé simple des principales complexités :
Avec ces concepts, vous serez mieux armé pour choisir et optimiser vos algorithmes en fonction des performances attendues !