Speichern möchten binäre Struktur auf der Festplatte für das "20-Fragen" - Spiel
Kurz gesagt, ich würde es gerne lernen/entwickeln, die eine elegante Methode zum speichern eines binären Baums auf der Festplatte (eine Allgemeine Struktur, die nicht unbedingt eine BST). Hier ist die Beschreibung meines Problems:
Ich bin Implementierung ein Spiel der "20-Fragen". Ich habe geschrieben ein binärer Baum, dessen innere Knoten sind Fragen und lässt Antworten gibt. Das linke Kind eines Knotens ist der Weg, dem Sie Folgen würden, wenn jemand antwortete "ja" zu Ihrer aktuellen Frage, während das Rechte Kind ist ein "Nein" zu beantworten. Hinweis: dies ist nicht eine binäre Suche Baum, nur ein binärer Baum, dessen linke Kind ist "ja" und rechts "Nein".
Das Programm fügt einen Knoten zu einem Baum, wenn er auf ein Blatt, das null ist, indem der Benutzer gefragt wird, unterscheiden Sie Ihre Antwort von der einen war der computer zu denken.
Dies ist ordentlich, weil der Baum baut sich auf wie der Benutzer spielt. Was nicht ordentlich ist, dass ich nicht haben eine gute Möglichkeit zum speichern des Baumes auf der Festplatte.
Habe ich mir Gedanken über die Rettung der Baum als array-Darstellung (für Knoten i, linke Kind ist 2i+1 und 2i+2, (i-1)/2 für die Eltern), aber es ist nicht sauber, und ich am Ende mit sehr viel Platz verschwendet.
Ideen für eine elegante Lösung zum speichern eines sparse binary tree auf der Festplatte?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Können Sie es speichern, rekursiv:
Entwickeln Ihre eigenen weniger texty Ausgabe-format. Ich bin sicher, ich brauche nicht zu beschreiben die Methode zum Lesen der Ausgabe.
Dies ist depth-first-traversal. Zuerst der Breite funktioniert auch.
Ich würde eine Level-order-traversal. Das heißt, Sie sind im Grunde tun, eine Breite-zuerst-Suche Algorithmus.
Haben Sie:
Level-order-traversal Reihenfolge: F, B, G, A, D, I, C, E, H
Was Sie speichern auf dem Datenträger: F, B, G, A, D, NullNode, ich, NullNode, NullNode, C, E, H, NullNode
Laden von der Festplatte ist noch einfacher. Lesen Sie einfach von Links nach rechts die Knoten, die Sie auf der Festplatte gespeichert. Dies wird Ihnen jeder Ebene der linken und rechten Knoten. I. e. der Baum füllt sich von oben nach unten von Links nach rechts.
Schritt 1 Lesen in:
Schritt 2 Lesen in:
Schritt 3 Lesen in:
Schritt 4 Lesen in:
Und so weiter ...
Hinweis: wenn Sie einen NULL-Knoten-Darstellung, die Sie nicht mehr benötigen, um die Liste seiner Kinder auf die Festplatte. Beim laden zurück, werden Sie wissen, zu überspringen, um den nächsten Knoten. Also für sehr Tiefe Bäume, diese Lösung wird immer noch effizient sein.
Einen einfachen Weg, dies zu erreichen, Durchlaufen den Baum Ausgabe jedes element, wie Sie das tun. Dann laden Sie den Baum wieder, einfach Durchlaufen Ihre Liste einfügen, die jedes element wieder in den Baum. Wenn Sie Ihren Baum nicht selbst balancing, möchten Sie vielleicht die Reihenfolge der Liste in einer Weise, dass der endgültige Baum ist einigermaßen ausgewogen.
Nicht sicher, es ist elegant, aber es ist einfach und erklärbar:
Eine eindeutige ID zuweisen, um jeden Knoten, ob stengel oder Blätter. Ein einfaches zählen integer tun.
Beim speichern auf der Festplatte, Durchlaufen den Baum und speichert jede Knoten-ID", "ja" link-ID "kein" link-ID und den text der Frage oder Antwort. Für null-links, verwenden Sie null als null-Wert. Sie können entweder fügen Sie eine Flagge, um anzuzeigen, ob Frage oder Antwort, oder einfacher, zu überprüfen, ob beide links sind null. Sie sollten etwas wie diese:
Beachten Sie, dass wenn Sie verwenden die sequentielle Ganzzahlen Ansatz, speichern die Knoten-ID kann redundant sein, wie hier gezeigt. Sie konnte einfach legen Sie Sie in der Reihenfolge von ID.
Zur Wiederherstellung von Festplatte, eine Zeile Lesen, dann fügen Sie es an den Baum. Sie werden wahrscheinlich brauchen eine Tabelle oder ein array zu halten, weiterleiten-referenzierten Knoten, z.B. bei der Verarbeitung von Knoten 1, halten Sie track 2 und 3, bis Sie diese Werte.
Die beliebige einfache Art und Weise ist nur eine grundlegende format, das verwendet werden kann, zum darstellen von jeder Grafik.
Ie:
Gibt es nicht viel Redundanz hier, und die Formate, die meist von Menschen lesbar, die nur die Duplizierung der Daten ist, dass es eine Kopie von einem Elternteil für jedes direkte Kind es hat.
Die einzige Sache, die Sie wirklich achten müssen ist, dass Sie nicht versehentlich erzeugen einen Zyklus 😉
Es sei denn, das, was Sie wollen.
Dies ist der Grund, warum ich traditionell nur verwenden graph-Strukturen im Speicher für so ein Ding mit Zeigern geht überall.
Dann das "Kind/Eltern" - Konnektivität ist lediglich Metadaten.
In java, wenn Sie waren, um eine Klasse serializeable Sie können schreiben Sie einfach die Objekt-Klasse-disc und Lesen Sie wieder mit input/output-streams.
Ich würde lagern Sie den Baum wie diesem:
wo die Kind Knoten werden nur rekursive Instanzen der oben genannten. Die bits in [] sind optional, und die vier Kennungen sind nur Konstanten/enum-Werte.
Hier ist der C++ - code mit PreOrder-DFS:
In
main()
Sie tun können:Die DFS ist einfacher zu verstehen.
Aber wir können level-scan BFS mit Hilfe des queue -
In
main()
Sie tun können: