Ich habe kürzlich gelesen, dass es möglich ist, Arrays zu haben, die nicht initialisiert werden müssen, dh, es ist möglich, sie zu verwenden, ohne Zeit aufwenden zu müssen, um jedes Mitglied auf den Standardwert zu setzen. Das heißt, Sie können das Array so verwenden, als ob es mit dem Standardwert initialisiert worden wäre, ohne es initialisieren zu müssen. (Entschuldigung, ich kann mich nicht erinnern, wo ich das gelesen habe).
Zum Beispiel, warum das überraschend sein kann:
Angenommen, Sie versuchen, einen Worst- Case zu modellieren -Hashtabelle für den(für jede Einfügung / Löschung / Suche) von Ganzzahlen im Bereich.
Sie können ein Array mit einer Größe von Bits zuweisen und einzelne Bits verwenden, um die Existenz einer Ganzzahl in der Hashtabelle darzustellen. Hinweis: Das Zuweisen von Speicher wird als -Zeit betrachtet.
Wenn Sie dieses Array überhaupt nicht initialisieren mussten, ist jetzt eine beliebige Folge von Operationen für diese Hashtabelle der ungünstigste Fall .
Tatsächlich haben Sie also eine "perfekte" Hash-Implementierung, die für eine Folge von Operationen den Raum verwendet, aber in der Zeit wird!
Normalerweise würde man erwarten, dass Ihre Laufzeit mindestens so schlecht ist wie Ihr Platzbedarf!
Hinweis: Das obige Beispiel könnte für die Implementierung einer Gruppe mit geringer Dichte oder einer Matrix mit geringer Dichte verwendet werden, daher ist es vermutlich nicht nur von theoretischem Interesse.
Die Frage ist also:
Wie ist es möglich, eine Array-ähnliche Datenstruktur zu haben, die es uns ermöglicht, den Initialisierungsschritt zu überspringen?
quelle
Antworten:
Dies ist ein sehr allgemeiner Trick, der für andere Zwecke als für das Hashing verwendet werden kann. Unten gebe ich eine Implementierung (in Pseudocode).
Es seien drei nicht initialisierte Vektoren , P und V der Größe n . Wir werden diese verwenden, um die von unserer Datenstruktur angeforderten Operationen durchzuführen. Wir halten auch eine Variable p o s . Die Operationen werden wie folgt implementiert:A P V n pos
Das Array speichert einfach die Werte , die durch die übergeben werden , s e t - Verfahren. Die Arrays V und P funktionieren als Zertifikate, die anzeigen, ob eine bestimmte Position in A initialisiert wurde.A set V P A
Beachten Sie, dass die Elemente in jedem Augenblick im Bereich von 0 bis p o s - 1 initialisiert werden. Wir können diese Werte daher sicher als Zertifikat für die initialisierten Werte in A verwenden . Für jede Position i in A , die initialisiert wird, gibt es ein entsprechendes Element im Vektor P, dessen Wert gleich i ist . Dies wird durch V [ i ] gezeigt . Betrachten wir also das entsprechende Element, so ist P [ V [ i ] ] und sein Wert iP 0 pos−1 A i A P i V[i] P[V[i]] i , wir wissen, dass initialisiert wurde (da P niemals lügt, weil alle Elemente, die wir betrachten, initialisiert sind). In ähnlicher Weise kann, wenn A [ i ] nicht initialisiert ist, V [ i ] entweder auf eine Position in P außerhalb des Bereichs 0 ... p o s - 1 zeigen , wenn wir sicher sind, dass es nicht initialisiert ist, oder auf eine Position in diesem Bereich. Aber dieses besondere P [ j ] entspricht einer anderen Position in A und daherA[i] P A[i] V[i] P 0..pos−1 P[j] A , daher wissen wir, dass A [ i ] nicht initialisiert wurde.P[j]≠i A[i]
Es ist leicht zu erkennen, dass all diese Vorgänge in konstanter Zeit ausgeführt werden. Außerdem verwendet der Raum ist für jeden der Vektoren und O ( 1 ) für die Variable p o s , also O ( n ) insgesamt.O(n) O(1) pos O(n)
quelle