Baum-wie Datastructure (für die Verwendung mit VirtualTreeview)
Komme ich zu dem Punkt, wo ich aufhören müssen der Speicherung meiner Daten in eine VCL-Komponente, und eine "zugrunde liegende datastructure", wie Herr Rob Kennedy vorgeschlagen.
Zunächst, diese Frage ist "wie mache ich eine zugrunde liegende datastructure". 🙂
Meine Hierarchie besteht aus 2 Ebenen von Knoten.
Gerade jetzt, ich gehe durch meine Sachen durch looping rootnodes, wobei ich eine loop-thru des Stammknotens ist childnodes, zu bekommen, was ich brauche (Daten). Ich würde lieben im Stande zu sein, die zum speichern aller meiner Daten in eine so genannte Zugrunde liegende Datastructure, so dass ich können Sie leicht ändern Sie die Einträge, die Verwendung von threads (ich glaube, ich bin in der Lage, das zu tun?)
Jedoch, wenn die Schleife durch meine Einträge (jetzt), die Ergebnisse sind abhängig von den Knoten, die Checkstate - wenn ich mich mit einer zugrunde liegenden Daten-Struktur, wie weiß ich, ob mein Knoten markiert ist oder nicht, wenn Ihr meine datastructure ich eine loop-thru, und nicht meine Knoten?
Sagen wir, ich wollte mit 2 Ebenen.
Wäre dies die Eltern:
TRoot = Record
RootName : String;
RootId : Integer;
Kids : TList; //(of TKid)
End;
Und das Kind:
TKid = Record
KidName : String;
KidId : Integer;
End;
Das ist im Grunde das, was ich jetzt tun soll. Kommentare, dass dies nicht die beste Lösung, so bin ich für Vorschläge offen. 🙂
Ich hoffe, Sie verstehen meine Frage(N). 🙂
Dank!
- IMHO, deine Frage ist nicht verständlich für alle, die nicht gelesen haben, Ihre vorherigen Fragen, für was Sie nicht links (als letzten Ausweg), aber es ist besser, wenn Sie schreiben jede Frage, als ob es die einzige Frage, die Sie hier gepostet. So wird die Frage leicht beantwortbar durch jedermann, aber am wichtigsten ist, es wird verständlich sein für den zukünftigen Leser.
- Ich bin froh, dass Sie mir sagen, werden versuchen zu finden, den vorherigen post. 🙂
- bearbeitet. 🙂
- Nichts für ungut, aber wenn ich habe Dinge richtig, Sie sind ein Anfänger-Programmierer-aber wenn Sie halten Sie das lernen, werden Sie (in ein paar Jahren), master-Programmierung auf einer viel anspruchsvolleren Ebene. Bis dann, ich denke aber, es ist nicht klug, zu versuchen zu hart, die Dinge, wenn es einfachere alternativen. Sind Sie wirklich sicher, dass Sie nicht verwenden können, eine
TListBox
? Ich meine, wenn Sie brauchen eine fortschrittliche Steuerung, um die Daten anzuzeigen, wie das Virtual TreeView, sollten Sie zunächst die Daten in etwas "unterlegt datastructure". - (Forts.) Eine "Zugrunde liegende Datastructure" ist nicht eine Magische Sache, die im Zusammenhang mit der virtual treeview, sondern etwas, was Sie die ganze Zeit bei der Programmierung auf einer höheren Ebene-alles, was Sie tun, ist zu verwalten, die Daten mittels algorithmen.
- Diese Frage nützlich aussieht: stackoverflow.com/questions/1841621
- Ja, ich bin ein Anfänger. Ich habe bereits meine Sachen gespeichert, die in den Aufzeichnungen, aber meine Daten zerstört werden mit dem Baum.
- 1, weil Sie akzeptiert die Antwort ist falsch: Sie wirklich brauchen, um zu lernen, über Daten-Strukturen, es ist der einzige Weg, um vorwärts zu bewegen. Doch Sie entschied sich (wieder) der einfachste Pfad, den Sie ausgewählt, um die Verwendung von Datenbank-Technologie und vermeiden Sie die harte Arbeit. Normalerweise würde ich mich nicht, aber nach deinen Fragen, die ich bemerkt, Sie es geschafft, einige interessante Sachen zu entwickeln, es gibt keinen Zweifel in meinem Kopf, die Sie behandeln können eine Baum-Datenstruktur. Nehmen Sie diese downvote wie ein kick in die richtige Richtung.
- Ich habe nur markiert Sie als Antwort, denn wenn ich nicht, wird jemand kommen und mir sagen, zu akzeptieren, dass man als Antwort, wie das Letzte mal. Ich will nicht Aussehen wie ein Stich, der nicht apreciate jede Anstrengung. Entfernt habe ich es jetzt, dass ich weiß, dass ich kriegen es so oder so. Meine Frage ist über Datenstrukturen, aber da war ich kurze Zeit, ich beschloss, nest einige TLists.
- Doch Sie entschied sich (wieder) der einfachste Pfad, den Sie ausgewählt, um die Verwendung von Datenbank-Technologie und vermeiden Sie die harte Arbeit. ich sehen, warum Sie machen diese Annahme, aber mein Kommentar oben nicht anders angegeben. Auch ich bin noch ziemlich neu hier, und ich werde verwendet, um Forum-Regeln, wie "nicht doublepost, nicht doublethread, nicht dies, Tu das".
- Ich bin mir sicher, dass es gute frei verfügbare tree-view-data-Strukturen. Ich weiß nur persönlich nicht wissen, was Sie sind. Ich habe verwendet, tpSysTools vor, aber ich bin mir nicht sicher, wie gut spielt es sich mit modernen Delphi.
- danke Kumpel. Ich sehe, wie die Dinge funktionieren hier. Ich würde nicht sagen, ich bin geschätzt, als ich nicht antwortete jemand anderes die Frage ist doch, und ich möchte eine Frage, die ich beantworten kann, dann erscheint irgendwann 🙂 ich dachte, Ihr Jungs Ihre eigenen Strukturen? Was ich getan habe (das funktioniert mit dem, was ich brauche), war ein Level-1-Datensatz und einen Level-2-Datensatzes und der level-1-Datensatz enthält eine TList von Level-2-Datensätze. Ist, dass eine besonders anständige Art und Weise tun?
- Wahrscheinlich würde ich immer Schreibe meine eigenen. In der Tat, meine eigene Codebasis hat ein einheimischer Baum, geschrieben von einem Kollegen. Ihre Lösung ist nicht gut. Sie sollten zuerst studieren, wie eine verknüpfte Liste und gehen Sie dann zu Bäumen. Jeder Knoten verwaltet Verweise auf den nächsten Geschwisterknoten und sein erstes Kind, und möglicherweise auch seine Eltern. Das ist wirklich alles, was Sie brauchen. Haben Sie Lesen alle Bücher, die auf Datenstrukturen?
- Naja, wenn meine Lösung tut was Sie soll, und das, was ich brauche, sehe ich keinen Grund, warum das hinzufügen von mehr Funktionen als ich benötige? 🙂 Nein, ich habe nicht alles Lesen, um ehrlich zu sein.
- Auch wenn Sie TUN, um eine Arbeit zu beantworten, es ist nicht in Ihrem besten Interesse, noch im Interesse der Gemeinschaft sofort akzeptieren, eine Antwort. Es sei denn, das problem ist ganz einfach, wie Sie sollten, warten Sie einen Tag oder zwei, um zu akzeptieren eine Antwort: vielleicht eine bessere Antwort wird zeigen, bis! Dies ist in der Tat die Art von Frage, die Vorteile von mehreren Antworten. Zum Beispiel sah ich die Frage heute morgen nicht die Zeit haben, sich damit zu befassen, wenn ich zurück kam, sah ich das Häkchen für eine Antwort, die vermuten lässt, dass die Verwendung einer Datenbank. Ich hasse es, wenn Leute empfehlen, die Datenbanken so wenn Sie wäre ein Allheilmittel.
- bitte Bearbeiten Sie die Frage und auch einige Informationen über die Daten in Ihrem Datensatz. Idealerweise wird die ganze Platte. Wenn Sie das tun, würde ich in der Lage sein, um wieder mein downvote (ich würde gerne zurückkehren, seit Sie das Häkchen in der Datenbank Antwort, aber ich kann nicht tun, da es schon mehr als 1 Stunde; wenn Sie Sie Bearbeiten, SO dass mir erlaubt, zu überprüfen, die Stimmen). Ich werde die -1 in +1 und vielleicht sogar eine Antwort auf meine eigene, wenn die anderen Experten nicht, tun Sie es zuerst.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Die Daten-Struktur, die Sie fordert, ist sehr einfach, es ist so einfach, ich würde empfehlen, mit der windows-zur Verfügung gestellt
TTreeView
: es ermöglicht die Speicherung von text und eine ID direkt in den Baum Knoten mit keine zusätzliche Arbeit.Trotz meiner Empfehlung zu verwenden, die einfacher
TTreeView
ich werde mein nehmen auf die Daten-Struktur-problem. Zunächst werde ich Klassen, nicht Datensätze. In Ihrem sehr kurzen Codebeispiel Sie mischen records und Klassen in einem sehr unfrotunate so: Wenn Sie eine Kopie derTRoot
record (Zuordnung von Datensätzen ermöglicht vollständige Kopien, da die Datensätze sind immer behandelt, als "Werte"), Sie sind nicht so eine "Tiefe Kopie" der Baum: Die vollständige KopieTRoot
enthält die gleichenKids:TList
wie das original, denn die Kurse, im Gegensatz zu Datensätzen, sind Referenzen: Sie sind Bewältigungsstrategien, die mit dem Wert der Referenz.Einem anderen problem, wenn Sie einen Datensatz mit einem Objekt-Feld ist life-cycle-management: Ein Datensatz nicht über ein Destruktor Sie müssen sich also einen anderen Mechanismus, um kostenlos das Eigentum Objekt (
Kids:TList
). Sie ersetzen könnten dieTList
mit einemarray of Tkid
aber dann werden Sie brauchen, um sehr vorsichtig, wenn man das monster Datensatz herum, weil Sie am Ende vielleicht indem Tiefe Kopien von großen Datensätzen, wenn Sie es am wenigsten erwarten.Meiner Meinung nach die Klügste, was zu tun ist, um die Daten-Struktur auf Klassen, nicht records: die Klasse von Instanzen (Objekte) übergeben werden, um als Referenzen, so dass Sie können Sie bewegen, wie Sie wollen, ohne Probleme. Sie auch die integrierte life-cycle-management (die Destruktor)
Der Basis-Klasse würde wie folgt Aussehen. Sie werden bemerken, es kann verwendet werden, entweder als Root oder das Kind, weil beide Root und Kind teilen von Daten: Die haben beide einen Namen und eine ID:
Wenn diese Klasse verwendet wird, als Root, es muss ein Weg, um zu speichern die Kinder. Ich nehme an, du bist auf Delphi 2010+, so haben Sie die Generika. Diese Klasse, die komplett mit einer Liste sieht wie folgt aus:
Du vielleicht nicht sofort erkennen, aber diese Klasse allein ist genug für die Durchführung einer multi-level-Baum! Hier finden Sie den code, füllen Sie den Baum mit ein paar Daten:
Müssen Sie eine rekursive Prozedur zum füllen der virtuellen Baum-Ansicht mit diesem Typ:
Wenn Sie Objekte auf verschiedenen Knoten in Ihrer Virtuellen Baum können verschiedene Arten von Objekten im Zusammenhang mit Ihnen. In unserem Beispiel werden wir nur hinzufügen Knoten
TNode
geben, aber in der realen Welt, die Sie haben könnten Knoten der TypenTContact
,TContactCategory
,TRecentCall
alle in einer VT. Verwenden Sie dieis
Betreiber zu prüfen, die tatsächliche Typ des Objekts in der VT-Knoten wie dieser:Und hier ist ein Beispiel, warum zum speichern VirtualNode Zeiger auf das Knoten-Instanzen:
Wissen Sie ein Beispiel für eine einfache Baumstruktur. Sie müssen "wachsen" diese Datenstruktur zu suite Ihren Anforderungen: die Möglichkeiten sind endlos! Um Ihnen einige Ideen, Richtungen zu erkunden:
Name:string
in eine virtuelle MethodeGetText:string;virtual
und dann erstellen spezielle Nachkommen vonTNode
überschreibenGetText
um spezialisierte Verhalten.TNode.AddPath(Path:string; ID:Integer)
, die es Ihnen ermöglicht, das zu tunRoot.AddPath('Contacts\Abraham', 1);
- das ist eine Methode, die erstellt automatisch alle intermediären Knoten der Letzte Knoten, ermöglichen die einfache Erstellung des Baumes.PVirtualNode
inTNode
selbst, so dass Sie überprüfen können, sondern der Knoten wird "geprüft" in den Virtuellen Baum. Das wäre eine Brücke, von der Daten-GUI-Trennung.AddNodesToTree
. Ich habe auch entfernt diePNode = ^TNode
Typ-Deklaration (und alle Verweise darauf), weil es nicht notwendig und ich weiß wirklich nicht, wie die double-pointer-Deklarationen. Finden Sie den geänderten code in der ProbeVTGetText
zu sehen, wie ich war in der Lage, durch zu bekommen, ohne mitPNode
.Contact: TContact;
Erklärung inVTGetText
Veranstaltung und die Verwendung z.B.with PayloadObject as TContact do
nachis
Klasse test.:=
im var-Deklaration, die durch Fehler, ich wollte das korrigieren, aber edits hier muss mindestens 6 chars und ich habe nichts mehr hier zu sagen 🙂PNode = ^TNode
ist eigentlich ein Zeiger auf einen Zeiger, so sind Sie nicht beide "nur Pointer". Ist ein Zeiger, der auf eine ist eine Doppel-indirected Zeiger. Und es wäre die falsche Art zu verwenden, inVTGetText
vor allem, wenn Sie erwarten, dass die Nutzlast zuTNode
ODER etwas anderes: eine bessere Wahl wärePObject = ^TObject
;:=
Dank.TNode
ist auch ein Zeiger auf die Instanz der Klasse.NodeDataSize
zuSizeOf(Pointer)
, nicht zuPointer
. VT-Knoten benötigen, um Speicherplatz zu sparen, für das was ich Plane, hinzufügen, und da ich Plane, fügen Sie einTNode
Verweis, dass die Menge der Raum, den ich brauche (können Sie denken an Objekte immer Zeiger). Ich kann nicht wissen, warum man einen AV von Ihrem AddUser routine, ohne dass der code.VT.AddChild();
ich nehme an, es ist nicht threadsicher, richtig? Ich werde versuchen, eine Lösung, die threadsicher ist, können Sie mich hinzufügen, löschen, hinzufügen, löschen, etc, von meinem Daten-Struktur in einem thread, so dass der Benutzer nicht bemerken (die app hängen würde anders).VT.AddChild()
imSynchronize()
.OnFreeNode
Veranstaltung...Ich glaube, Sie werden am besten gedient, durch das finden einer vorhandenen Bibliothek mit einem Allgemeinen Baum-Implementierung, die können Sie dann wieder verwenden um Ihre Bedürfnisse zu dienen.
Um Ihnen eine Idee geben, warum, hier ist etwas code, den ich schrieb, um zu illustrieren die einfache Bedienung bei den meisten einfachen Baumstruktur vorstellen kann.
Hinweis: ich habe nicht getestet code und kann daher nicht bürgen für die Richtigkeit. Ich erwarte, dass es Mängel hat.
All dies tut, ist fügen Sie einen neuen Knoten in den Baum ein. Es gibt Sie wenig Kontrolle darüber, wo im Baum der Knoten wird Hinzugefügt. Wenn einfach fügt einen neuen Knoten als letzten gleichrangigen Element des angegebenen übergeordneten Knotens.
Nehmen diese Art von Ansatz würden Sie wahrscheinlich benötigen, um mit:
Es ist sicherlich möglich, dies zu tun, aber man ist besser beraten, finden Sie eine 3rd-party-Bibliothek, die bereits implementiert die Funktionalität.
Fragte ich ähnliche Frage hier. Ich habe nicht bekam keine nützlichen Antworten, damit ich entscheiden, um meine eigene Implementierung, die Sie hier finden können hier.
BEARBEITEN:
Ich werde versuchen, nach Beispiel, wie Sie könnte meine Daten Struktur:
Erklären Datentyp:
Erklären sich mit den Haupt-Daten-Struktur-Objekt irgendwo im code:
Erstellen (und vergessen Sie nicht, free später):
Ordnen Sie den VirtualStringTree zu unserer Datenstruktur:
Dann können Sie init Ihrem Baum, mit einige Werte:
- Und set-VST-events, um die Daten anzuzeigen:
In diesem Punkt arbeiten Sie nur mit Ihrem MyTree der Struktur der Daten und alle änderungen, die vorgenommen werden, spiegelt sich in Ihrem zugewiesenen VST. Sie sind dann immer speichern (und laden) zugrunde liegende Struktur zu stream oder einer Datei. Hoffe, das hilft.
Wenn ich das richtig verstehe, benötigen Sie ein datastructure für Ihren Baum. Jeder einzelne Knoten erfordert einen Datensatz zu halten seine Daten. Aber die zugrunde liegenden bietet die verwaltet werden können, in ein paar verschiedene Möglichkeiten. Ich vermute das ist alles gelungen, in einigen Sortieren der Datenbank - Diese ist bereits gesprochen worden auf dieser Website, so dass ich Sie auf:
Die Implementierung einer hierarchischen Datenstruktur in einer Datenbank
und hier:
Was ist das effizienteste/elegante Art und Weise zu analysieren, einen flachen Tisch in einem Baum?
und hier:
SQL - gewusst Wie: speichern und navigieren von Hierarchien?
Nested Set Modell:
http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/
Wenn Sie mit neueren Versionen von Delphi unterstützt Generics, überprüfen GenericTree
Delphi hat Generika heute. Ich gerade erfunden, einen sehr schönen Baum-Datenstruktur. Nicht gonna give-code entfernt nur noch, nicht wirklich ein open-source-person, vielleicht in Naher Zukunft sein, auch aus anderen Gründen, siehe unten.
Aber ich gebe einige Hinweise, wie Sie neu zu erstellen:
Annahme, dass alle Knoten enthalten kann, die die gleiche Datenstruktur (das scheint der Fall zu sein, von oben, ein string, eine id, und dann links.
Zutaten, die Sie brauchen, um neu zu erstellen, ist die folgende:
(In Ihrem Fall ersetzen-Klasse mit Rekord, ungetestet, kann aber auch funktionieren)
Einer Immobilie
Nicht nur alle Anwesen, eine default-Eigenschaft 😉
Einen getter.
Einen rekursiven Konstruktor mit Tiefe und Kind.
Gegeben, alle von Ihnen genügend Hinweise, wäre lustig und interessant zu sehen, ob jemand kann neu erstellen, sonst könnte ich genauso gut patentieren, nur ein Scherz, ich will nicht Geld zu werfen, die dagegen sind, vielleicht erweitern Sie die Klasse, wenn auch mit anderen Einrichtungen.
Die Klasse zuweist, werden alle Knoten während der Konstruktion wie eine wahre Daten-Struktur... bemerkte mit hinzufügen und entfernen, und solche, zumindest nicht für jetzt.
Jetzt kommt die interessante und lustige Aspekt dieser (geheim -) design, etwas, was ich irgendwie wollte, und wird jetzt Wirklichkeit. Kann ich jetzt den code schreiben, wie folgt:
TGroup ist nur ein Beispiel, kann alles sein, solange es eine Klasse, in meinem Fall.
In diesem Fall ist es nur eine Klasse mit mString
Nun, was Sie beachten können von diesem tatsächlichen test-code, der es ermöglicht, "array-Erweiterung" wie selten habe ich gesehen, Dank dieser Eigenschaft, die self-references eine Art...
So [] [] ist die Tiefe 2.
[][][] wäre die Tiefe 3.
Ich bin immer noch die Bewertung die Verwendung dieses.
Ein potentielles problem ist Delphi hat keine wirkliche Technik zu auto-expand diese arrays, obwohl keiner habe ich noch nicht gefunden, und sind statisfied mit.
Möchte ich eine Technik, wo kann ich code schreiben, die gehen können, um die Tiefe Ebene:
[0][0][0][0][0]
Noch nicht sicher, wie das zu tun... simpelst option ist "Rekursion".
real Beispiel:
Irgendwie interessant ist es nicht.
Noch zu erforschen ist es Nützlichkeit für die "realen Anwendungen" und wenn ich will, zu gehen mit Rekursion oder nicht 😉
Eines Tages vielleicht, werde ich open source alle von meinem code. Ich bin fast 40 Jahre alt, wenn ich jenseits der 40, von 39 auf 40, ich war ein bisschen Planung auf open source. Noch 4 Monate Weg von 40 =D
(Ich muss sagen das ist das erste mal, dass ich bin beeindruckt von Generika, es getestet, vor langer Zeit, es war super buggy damals, und vielleicht design-Weise unbrauchbar, aber jetzt, mit dem Fehler behoben und die eingeschränkte Generika, es ist sehr eindrucksvoll in der neuesten Delphi-Toyko 10.2.3 version august 2018 ! 😉 :))
Bin ich nur an der Oberfläche kratzen, was unmöglich ist mit den neuesten Delphi-tech, vielleicht mit anonymen Methoden, die das schreiben von rekursiven Routinen zur Verarbeitung dieser Daten Struktur, könnte ein wenig einfacher, vielleicht auch parallele Verarbeitung könnte in Betracht kommen, Delphi-Hilfe erwähnt, das für den anonymen Methoden.
Bye,
Skybuck.