Gibt es eine Datenstruktur für die schnelle Listenmanipulation und für Bestellabfragen?

9

Wir haben eine Menge von Listen von Elementen aus der Menge . Jedes Element von wird in einer einzigen Liste in . Ich suche eine Datenstruktur, die die folgenden Aktualisierungen durchführen kann:LN={1,2,3,...,n}NL

  1. concat(x,y) : Verkettet die Liste mit mit dem Ende der Liste mityx

  2. split(x) : Teilt die Liste mit direkt nachxx

Außerdem müssen die folgenden Abfragen ausgeführt werden:

  1. follows(x,y) : gibt zurück wenn und in derselben Liste sind und nach (aber nicht unbedingt neben )truexyyxx

  2. first(x) : Gibt das erste Element der Liste zurück, dasx

  3. next(x) : Gibt das nächste Element nach in der Liste zurück, diexx

Ich habe bereits eine Datenstruktur entwickelt, die diese Aktualisierungen in und Abfragen in Zeit durchführt. Mich interessiert vor allem, ob es bereits eine Datenstruktur gibt, die dies kann (hoffentlich schneller?).O(lg2(n))O(lg(n))

Motivation: Verwurzelte gerichtete Wälder können mit zwei dieser Listensätze dargestellt werden und ermöglichen eine schnelle Berechnung der Erreichbarkeit in solchen Wäldern. Ich möchte sehen, wofür sie sonst noch verwendet werden können und ob all dies bereits bekannt ist.

bbejot
quelle

Antworten:

11

Behalten Sie Ihre Ganzzahlen in Sprunglisten. Normale Sprunglisten sind nach Schlüsseln geordnet, aber wir werden sie nur als Darstellung von Sequenzen verwenden. Pflegen Sie außerdem ein Array von Zeigern der Größe . Jedes Element des Arrays sollte auf einen Knoten in einer Überspringliste verweisen. Ich glaube, dies unterstützt als in und alle anderen Operationen in .nnextO(1)O(lgn)

Speziell:

  • concat ing oder ting zwei Sprunglisten nimmt Zeit und damit Ungültigmachungseinträge höchstens Zeiger.splitO(lgn)O(lgn)
  • next folgt einfach dem Vorwärtszeiger auf Blattebene und benötigt Zeit.O(1)
  • firstdauert Zeit: Folgen Sie den Zeigern, bis Sie stecken bleiben, und folgen Sie dann einem linken Zeiger. Wenn Sie keinen linken Zeigern mehr folgen können, befinden Sie sich am Kopfzeiger Ihrer Überspringliste. Folgen Sie den Zeigern nach unten auf das Blatt und dann einem Vorwärtszeiger. Dies ist das erste Element in der Liste.O(lgn)
  • follows ist etwas kniffliger. Gehen Sie wie für , aber notieren Sie eine Liste der Werte, bei denen Sie stecken bleiben (dh bei denen Sie keine Zeiger mehr verfolgen können). Wir nennen diese Liste Sie zeichnen eine "Spur" auf. Machen Sie dasselbe für , aber folgen Sie den rechten Zeigern, wenn Sie stecken bleiben, nicht links. Wenn vor , schneiden sich ihre Spuren. Die Spuren haben die Größe . Wenn jedes Element in der Ablaufverfolgung mit der feststeckenden Ebene versehen ist, können wir nach einem Schnittpunkt in der Zeit .firstyxxyO(lgn)O(lgn)

next kommt der schlechteste Fall , alle anderen sind mit hoher Wahrscheinlichkeit . Sie können im schlimmsten Fall mithilfe deterministischer Sprunglisten erstellt werden.O(1)O(lgn)

Ich denke, kann zu werden, indem Bäume auf Blattebene (2,5) verwendet und die Stacheln verstärkt werden. Informationen zum Bootstrapping-Trick finden Sie unter " Rein funktionale Darstellungen verkettbarer sortierter Listen " von Kaplan und Tarjan.concatO(lglgn)

jbapple
quelle
cool. Ich dachte über Sprunglisten nach, konnte aber nicht genau sehen, wie ich ohne zugehörige Schlüsselwerte folgen sollte.
Sasho Nikolov
Das ist toll; Ich sehe, wie man alle Aktualisierungen deterministisch , was gut ist. Ich muss weiterlesen, um das O (lg lg (n)) zu verstehen. Danke für den Beitrag @jbapple. O(lg(n))
Bbejot
1

Das am wenigsten verbreitete Vorfahrenproblem kann verwendet werden, um das Erreichbarkeitsproblem in dynamisch verwurzelten Bäumen zu lösen. Ich kann mir daher vorstellen, dass Sie auch an folgenden Themen interessiert sind: Optimale Algorithmen zum Finden der nächsten gemeinsamen Vorfahren in dynamischen Bäumen von Alstrup und Thorup. In diesem Dokument wird eine Zeitgrenze von für Links und nca-Abfragen auf einem Zeigercomputer angegeben. O(n+mloglogn)nm

Shaun Harker
quelle
Vielen Dank für den Hinweis. Das nächstgelegene gemeinsame Vorfahrenproblem löst sicherlich die Erreichbarkeit von Bäumen. Das Papier, mit dem Sie verlinkt haben, beschreibt einen inkrementellen Baum mit allen Operationen in . Ich frage mich, ob es verbessert werden kann, auch mit volldynamischen Bäumen zu arbeiten. O(lglg(n))
Bejot