Tutorial
Baumstrukturen in FreeBASIC
von ThePuppetMaster | Seite 7 von 7 |
Der bis jetzt erzeugte Quellcode ist ausreichend, um eine Liste zu erstellen. Zwar können wir sie noch nicht komfortabel lesen, aber das soll uns nicht daran hindern, ein kleines Beispiel zu schreiben.
Zuerst einmal bauen wir die bis jetzt entwickelte Typen-Struktur sowie die Funktionen in das Programm ein.
Function LL_Add(ByRef V_List_F as Element_Type Ptr, ByRef V_List_L as Element_Type Ptr, V_Root as Element_Type Ptr, V_Parent as Element_Type Ptr, V_Type as UInteger, V_DataPtr as UInteger, V_DataSize as UInteger) as Element_Type Ptr
'...
With *V_List_L
'...
For X as UInteger = 1 To V_DataSize 'Byte für Byte durchgehen
*(.V_Data[X - 1]) = *(V_Data[X - 1]) 'und kopieren
Next
End With
Return V_List_L 'Am Ende das neue Element zurückgeben
End Function
Die fertige Funktion sieht anschließend wie folgt aus:
Type Element_Type
V_Next as Element_Type Ptr
V_Prev as Element_Type Ptr
V_ChildF as Element_Type Ptr
V_ChildL as Element_Type Ptr
V_Parent as Element_Type Ptr
V_Root as Element_Type Ptr
V_Type as UInteger
V_Size as UInteger
V_Data as Any Ptr
End Type
Function LL_Add(ByRef V_List_F as Element_Type Ptr, ByRef V_List_L as Element_Type Ptr, V_Root as Element_Type Ptr, V_Parent as Element_Type Ptr, V_Type as UInteger, V_DataPtr as UInteger, V_DataSize as UInteger) as Element_Type Ptr
If V_List_L <> 0 Then
V_List_L->V_Next = CAllocate(SizeOf(Element_Type))
V_List_L->V_Next->V_Prev = V_List_L
V_List_L = V_List_L->V_Next
Else
V_List_L = CAllocate(SizeOf(Element_Type))
V_List_F = V_List_L
End If
With *V_List_L
.V_Parent = V_Parent
.V_Root = V_Root
.V_Type = V_Type
.V_Size = V_DataSize
.V_Data = CAllocate(SizeOf(V_DataSize))
For X as UInteger = 1 To V_DataSize
*(.V_Data[X - 1]) = *(V_Data[X - 1])
Next
End With
Return V_List_L
End Function
Function Element_Add(ByRef V_List_F as Element_Type Ptr, ByRef V_List_L as Element_Type Ptr, V_Root as Element_Type Ptr, V_Parent as Element_Type Ptr, V_Data as String) as Element_Type Ptr
Return LL_Add(V_List_F, V_List_L, V_Root, V_Parent, 1, StrPtr(V_Data), Len(V_Data))
End Function
Function Element_Add(ByRef V_List_F as Element_Type Ptr, ByRef V_List_L as Element_Type Ptr, V_Root as Element_Type Ptr, V_Parent as Element_Type Ptr, V_Data as UByte) as Element_Type Ptr
Return LL_Add(V_List_F, V_List_L, V_Root, V_Parent, 2, @V_Data, SizeOf(V_Data))
End Function
Function Element_Add(ByRef V_List_F as Element_Type Ptr, ByRef V_List_L as Element_Type Ptr, V_Root as Element_Type Ptr, V_Parent as Element_Type Ptr, V_Data as UShort) as Element_Type Ptr
Return LL_Add(V_List_F, V_List_L, V_Root, V_Parent, 3, @V_Data, SizeOf(V_Data))
End Function
'...
Jetzt müssen wir 2 Variablen erzeugen, welche die Baumstruktur speichern.
'...
Dim Shared List_F as Element_Type Ptr
Dim Shared List_L as Element_Type Ptr
'...
Und schon können wir damit beginnen, Elemente hinzuzufügen.
'...
For X as UInteger = 1 to 10
Element_Add List_F, List_L, List_F, List_F, "Test_" & Str(X))
Next
'...
Es werden 10 Elemente erzeugt. Jedes dieser Elemente ist auf derselben Ebene. Möchte man nun ein Element erzeugen, das auch Child-Unterelemente hat, ist die Liste V_Child:
'...
Dim TPtr as Element_Type Ptr
For X as UInteger = 1 to 10
TPtr = Element_Add List_F, List_L, List_F, List_F, "Test_" & Str(X))
For Y as UInteger = 1 to 3
Element_Add TPtr->V_ChildF, TPtr->V_ChildL, List_F, TPtr, "Test_" & Str(X) & "-" & Str(Y))
Next
Next
'...
Hierbei ist darauf zu achten, dass Root auch wirklich Root ist. Root ist, wie schon mehrfach erwähnt, das ALLERerste Element in der Liste. Dieses erste Element wird in List_F gespeichert. Daher können wir den Root Parameter so belassen. Was sich jedoch ändert, ist der Parent Parameter, das Elternteil. Die Eltern der Y-Kinder (Variable Y im Quelltext) sind in TPtr hinterlegt. Wie ebenfalls schon erwähnt, gibt uns die überladene Funktion den Pointer auf das neu erzeugte Element zurück. Dieses neue Element speichern wir in TPtr zwischen. TPtr entält folglich auch das Element, welches die Kinder aufnehmen soll. Darum übergeben wir als Listenparameter diesmal die V_Child Einträge von TPtr sowie als Elternteil das TPtr selbst.
Dieses Spielchen lässt sich beliebig oft und beliebig tief wiederholen. Die einzigste Beschränkung liegt in der verfügbaren Größe des Arbeitsspeichers.
Damit wäre eigentlich schon alles geklärt. Wie man Daten wieder aus der Liste ausliest, Daten verschiebt, bearbeitet oder löscht, sehe ich mal als Hausaufgabe für euch an. Die grundlegenden Kenntnisse sollten (so hoffe ich) nun verstanden sein - insbesondere der Aufbau des Speichers bei Verwendung einer Linked List mit einer Baumstruktur. Sollten dennoch Fragen offen bleiben, könnt ihr diese gerne im Forum (http://forum.qbasic.at/) stellen.
MfG + Viel Erfolg + HF
TPM
Zusätzliche Informationen und Funktionen | |||||||
---|---|---|---|---|---|---|---|
|
|