web-dev-qa-db-fra.com

Pourquoi la complexité temporelle de la méthode O (1) de list.append () en python?

Comme vu dans la documentation de TimeComplexity , le type list de Python est implémenté en utilisant un tableau.

Donc, si un tableau est utilisé et que nous faisons quelques ajouts, vous devrez éventuellement réallouer l'espace et copier toutes les informations dans le nouvel espace.
Après tout cela, comment peut-il être O(1) pire cas?

25
ohad edelstain

Si vous regardez la note de bas de page dans le document que vous avez lié, vous pouvez voir qu'ils contiennent une mise en garde:

Ces opérations reposent sur la partie "Amortized" du "Amortized Worst Case". Les actions individuelles peuvent prendre étonnamment longtemps, en fonction de l'histoire du conteneur.

En utilisant analyse amortie , même si nous devons occasionnellement effectuer des opérations coûteuses, nous pouvons obtenir une limite inférieure sur le coût `` moyen '' des opérations lorsque vous les considérez comme une séquence, plutôt qu'individuellement.

Ainsi, toute opération individuelle pourrait être très coûteuse - O(n) ou O (n ^ 2) ou quelque chose de plus grand encore - mais comme nous savons que ces opérations sont rares, nous garantissons qu'une séquence de O(n) les opérations peuvent être effectuées en O(n) temps).

21
Jacob Ritchie

Il est amorti O (1), pas O (1).

Disons que la taille réservée de la liste est de 8 éléments et qu'elle double de taille lorsque l'espace est épuisé. Vous voulez pousser 50 éléments.

Les 8 premiers éléments Poussez O (1). Le dix-neuvième déclenche une réallocation et 8 copies, suivi d'un O(1) Push. Le 7 suivant pousse dans O (1). Le dix-septième déclenche une réallocation et 16 copies, suivi d'un O(1) Push. Les 15 prochains Push in O (1). Le trente-troisième déclenche une réallocation et 32 ​​copies, suivi d'un O(1) Push. Les 17 suivants Appuyez sur O (1).

Donc, toutes les poussées ont une complexité O(1), nous avons eu 56 copies à O (1) et 3 réallocations à O (n), avec n = 8, 16 et 32. Notez qu'il s'agit d'une série géométrique et asymptotiquement égale à O(n) avec n = la taille finale de la liste. Cela signifie que toute l'opération consistant à pousser n objets sur la liste est O (n) Si nous amortissons cela par élément, c'est O (n)/n = O (1).

26
rlbond