Buchempfehlung
Windows-Programmierung. Das Entwicklerhandbuch zur WIN32-API
Windows-Programmierung. Das Entwicklerhandbuch zur WIN32-API
"Der" Petzold, das über 1000 Seiten starke Standardwerk zum Win32-API - besonders nützlich u. a. bei der GUI-Programmierung in FreeBASIC! [Mehr Infos...]
FreeBASIC-Chat
Es sind Benutzer im FreeBASIC-Chat online.
(Stand:  )
FreeBASIC bei Twitter
Twitter FreeBASIC-Nachrichten jetzt auch über Twitter erhalten. Follow us!

Tutorial

Baumstrukturen in FreeBASIC

von MitgliedThePuppetMasterSeite 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 (Externer Link!http://forum.qbasic.at/) stellen.

MfG + Viel Erfolg + HF
TPM

 

Gehe zu Seite Gehe zu Seite  1  2  3  4  5  6  7  
Zusätzliche Informationen und Funktionen
  Bearbeiten Bearbeiten  

  Versionen Versionen