Suche nach spezieller C ++ - Datenstruktur

8

Ich suche nach einer C ++ - Implementierung einer Datenstruktur (oder einer Kombination von Datenstrukturen), die die folgenden Kriterien erfüllen:

    Auf
  • Elemente wird wie in std :: vector
  • zugegriffen
  • bietet einen Direktzugriffs-Iterator (zusammen mit dem Iterator-Vergleich & lt;, & gt;)
  • durchschnittlicher Artikel Zugriff (: lookup) Zeit ist im schlimmsten Fall O(log(n)) Komplexität
  • Elemente werden in der gleichen Reihenfolge durchlaufen, in der sie dem Container hinzugefügt wurden
  • Bei einem Iterator kann ich die Ordinalposition des Objekts ermitteln, auf das im Container verwiesen wird, im schlimmsten Fall von O(log(n)) complexity
  • ermöglicht das Einfügen und Entfernen von Elementen an bestimmten Positionen von schlimmstenfalls O(log(n)) complexity
  • Entfernen / Einfügen von Elementen macht zuvor erhaltene Iteratoren nicht ungültig.

Vielen Dank im Voraus für Anregungen

Dalibor

(Bearbeiten) Antworten:

Die von mir gewählte Antwort beschreibt eine Datenstruktur, die alle diese Anforderungen erfüllt. Boost :: multi_index, wie von Maxim Yegorushkin vorgeschlagen, bietet jedoch sehr ähnliche Funktionen.

(Bearbeiten) Einige der Anforderungen wurden nicht korrekt angegeben. Sie sind nach korrektur (: original)

modifiziert

(Bearbeiten) Ich habe eine Implementierung der in der angenommenen Antwort beschriebenen Datenstruktur gefunden. Bis jetzt funktioniert es wie erwartet. Es heißt Counter-Struktur

(Bearbeiten) Ziehen Sie in Betracht, das von sp2danny vorgeschlagene AVL-Array zu verwenden.

    
Dalibor Frivaldsky 10.08.2011, 12:13
quelle

5 Antworten

3

Gehen wir durch diese ...

  
  • Die durchschnittliche Suchzeit für Elemente ist im schlimmsten Fall die Komplexität von O (log (n))
  •   
  • Entfernen / Einfügen von Elementen macht zuvor erhaltene Iteratoren nicht ungültig.
  •   
  • ermöglicht das Einfügen und Entfernen von Elementen im schlimmsten Fall O (log (n)) Komplexität
  •   

Das schreit ziemlich "Baum".

  
  • bietet einen Direktzugriffs-Iterator (zusammen mit dem Iterator-Vergleich & lt;, & gt;)
  •   
  • Bei einem Iterator kann ich die Ordinalposition des Objekts ermitteln, auf das im Container verwiesen wird, im schlimmsten Fall von O (log (n)) complexity
  •   
  • Elemente werden in der gleichen Reihenfolge durchlaufen, in der sie dem Container hinzugefügt wurden
  •   

Ich gehe davon aus, dass der Index, den Sie für den Direktzugriffs-Iterator bereitstellen, in der Reihenfolge der Einfügung ist, also wäre [0] das älteste Element im Container, [1] wäre das nächstälteste usw. bedeutet, dass der Iterator intern den Index nicht speichern kann, da er sich ohne vorherige Benachrichtigung ändern kann, damit die Iteratoren gültig sind. Also einfach mit map mit dem Schlüssel zu arbeiten, der die Reihenfolge der Insertion nicht funktioniert.

Jeder Knoten in Ihrem Baum muss zusätzlich zu seinen üblichen Mitgliedern die Anzahl der Elemente in jedem Teilbaum verfolgen. Dies ermöglicht einen wahlfreien Zugriff mit O(log(N)) time. Ich kenne keinen fertigen Code, aber die Unterklassen std::rb_tree und std::rb_node wären mein Ausgangspunkt.

    
Mike DeSimone 10.08.2011, 12:33
quelle
4

Basierend auf Ihren Anforderungen macht boost::multi_index mit zwei Indizes den Trick.

Der erste Index ist geordneter Index . Es ermöglicht O (log (n)) einfügen / suchen / entfernen. Der zweite Index ist Direktzugriffsindex . Es ermöglicht einen wahlfreien Zugriff und die Elemente werden in der Reihenfolge des Einfügens gespeichert. Für beide Indizes werden Iteratoren nicht ungültig gemacht, wenn andere Elemente entfernt werden. Die Konvertierung von einem Iterator in einen anderen ist O (1) Operation.

    
Maxim Egorushkin 10.08.2011 12:26
quelle
0

Siehe hier: STL-Container (scrollen Sie auf der Seite nach unten, um Informationen zur algorithmischen Komplexität zu erhalten), und ich denke, std::deque entspricht Ihren Anforderungen.

    
yasouser 10.08.2011 12:16
quelle
0

AVL-Array sollte der Rechnung entsprechen.

    
sp2danny 24.06.2014 13:57
quelle
0

Hier ist mein "lv" -Container, der die Anforderung erfüllt, O (log n) einzufügen / löschen / Zugriffszeit.     Ссылка

Der Container ist nur Header-C ++ - Bibliotheken, und hat den gleichen Iterator und funktioniert mit anderen C ++ - Containern wie Liste und Vektor.

Der

"lv" -Behälter basiert auf dem rb-Baum, wobei jeder Knoten einen Größenwert über die Anzahl der Knoten in dem Unterbaum hat. Durch Überprüfung der Größe des linken / rechten Kinds eines Baumes können wir schnell auf den Knoten zugreifen.

    
xhawk18 22.11.2014 14:37
quelle