2009-05-08 6 views
63

Gemäß Wikipedia article on linked lists wird das Einfügen in der Mitte einer verknüpften Liste als O (1) betrachtet. Ich würde denken, es wäre O (n). Müsstest du nicht den Knoten finden, der sich am Ende der Liste befinden könnte?Warum wird in der Mitte einer verknüpften Liste O (1) eingefügt?

Berücksichtigt diese Analyse nicht das Finden der Knotenoperation (obwohl es erforderlich ist) und nur die Einfügung selbst?

EDIT:

verlinkte Listen haben mehrere Vorteile gegenüber Arrays. Das Einfügen eines Elements an einem bestimmten Punkt einer Liste ist eine Operation mit konstanter Zeit, während das Einfügen in ein Array möglicherweise die Hälfte der Elemente oder mehr erfordert.

Die obige Aussage ist ein wenig irreführend für mich. Korrigieren Sie mich, wenn ich falsch liege, aber ich denke, sollte die Schlussfolgerung sein:

Arrays:

  • Finden der Punkt Einfügen/Löschen O (1)
  • Durchführen der Einfügen/Löschen O (n)

verlinkte Listen:

  • den Punkt Einfügen/Löschen O (n)
  • Durchführen der Einfügen/Löschen O (1)

Ich denke, das einzige Mal, Sie würden nicht finden die Position ist, wenn Sie einige Finding gehalten Art von Zeiger darauf (wie in einigen Fällen mit dem Kopf und dem Schwanz). Wir können also nicht einfach sagen, dass verknüpfte Listen immer Arrays für Einfüge-/Löschoptionen übertreffen.

+4

Nicht * ziemlich * ein Duplikat. Die vorherige Frage konzentrierte sich auf dynamische Arrays und verwendete verkettete Listen als Vergleichsgrundlage. –

Antwort

75

Sie haben Recht, der Artikel betrachtet "Indizierung" als eine separate Operation. Also ist die Einfügung selbst O (1), aber zu diesem mittleren Knoten gelangt man zu O (n).

+2

Was macht einen größeren Unterschied, wenn mehr als ein Objekt an der gleichen Stelle eingefügt wird ... –

+0

@ Anony-Mousse können Sie es ein bisschen mehr erklären? d. h. wir müssen die Einfügeposition nur einmal beim Einfügen mehrerer Objekte finden? – MyTitle

+1

Es ist O (n) in der Größe der vorhandenen Liste, nicht die Anzahl der Einfügungen, die Sie dort machen wollen. –

3

Weil es keine Schleifen beinhaltet.

Einfügen ist wie:

  • Einsatzelement
  • Link zum vorherigen
  • Link zu dem nächsten
  • getan

dies in jedem Fall konstant Zeit.

Folglich ist das Einfügen von n Elementen nacheinander O (n).

2

Einfügen ist O (1) sobald Sie wissen, wo Sie es hinstellen werden.

17

Nein, wenn Sie sich entscheiden, dass Sie einfügen möchten, wird angenommen, dass Sie sich bereits in der Mitte der Liste befinden.

Operationen auf verknüpften Listen werden oft so durchgeführt, dass sie nicht wirklich als generische "Liste" behandelt werden, sondern als eine Ansammlung von Knoten - denken Sie an den Knoten selbst als Iterator für Ihre Hauptschleife. Wenn Sie also durch die Liste stochern, bemerken Sie als Teil Ihrer Geschäftslogik, dass ein neuer Knoten hinzugefügt (oder ein alter gelöscht) werden muss, und Sie tun dies. Sie können 50 Knoten in einer einzigen Iteration hinzufügen.

Edit: Mann, du tippst einen zweiten Absatz ein und plötzlich bist du nicht der Ersthelfer, sondern der 5., der dasselbe sagt wie die ersten 4!

+0

Ha ja das saugt ... ich + 1'd, weil es wert ist, zu sagen, dass die Komplexität der Einfügung von verbundenen Listen in dem Kontext betrachtet wird, in dem bereits der gewünschte Zeiger ist. –

3

Berücksichtigt diese Analyse nicht das Finden der Knotenoperation (obwohl es erforderlich ist) und nur die Einfügung selbst?

Sie haben es. Die Insertion an einem gegebenen Punkt geht davon aus, dass Sie bereits einen Zeiger auf das Element halten, die Sie einfügen möchten nach:

InsertItem(item * newItem, item * afterItem) 
14

Das Einsetzen selbst O (1) ist. Knoten finden ist O (n).

0

In diesem Artikel geht es darum, Arrays mit Listen zu vergleichen. Das Finden der Einfügeposition für Arrays und Listen ist O (N), so dass der Artikel sie ignoriert.

+1

Wäre nicht der Einfügepunkt eines Arrays O (1)? Da Arrays im zusammenhängenden Speicher gespeichert sind, muss nur der Offset hinzugefügt werden. –

+0

Das wäre Indexierung. – Brian

+0

@ vg1890 - Sie müssen zuerst den Offset finden. –

0

O (1) ist abhängig von dieser Tatsache, dass Sie einen Artikel haben, wo Sie den neuen Artikel einfügen werden. (vorher oder nachher). Wenn du es nicht tust, ist es O (n), weil du diesen Gegenstand finden musst.

2

Nein, es berücksichtigt nicht die Suche. Wenn Sie jedoch bereits einen Zeiger auf ein Element in der Mitte der Liste haben, wird an diesem Punkt O (1) eingefügt.

Wenn Sie suchen müssen, müssen Sie die Zeit für die Suche hinzufügen, die O (n) sein sollte.

0

Ich denke, es ist nur ein Fall von dem, was Sie für die O() Notation zählen. Im Falle des Einfügens der normalen Operation zum Zählen sind Kopiervorgänge. Bei einem Array wird beim Einfügen in der Mitte alles oberhalb des Speicherorts kopiert. Bei einer verknüpften Liste werden zwei Zeiger gesetzt. Sie müssen den Standort finden, egal was eingefügt wird.

5

Für den Vergleich mit einem Array, was das Diagramm zeigt, ist es O (1), weil Sie nicht alle Elemente nach dem neuen Knoten verschieben müssen.

Also ja, sie gehen davon aus, dass Sie bereits den Zeiger auf diesen Knoten haben, oder dass das Abrufen des Zeigers trivial ist. Mit anderen Worten, das Problem wird angegeben: "gegeben Knoten bei X, was ist der Code nach diesem Knoten einfügen?" Sie beginnen am Einfügepunkt.

0

Wenn Sie die Referenz des einzufügenden Knotens haben, nachdem die Operation O (1) für eine verkettete Liste ist.
Für ein Array ist es immer noch O (n), da Sie alle konsekutiven Knoten verschieben müssen.

0

Die häufigsten Fälle sind wahrscheinlich am Anfang oder am Ende der Liste einfügen (und die Enden der Liste kann keine Zeit zu finden).

Vergleichen Sie das mit dem Einfügen von Elementen am Anfang oder am Ende eines Arrays (die Größe des Arrays erfordert, wenn es am Ende ist, oder die Größe ändern und verschieben alle Elemente, wenn es am Anfang ist).

+0

Es ist möglich, das Einfügen von Elementen in das Ende eines Arrays mit O (1) zu machen, wenn Sie am Ende einen Puffer mit leeren Elementen behalten, obwohl gelegentlich die Einfügungen immer noch O (1) sind. Die meisten Sammlungen tun dies. Es ist auch möglich, inertisierende Elemente an den Anfang eines Arrays mit O (1) zu setzen, indem Sie Ihren Indexoperator so ändern, dass die Elementnummer (n + x)% len zurückgegeben wird. Dabei steht x für die Anzahl der Einfügungen von Elementen an den Anfang der Liste. Deques werden manchmal so implementiert (manchmal werden sie auch mit doppelt verknüpften Listen implementiert). – Brian

3

Die Einfügung in eine verkettete Liste unterscheidet sich von der Iteration.Sie finden den Gegenstand nicht, Sie setzen Zeiger zurück, um den Gegenstand dorthin zu setzen. Es spielt keine Rolle, ob es in der Nähe des vorderen Endes oder nahe dem Ende eingefügt wird, die Einfügung bezieht sich immer noch auf Zeiger, die neu zugewiesen werden. Es hängt natürlich davon ab, wie es implementiert wurde, aber das ist die Stärke von Listen - Sie können sie einfach einfügen. Der Zugriff über den Index ist der Ort, an dem ein Array leuchtet. Für eine Liste ist es normalerweise O (n), den n-ten Gegenstand zu finden. Zumindest erinnere ich mich an die Schule.