Liste liée insertion temps d'exécution de la confusion
J'ai essayé de confirmer le temps d'exécution pour l'insertion de Liste, et il semble comme il y a deux réponses différentes.
Pour l'insertion d'un élément à la fin d'une Liste Liée, je pense que ce serait prendre en O(n), puisqu'il fait parcourir à la fin de la liste pour accéder à la queue. Mais certaines des réponses que j'ai vu, dit-O(1)? Sont-ils en supposant que toutes les listes chaînées de la mise en œuvre d'un pointeur vers la queue? Si oui, est qu'une hypothèse vraisemblable?
Deuxièmement, certains endroits suggèrent également que l'insertion d'un élément au milieu d'une liste chaînée est O(1), que je suis confus au sujet de la raison pour le même raisonnement de la traverse au moyen de la liste pour l'insérer.
Quelqu'un pourrait-il préciser? Merci.
Li0liQ: l'Un des avantages de listes liées, c'est que vous pouvez insérer des éléments dans le milieu, en temps constant, où, dans les tableaux, vous devez déplacer tous les éléments suivants.
Quid de la constante de temps de l'indexation?
OriginalL'auteur Troy | 2009-12-19
Vous devez vous connecter pour publier un commentaire.
Insertion d'une liste chaînée est O(1) si vous avez un pointeur vers le nœud où vous souhaitez insérer l'élément. Trouver ce nœud peut être O(n) en fonction de ce que vous voulez faire.
Si vous gardez un pointeur vers la liste de la queue, alors vous n'avez pas besoin de le chercher, puis de l'insertion est O(1).
Et non, pas tous liés liste des implémentations d'avoir un pointeur sur la fin de la liste.
Exemple
Supposons que vous avez une liste vide à laquelle vous ajoutez un nœud unique,
x
. Ensuite, vous ajoutezn
les nœuds de la liste avant et aprèsx
. Vous pouvez toujours insérer un nœud unique aprèsx
par simple mise à jour de sonnext
pointeur (et le nouveau nœud), indépendamment du nombre de nœuds sont la liste.OriginalL'auteur Amnon
Modifications à la liste liée implique deux opérations:
Dans la Liste Liée, la seconde opération est un
O(1)
opération, c'est donc la question du coût des premières opérations.Lors de l'ajout au dernier nœud de la naïveté des implémentations de la liste liée entraînerait
O(n)
itération de temps. Cependant, la bonne liste liée bibliothèques de compte pour la plupart des utilisations courantes, cas particulier de l'accès au dernier nœud. Cette optimisation entraîneraitO(1)
récupération du dernier élément, entraînant l'ensembleO(1)
heure d'insertion à la fin.Comme pour le milieu, votre analyse est correcte en ce que la localisation du nœud serait également prendre
O(n)
. Cependant, certaines bibliothèques exposer une méthode qui permettrait de prendre un pointeur à l'endroit où le nouveau nœud doit être inséré plutôt que l'indice de référence (par exemple,C++
list
). Ceci élimine le linéaire des coûts, résultant en plus de tous lesO(1)
.Tout d'insertion vers le milieu est généralement considéré comme
O(n)
opération, il peut être optimisé pourO(1)
dans certains cas. C'est l'inverse de la matrice de liste, où l'insertion de l'opération elle-même (la deuxième opération) estO(n)
, comme tous les éléments dans des emplacements doivent être déplacés. Cette opération ne peut pas être optimisé.Pour insertation
Une implémentation naïve d'une liste chaînée entraînerait
O(n)
moment de l'insertion. Cependant, la bonne liste, bibliothèque des écrivains permettrait d'optimiser pour la plupart des cas, afin qu'ils puissent garder une référence à la dernière éléments (ou qui ont une liste chaînée circulaire de mise en œuvre), résultant en uneO(1)
moment de l'insertion.Comme pour l'insertion vers le milieu. Certaines bibliothèques, comme celle de
C++
, a un emplacement suggéré pour l'insertion. Ils prennent un pointeur vers le noeud de liste, où la nouvelle est d'être ajouté. De telles insertions coûteraitO(1)
. Je ne pense pas que vous pouvez obtenirO(1)
par numéro d'index.C'est apposée à un tableau, une liste d'insertion vers le milieu des forces de la réorganisation de tous les éléments de plus qu'elle, donc elle doit être un
O(n)
opération.OriginalL'auteur notnoop
Si vous n'avez pas muter les nœuds de votre (tout simplement) liste liée, vous avez besoin de O(n) le temps de l'insérer à une position arbitraire dans la liste (parce que vous devez copier tous les nœuds à partir du début de la liste à la position de l'élément nouveau. Il est O(1) pour une mutable liste si vous avez déjà un pointeur vers le nœud où vous souhaitez insérer un élément, et O(n) si vous avez à la recherche pour elle.
Dans les deux cas, vous avez seulement besoin de O(1) fois pour insérer un élément au début de la liste. Si vous avez souvent besoin d'insérer un élément dans le milieu de la liste (O(n) cas), vous devriez utiliser une autre structure de données.
OriginalL'auteur gnomnain
Par la Java LinkedList code source, Java permet d'atteindre le O(1) pour
LinkedList
queue opérations, en donnant laheader
Entrée un lien vers la queue de l'élément viaheader.previous
. Donc, si vous voulez le dernier élément, la classe peut toujours revenirheader.previous
, permettant à temps constant.Je suppose que beaucoup d'autres langues utilisent la même stratégie de base.
OriginalL'auteur Kaleb Brasee
Évidemment, vous avez probablement regardé l'article de wikipédia http://en.wikipedia.org/wiki/Linked_list. Je vois la table où ils sont en précisant que les deux l'insertion, la suppression de la fin et au milieu de la liste ont O(1) de la performance, mais ne parviennent pas à expliquer comment ils ont déterminé que.
Il y a quelques réponses intéressantes à une question similaire ici sur stackoverflow à Pourquoi est-insertion dans le milieu d'une liste liée O(1)?. L'affiche originale de la question editted son poste et fait un point qu'il croit que quand on dit que l'insertion/délétion est O(1) ils parlent le réel de l'opération d'insertion et de ne pas la constatation de l'emplacement d'insertion. Cela fait sens, mais je n'ai pas vu que formellement indiqué dans aucun des articles que j'ai trouvé à ce stade.
OriginalL'auteur Brian Hasden
Je pense qu'une des raisons de votre confusion est le fait que vous pensez que si il y a un idéal/canoniques liste liée, ce qui a ou n'a pas certaines de la tête/queue de pointeurs. La réalité est que tout linéaire (pas de branchement) structure de données qui accède à des éléments en passant par des pointeurs à partir des éléments précédents est essentiellement une liste liée. Si vous gardez des pointeurs de la première à la dernière, k-ième etc. éléments est entièrement à vous. Donc, si vous avez besoin d'une liste où vous avez souvent besoin d'insérer/supprimer des éléments à la 10e position, vous pouvez simplement mettre en œuvre celui qui possède un pointeur vers le 9e élément et de le faire en O(1) fois.
Une autre chose est que lors de l'itération sur les éléments d'une liste liée, vous pouvez insérer un nouvel élément juste après l'élément courant (et juste avant qu'il s'agit d'une double liste chaînée) en O(1), parce que vous avez déjà un pointeur.
OriginalL'auteur MAK
@Kaleb Brasee points, de l'insertion à la queue en Java est O(1) parce que Java utilise une liste à double liaison comme son
LinkedList
mise en œuvre. Je pense que c'est assez de choix pour beaucoup de SDK implémentations. Par exemple, la STLlist
mise en œuvre est doublement lié (source).OriginalL'auteur Hank Gay