web-dev-qa-db-fra.com

Pourquoi ArrayList add () et add (int index, E) la complexité est-elle à temps constant amorti? Pourquoi pas O(1) pour add (), O(n) pour add (int index, E)?

Pourquoi ArrayList add () et add (int index, E) complexité est amorti à temps constant?

Pourquoi pas O(1) pour une seule opération add (), O(n) pour une opération simple add (int index, E) et O(n) pour l'ajout de n éléments (n opérations add) à l'aide de l'une ou l'autre méthode add? Supposons que nous utilisons add (int index, E) pour ajouter rarement à la fin du tableau?

N'est-ce pas une complexité d'opération de tableau (et ArrayList) ayant déjà n éléments:

  1. ajouter () - O (1)?
  2. add (int index, E) - O (n)?

Si nous faisons un million d'insertions, la moyenne de 1 et 2 ne peut pas être O (1), non?

Pourquoi Oracle dit

L'opération d'ajout s'exécute en temps constant amorti , c'est-à-dire que l'ajout de n éléments nécessite O(n) fois .

Je pensais que la complexité était O(1) pour add () et O(n) pour add (int index, E).

Cela signifie-t-il que "complexité intégrale de n opérations" (chaque opération de complexité O(1)) est pour ainsi dire n * O (1) = O (n). Qu'est-ce qui me manque ?

Peut-être que pour Oracle, "ajouter une opération" signifie toujours seulement ajouter ()? Et ajouter (int, E) est "opération d'insertion"? Alors totalement clair!

J'ai une supposition, cela a à voir avec la différence entre analyse asymptotique et analyse amortie, mais je ne peux pas le comprendre jusqu'au bout.

Qu'est-ce qu'une analyse amortie des algorithmes?

Pourquoi la complexité temporelle d'une insertion de tableau est O(n) et non O (n + 1)?

Plus approprié pour dire Amortized O(1) vs O(n) pour insertion dans un tableau dynamique non trié? (pas tout à fait clair) )

Big O lors de l'ajout de différentes routines

9
Code Complete

En termes Oracle (qui sont implicites tacitement) et en parlant de List

  • "ajouter une méthode" (synonyme - "ajouter une méthode") signifie toujours boolean add(E)
  • "insérer la méthode" signifie toujours boolean add(int index, E)

Quand Oracle écrit

L'opération d'ajout s'exécute en temps constant amorti, c'est-à-dire que l'ajout de n éléments nécessite O(n) temps.

ça veut dire:

La complexité d'une seule opération boolean add(E) est amortie O (1).

Il ne peut pas être simplement O(1) asymptotique (toujours) car nous avons rarement besoin d'augmenter la capacité du tableau. Cette opération d'ajout unique qui est en fait une opération "créer un nouveau tableau plus grand, y copier un ancien tableau, puis ajouter un élément à la fin" est une complexité asymptotique O(n), car la copie du tableau lorsque l'augmentation de la capacité de la liste est O (n), la complexité de la croissance et de l'ajout est O(n) [calculée comme O(n) + O(1) = Sur)]. Sans cette opération de croissance de capacité, la complexité supplémentaire aurait été O (1), l'élément est toujours ajouté (ajouté) à la fin du tableau (indice max). Si nous "ajoutions" (= insérés) à la fin du tableau, nous aurions besoin de déplacer les éléments les plus à droite (avec des index plus grands), et la complexité pour une telle opération aurait été O (n).

Maintenant, pour une seule opération d'ajout, la complexité asymptotique est O(1) pour ajouter sans augmenter la capacité et O(n) pour ajouter avec augmenter la capacité (ce qui se produit très rare).

La complexité amortie d'une opération d'ajout unique est O (1). Cela reflète le fait que les rares opérations de croissance et d'ajout O(n) sont "diluées" avec beaucoup plus nombreuses O(1) celles sans ajout, ainsi de suite " l '"opération simple moyenne" est O (1).

La "complexité asymptotique" de n opérations d'addition est O (n). Mais ici, nous parlons de la complexité de n opérations, pas de la complexité d'une opération. Ce n'est pas une façon stricte de le dire comme ça ("Complexité asymptotique"), mais de toute façon. La complexité amortie de n opérations est encore moins logique.

Enfin, boolean add(int index, E) la complexité d'une seule opération est toujours O (n). S'il déclenche, c'est O(n) + O(n) [agrandir + insérer], mais 2 * O (n) est identique à O (n).

16
Code Complete