Ich habe eine Reihe von Objekten in einer flachen Struktur. Diese Objekte haben eine ID
und eine ParentID
Eigenschaft, sodass sie in Bäumen angeordnet werden können. Sie sind in keiner bestimmten Reihenfolge. Jede ParentID
Eigenschaft stimmt nicht unbedingt mit einer ID
in der Struktur überein . Daher könnten mehrere Bäume aus diesen Objekten hervorgehen.
Wie würden Sie diese Objekte verarbeiten, um die resultierenden Bäume zu erstellen?
Ich bin nicht so weit von einer Lösung entfernt, aber ich bin sicher, dass sie alles andere als optimal ist ...
Ich muss diese Bäume erstellen, um dann Daten in der richtigen Reihenfolge in eine Datenbank einzufügen.
Es gibt keine Zirkelverweise. Ein Knoten ist ein RootNode, wenn ParentID == null ist oder wenn ParentID in den anderen Objekten nicht gefunden werden kann
quelle
Antworten:
Speichern Sie die IDs der Objekte in einer Hash-Tabelle, die dem jeweiligen Objekt zugeordnet ist. Führen Sie eine Aufzählung aller Objekte durch und suchen Sie deren übergeordnetes Element, falls vorhanden, und aktualisieren Sie den übergeordneten Zeiger entsprechend.
quelle
Basierend auf der Antwort von Mehrdad Afshari und dem Kommentar von Andrew Hanlon für eine Beschleunigung, hier ist meine Meinung.
Wichtiger Unterschied zur ursprünglichen Aufgabe: Ein Stammknoten hat die ID == parentID.
quelle
Hier ist ein einfacher JavaScript-Algorithmus zum Parsen einer flachen Tabelle in eine übergeordnete / untergeordnete Baumstruktur, die in N-Zeit ausgeführt wird:
quelle
console.log(JSON.stringify(root, null, 2));
diese Option, um die Ausgabe hübsch zu drucken.Python-Lösung
Beispielsweise:
Produziert:
quelle
def recurse(id, pages): for row in rows: if row['id'] == id: print(f'''{row['id']}:{row['parent_id']} {row['path']} {row['title']}''') recurse(row['id'], rows)
JS-Version, die eine Wurzel oder ein Array von Wurzeln zurückgibt, von denen jede eine untergeordnete Array-Eigenschaft enthält, die die zugehörigen untergeordneten Elemente enthält. Hängt nicht von der geordneten Eingabe ab, ist anständig kompakt und verwendet keine Rekursion. Genießen!
quelle
Hier finden Sie eine großartige JavaScript-Version: http://oskarhane.com/create-a-nested-array-recursively-in-javascript/
Angenommen, Sie haben ein Array wie dieses:
Und Sie möchten, dass die Objekte wie folgt verschachtelt sind:
Hier ist eine rekursive Funktion, die dies ermöglicht.
Verwendung:
quelle
Beachten Sie für alle, die an einer C # -Version von Eugenes Lösung interessiert sind, dass auf node_list als Karte zugegriffen wird. Verwenden Sie stattdessen ein Wörterbuch.
Beachten Sie, dass diese Lösung nur funktioniert, wenn die Tabelle nach parent_id sortiert ist .
Der Knoten ist wie folgt definiert.
quelle
new Node { parent_id = 7, id = 9 },
verhindertnode_list.Add(item.id, item);
abzuschließen , weil Schlüssel nicht wiederholen können; es ist ein Tippfehler; Anstatt also id = 9 , Typ - ID = 8Ich habe eine generische Lösung in C # geschrieben, die lose auf der Antwort von @Mehrdad Afshari basiert:
quelle
Hier ist eine Java-Lösung der Antwort von Mehrdad Afshari.
quelle
Vage, wie mir die Frage erscheint, würde ich wahrscheinlich eine Karte von der ID zum eigentlichen Objekt erstellen. In Pseudo-Java (ich habe nicht überprüft, ob es funktioniert / kompiliert) könnte es so etwas sein wie:
Und um jeden Elternteil nachzuschlagen:
Durch Wiederverwenden
getRealObject(ID)
und Erstellen einer Zuordnung von Objekt zu einer Sammlung von Objekten (oder deren IDs) erhalten Sie auch eine übergeordnete> untergeordnete Zuordnung.quelle
Ich kann dies in 4 Codezeilen und O (n log n) Zeit tun, vorausgesetzt, Dictionary ist so etwas wie eine TreeMap.
BEARBEITEN : Ok, und jetzt habe ich gelesen, dass einige Eltern-IDs gefälscht sind. Vergessen Sie also das Obige und machen Sie Folgendes:
quelle
Bei den meisten Antworten wird davon ausgegangen, dass Sie dies außerhalb der Datenbank tun möchten. Wenn Ihre Bäume relativ statisch sind und Sie die Bäume nur irgendwie der Datenbank zuordnen müssen, sollten Sie möglicherweise verschachtelte Mengenrepräsentationen auf der Datenbankseite verwenden. Schauen Sie sich Bücher von Joe Celko an (oder hier für eine Übersicht von Celko).
Wenn sie ohnehin an Oracle dbs gebunden sind, überprüfen Sie deren CONNECT BY auf direkte SQL-Ansätze.
Bei beiden Ansätzen können Sie die Zuordnung der Bäume vollständig überspringen, bevor Sie die Daten in die Datenbank laden. Ich dachte nur, ich würde dies als Alternative anbieten, es könnte für Ihre spezifischen Bedürfnisse völlig ungeeignet sein. Der gesamte Teil der ursprünglichen Frage "richtige Reihenfolge" impliziert etwas, dass die Reihenfolge aus irgendeinem Grund in der Datenbank "korrekt" sein muss. Dies könnte mich dazu bringen, auch dort mit den Bäumen umzugehen.
quelle
Es ist nicht genau das gleiche, wonach der Fragesteller gesucht hat, aber ich hatte Schwierigkeiten, mich mit den hier angegebenen mehrdeutigen Antworten zu befassen, und ich denke immer noch, dass diese Antwort unter den Titel passt.
Meine Antwort besteht darin, eine flache Struktur einem Baum direkt auf dem Objekt zuzuordnen, in dem Sie nur ein
ParentID
Objekt für jedes Objekt haben.ParentID
istnull
oder0
wenn es eine Wurzel ist. Gegenüber dem Fragesteller gehe ich davon aus, dass alle gültigenParentID
Punkte auf etwas anderes in der Liste verweisen:quelle
Hier ist eine Ruby-Implementierung:
Es wird nach Attributname oder Ergebnis eines Methodenaufrufs katalogisiert.
quelle
Die akzeptierte Antwort erscheint mir viel zu komplex, daher füge ich eine Ruby- und eine NodeJS-Version hinzu
Angenommen, die Liste der flachen Knoten hat die folgende Struktur:
Die Funktionen, die die flache Listenstruktur oben in einen Baum verwandeln, sehen folgendermaßen aus
für Ruby:
für NodeJS:
quelle
null
muss sein fürundefined
null == undefined => true
in NodeJSEine elegante Möglichkeit, dies zu tun, besteht darin, Elemente in der Liste als Zeichenfolge darzustellen, die eine durch Punkte getrennte Liste der Eltern und schließlich einen Wert enthält:
Wenn Sie einen Baum zusammenbauen, erhalten Sie Folgendes:
Ich habe eine Konfigurationsbibliothek , die diese Überschreibungskonfiguration (Baum) aus Befehlszeilenargumenten (Liste) implementiert. Der Algorithmus zum Hinzufügen eines einzelnen Elements zur Liste zu einem Baum ist hier .
quelle
Verwenden Sie nur diese Attribute? Wenn nicht, kann es hilfreich sein, ein Array von untergeordneten Knoten zu erstellen, in denen Sie alle diese Objekte einmal durchlaufen können, um solche Attribute zu erstellen. Wählen Sie von dort aus den Knoten mit Kindern, aber keinen Eltern aus, und erstellen Sie Ihren Baum iterativ von oben nach unten.
quelle
Java-Version
quelle