Il pourrait être O (1) si la liste contient un indicateur qui permet d'intervertir le sens de l'expression " prev
" et " next
Chaque nœud a des pointeurs ". Si l'inversion de la liste est une opération fréquente, un tel ajout pourrait être en fait utile et je ne vois aucune raison pour laquelle l'implémenter serait une erreur. interdit par la norme actuelle. Cependant, l'existence d'un tel indicateur rendrait les traversée de la liste plus cher (ne serait-ce que par un facteur constant) parce qu'au lieu de
current = current->next;
dans le operator++
de l'itérateur de liste, on obtiendrait
if (reversed)
current = current->prev;
else
current = current->next;
ce qui n'est pas quelque chose que l'on décide d'ajouter facilement. Étant donné que les listes sont généralement parcourues beaucoup plus souvent qu'elles ne sont inversées, il serait très imprudent que la norme prévoie de mandat cette technique. Par conséquent, l'opération inverse peut avoir une complexité linéaire. Notez cependant que t ∈ O (1) ⇒ t ∈ O ( n ) donc, comme mentionné précédemment, la mise en œuvre de votre "optimisation" serait techniquement autorisée.
Si vous venez d'un environnement Java ou similaire, vous pouvez vous demander pourquoi l'itérateur doit vérifier le drapeau à chaque fois. Ne pourrait-on pas plutôt avoir deux types d'itérateurs distincts, tous deux dérivés d'un type de base commun, et avoir std::list::begin
et std::list::rbegin
retourner polymorphiquement l'itérateur approprié ? Bien que cela soit possible, cela rendrait l'ensemble encore pire parce que l'avancement de l'itérateur serait maintenant un appel de fonction indirect (difficile à mettre en ligne). En Java, vous payez ce prix régulièrement, mais c'est l'une des raisons pour lesquelles de nombreuses personnes choisissent le C++ lorsque les performances sont critiques.
Comme l'a souligné Benjamin Lindley dans les commentaires, puisque reverse
n'est pas autorisé à invalider les itérateurs, la seule approche autorisée par la norme semble être de stocker un pointeur vers la liste à l'intérieur de l'itérateur, ce qui entraîne un accès doublement indirect à la mémoire.