Gibt es eine bekannte Implementierung eines indizierten verlinkten Liste?
Mein Bauchgefühl sagt mir, es ist kein guter Weg, um dies zu erreichen, aber im Gegensatz zu Stephen Colbert, würde ich eher Vertrauen, eine Gemeinschaft von Entwicklern als mein Bauchgefühl...
Ist es eine bekannte Methode für die effiziente Umsetzung einer "best of both worlds" - Liste, eine, die bietet random access by index und O(1) einfügen/entfernen, wie eine verknüpfte Liste?
Ich sehe zwei mögliche Ergebnisse: entweder "Nein, das ist unmöglich, für die folgenden offensichtlichen Gründen..." oder "Uh, ja, das wurde getan; siehe hier, hier und hier."
InformationsquelleAutor Dan Tao | 2009-11-11
Schreibe einen Kommentar Antworten abbrechen
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich glaube nicht, dass es möglich sein wird, zu bekommen
O(1)
für beide einführen und lookup. Die minute, die Sie hinzufügen, ein array (oder auch Lust, teilbare Vektoren), die Einfügung wirdO(n)
.Gibt es Möglichkeiten zur Milderung der Schäden in Abhängigkeit vom erwarteten Verhalten Ihrer Liste. Wenn es eine Menge mehr lookups als Insertionen/Deletionen, kann es besser sein, nur Vektoren verwenden (variable-sized-arrays) - diese sind einigermaßen effizient, nicht ganz wie arrays, aber besser als die Traversierung von Listen (da diese Häufig werden Listen von arrays, es ist immer noch technisch traversieren einer Liste, sondern jedes element in der Liste hat in der Regel seine Größe, die macht es effizienter).
Wenn Einfüge-und Löschoperationen sind häufiger, können Sie den index erstellen ein fauler, so dass es nur dann gemacht, wenn erforderlich. Zum Beispiel, eingefügt und gelöscht werden, ändern Sie nur die verlinkten Liste Teil (und markieren Sie den index, wie schmutzig) - nur, wenn jemand versucht, verwenden Sie den index wird es wieder aufgebaut werden und markiert als sauber.
Können Sie noch optimieren, neu erstellen, indem Sie einen Datensatz der erste dirty Eintrag. Dies bedeutet, wenn Sie nur einfügen oder löschen in der letzten Hälfte der Liste, Sie brauchen nicht, um den Wiederaufbau der gesamten index, wenn jemand es benutzen möchte.
Einer Lösung, die ich einmal durchgeführt werden, wurde eine 2D-Liste. Damit meine ich:
Während dieses gemacht beiden einfügen und Suche in O(n), die balance war genau richtig. In einem reinen array-Lösung lookup
O(1)
und einfügen istO(n)
. Für einen reinen verkettete Liste, einfügenO(1)
(sobald Sie gefunden haben, die Einfügemarke, natürlich, ein Vorgang, der sichO(n)
) und lookupO(n)
.Die 2D-Liste ist
O(n)
für beide, aber mit einem geringeren Faktor. Wenn Sie schauen, um fügen, finden Sie in der rechten Spalte einfach durch die Untersuchung der ersten Zeile jeder Spalte ein. Dann Sie sich durch die Spalte selbst, der Suche nach der richtigen Zeile. Dann wird das Element eingefügt wird, und die Zählung für die Spalte erhöht. Ähnliches gilt für Löschungen, obwohl in diesem Fall die Zählung wird verringert, und die gesamte Spalte wird entfernt, wenn seine Zählung null erreicht.Für ein index-lookup, in den Sie sich durch die Spalten zu finden, die richtige Spalte, dann durchqueren Sie die Elemente in der Spalte zu bekommen, das richtige Element.
Und kann es sogar sein auto-Einstellung, indem Sie versuchen, halten Sie die maximale Höhe und Breite etwa die gleichen.
Wenn Sie denken, dass O(log N) == O(1),
check-out:
Wenn ich war die Implementierung einer verketteten Liste, in der Klasse, dachte ich über Optimierung des Zugriffs Zeit, indem 3 zusätzliche Felder: Der Knoten in der Mitte der Liste, wird der index der zuletzt aufgerufenen Knoten und der zuletzt aufgerufenen Knoten selbst.
Abrufen eines Knotens, die durch den index würde ich dann den ersten Blick auf alle verfügbaren Pfade zu erreichen, die den Knoten am gegebenen index und dann entschied sich für die billigste Weg, es zu tun. Die Möglichkeiten wären einfach:
Den Pfad mit den kleinsten Unterschied in unseren gewünschten index und wir starten mit index wäre die Günstigste option. Wenn keine Knoten zugegriffen wurde, doch der zuletzt besuchten Knoten gesetzt werden könnte, um den mittleren Knoten. Natürlich mit einer geraden Anzahl von Elementen gibt es keine eigentliche Mitte, also würde ich wählen Sie einfach den Boden von n/2.
Jedenfalls bin ich nie dazu gekommen, tatsächlich umzusetzen, diese Optimierung oder sogar wirklich zu analysieren, aber ich hoffe ich konnte helfen.
Ihr Bauch ist richtig auf dieser.
Verknüpften Listen in O(1) einfügen/löschen, weil die operation, die Sie durchführen, um einfügen oder entfernen, sowas ist einfach nur Umschalten ein paar von Zeigern (ein oder zwei auf das Objekt Sie einfügen, und ein oder zwei auf ein oder zwei andere Objekte). Dies ändert sich nicht durch die Größe der Liste, offensichtlich.
Einer skip-Liste geben Sie O(logn) - lookup, aber da bist du der Pflege einen index bedeutet es auch, O(logn) Einfügung/Löschung, weil dieser index muss aktuell gehalten werden.
Parallele Datenstruktur verwenden Sie für die Suche benötigen, um gepflegt werden, damit Ihre Komplexität wird die Skala, der index für die Komplexität.
Haben Sie ein bestimmtes problem im Kopf, das Sie lösen möchten?
Zum Beispiel, können Sie O(n) einfügen, entfernen und suchen, wenn Sie garantieren können, eine perfekte hash. Aber Sie müssen wissen, einige Dinge über Ihre Daten rechtzeitig, damit das funktioniert.
Wie etwa eine hash-Tabelle? Sie bekommen O(1) random-Zugriff durch Schlüssel und O(1) einfügen/löschen. Der Haken ist, dass die Einträge nicht geordnet.
Für eine effiziente Umsetzung der bestellten Sequenzen, check-out finger Bäumen. Sie geben Sie O(1) Zugriff auf
head
undlast
und O(log n) zufällige Zugang zu inneren Knoten. Einfügen oder löschen am Ende in O(1). Insbesondere die Umkehrung der ein-finger-Baum benötigt Konstante Zeit.Ich weiß nicht genau, wie BigO auf einfügen (als das würde variieren je nach Stichprobenumfang und-Wachstum), aber Java ist
java.util.LinkedList
würde sofort kommen in den Sinn.http://java.sun.com/j2se/1.5.0/docs/api/java/util/LinkedList.html
EDIT: ja, anscheinend unterhalb ist noch ein echter verkettete Liste und als solche indiziert wird, könnte sich O(n/2) ist natürlich formal O(n).
Konnte man immer Verschwendung, eine ganze Reihe von Raum und implementieren eine Liste Implementierung, hält eine parallel verkettete Liste und array mit latenten einfügen/entfernen.
Während ich dont denke, dass kann man ganzzahlige Indizierung, eine Unterlage, hashtable könnte funktionieren, wenn Sie mit 'Referenz -' - Typen.
Java
LinkedList
hat O(n) Zugriff für indiziert wird.LinkedList
erstrecktAbstractSequentialList
zu zeigen, dass es nicht in O(1) indexiert wird.Ich würde vorschlagen, dass Sie einen Blick auf Apache ist TreeList. Es bietet in O(log n) INSERT/Umzüge und O(1) - indexed-lookups.
get(Object)
und/oder ein indexget(index)
. Wenn auf indizierte bekommt, ich Rede von der zweiten, wo Sie wollen das N-te Element in der Liste.