; #################################################################################### ;## ## ;# Wie funktionieren eigentlich die LinkedLists? Und zu was sind sie zu gebrauchen? # ;## ## ; #################################################################################### ; Vorraussetzungen: - Standard-Typen (.b, .w, .l, .s) ; - While-Wend-Schleife ; - Repeat-Until-Schleife ; - MessageRequester ; - DIM (Arrays) ;Willkommen zu einer weiteren Stufe meiner Tutorial-Serie. Heute will ich euch die LinkedLists ;einmal naeher erlaeutern. ;Bei der LinkedList handelt ich sich um ein variables Array, also ein Array, dass waehrend der ;Programmausfuehrung stndig seine Groesse wechseln kann. Sei es, dass es groesser wird, oder ;auch kleiner. Wenn wir eine LinkedList erstellen wollen und in sie etwas schreiben wollen, gehen ;wir wie folgt vor: ; ; NewList LinkedListName.Typ() ; ;Im folgenden Beispiel erstellen wir zunaechst eine LinkedList; wir verwenden also den Befehl ;NewList. Aber wenn wir unsere LinkedList erstellt haben, koennen wir direkt noch nichts hinein- ;schreiben, da wir zuerst ein Element in der Liste erstellen muessen. Das machen wir mit den ;folgenden beiden Befehlen: ; ; Syntax: AddElement (LinkedListName()) ; InsertElement (LinkedListName()) ; ;Mit AddElement haben wir nun ein neues Element erstellt und befinden uns an Position 1 in der ;LinkedList. Bei jedem erneuten Aufruf von AddElement ruecken wir eine Position weiter und paral- ;lel dazu wird die LinkedList auch immer um ein Element groesser. Man sollte sich allerdings bei ;diesem Befehl merken, dass er immer ein Element nach der aktuellen Position einfuegt. ;Und das ist auch schon der Unterschied zu InsertElement. Dieser Befehl naemlich fuegt ein neues ;Element vor der aktuellen Position ein. ;Ausserdem wird bei beiden Befehlen das neu erstellte Element das aktuelle Element der LinkedList. ; ;Dabei tritt bei den LinkedLists uebrigens ein neues Problem, das sich im Vergleich zu den Arrays ;zeigt, auf. Wir koennen die Werte, die in einem Element in einer LinkedList stehen, nicht direkt ;abrufen; anders gesagt, heisst das, dass wir nicht wie bei einem Array z. B. schreiben koennen: ; ; Variable = ArrayName(10) ; ;Wir koennen uns naemlich nur relativ zu der momentanen Position bewegen. Entweder ein Element nach ;vorne oder ein Element zurueck springen. Das bewerkstelligen wir mit den folgenden beiden Befehlen: ; ; Syntax: Adresse = NextElement (LinkedListName()) ; Adresse = PreviousElement (LinkedListName()) ; ;Mit NextElement springen wir in der LinkedList um ein Element weiter. Wenn wir also beim ersten ;Element waren, gelangen wir zum zweiten. Aber wenn nach dem ersten Element kein weiteres folgt, also ;die LinkedList aus nur einem Element besteht, dann ist Adresse gleich Null. Mit PreviousElement ;springt man demnach ein Element wieder zurueck. Und wenn hier Adresse gleich Null ist, gab es kein ;vorheriges Element mehr, also sind wir bereits an Position eins angekommen gewesen. ;Wozu man die Adresse gebrauchen kann, wird in den naechten Abschnitten genauestens erklaert. ; ;Jetzt, wo wir bestimmen koennen, an welcher Position wir in der LinkedList sind, kommen wir zum ent- ;gegengesetzten Befehl von AddElement und InsertElement, naemlich DeleteElement: ; ; Syntax: DeleteElement (LinkedListName()) ; ;Dieser Befehl loescht das aktuelle Element aus der LinkedList, gibt den Speicher frei und setzt ;das aktuelle Element auf das, das dem geloeschten Element folgte. Wenn man bei einem Array ein ;Feld loeschen wollte, muesste man alle dem geloeschten Feld folgende Felder eins nach vorne ruecken, ;was ziemlich - je nach Groesse des Arrays - auf die Geschwindigkeit des Programms gehen wird. ; ;Kommen wir nun zu einem konkreten Beispiel fuer die LinkedLists. Dafuer nehme ich wie bei meinem ;Dim-Beispiel wieder den netten Einkaufszettel. Diesesmal kann man allerdings zuerst einmal soviele ;Produkte eingeben, wie man will, die dann schoen aufgelistet werden. :-) NewList Einkaufszettel.s() ;Zuallererst erstellen wir eine LinkedList ;mit dem Namen Einkaufszettel OpenConsole() Repeat ;Hier habe ich eine kleine Eingabeaufforderung Print("Produkt: ") ;in der Konsole gemacht. Dabei wird der einge- Produkt$ = Input() ;gebene Text in Produkt$ gespeichert. PrintN("") If Produkt$ <> "" ;Wenn Produkt$ nicht Null ist, wird mit AddElement(Einkaufszettel()) ;AddElement ein neues Element in der Liste Einkaufszettel() = Produkt$ ;erstellt und Einkaufszettel() der Wert von ;Produkt zugewiesen. ;Wenn man jetzt statt AddElement InsertElement ;benutzen wuerde, wurden spaeter gar keine Pro- ;dukte gespeichert sein, weil wir uns von Anfang ;an an Position Null befinden. Und vor diese ;Position laesst sich schlecht ein weiteres Ele- ;ment einfuegen. EndIf Until Produkt$ = "" ;Verlasse die "Eingabe-Schleife", wenn der Be- ;nutzer nichts eingegeben hat. CloseConsole() ResetList(Einkaufszettel()) ;Neuer Befehl: Setzt das aktuelle Element auf ;die Position Null. Wenn man nach diesem Befehl, ;den Wert von der resetteten LinkedList auslesen ;will, stuerzt das Programm sofort ab, da die ;niedrigste Position in einer LinkedList immer ;Eins ist. Liste.s = "" ;Damit wir die gesamte Einkaufsliste in einem ;Fenster darstellen koennen, speichern wir ;sie in dem String Liste.s, in dem jedes Produkt ;getrennt durch Chr(13) aufgelistet ist. While NextElement(Einkaufszettel()) ;Bevor wir allerdings etwas aus unserer Einkaufs- ;liste lesen koennen, muessen wir zum naechsten ;Element springen. Das machen wir mit NextElement. ;Verbunden mit einer While-Wend-Schleife, ist es ;so moeglich, alle Elemente durchzugehen, bis keins ;mehr da ist, also der Wert von NextElement Null ;ist. Liste = Liste + Chr(13) + Einkaufszettel() ;Jetzt weisen wir unserem Auflistungs-String seinen ;eigenen Wert plus Chr(13) plus das naechste Produkt ;zu... Wend MessageRequester("Einkaufszettel:", Liste, 0) ;...und zeigen zum Schluss die Liste in einem ;Fenster an. ;Weitere Befehle zu den LinkedLists: ; ; Syntax: ClearList (LinkedListName()) ; ;Dieser Befehl loescht alle zuvor geaddeten Elemente aus einer LinkedList und gibt ihren Speicherplatz wieder ;fuer andere Zwecke frei. Allerdings wird dabei nicht die LinkedList selbst geloescht; man kann naemlich wieder ;neue Elemente hinzufuegen. ; ; Syntax: ElementAnzahl.l = CountList(LinkedListName()) ; ;Diese Funktion gibt die Anzahl der Elemente in einer LinkedList zurueck und distanziert sich dabei voll von ;deren Inhalt. Das heisst, dass an der LinkedList nichts veraendert wird. ; ; Syntax: FirstElement (LinkedListName()) ; ;Dieser Befehl funktioniert so aehnlich wie ResetList. Der Unterschied dabei ist, dass die Position des aktu- ;ellen Elementes nicht Null, sondern Eins ist. Das heisst, dass man direkt - nicht wie bei ResetList - auch ;etwas aus der LinkedList auslesen kann. ; ; Syntax: LastElement (LinkedListName()) ; ;Dies ist der entgegengesetzte Befehl zu FirstElement. Mit ihm ist es moeglich, das letzte Element der LinkedList ;als das aktuelle Element einzustellen. Dann kann man mit AddElement weitere Elemente an die LinkedList anhaengen. ; ; Syntax: Position.l = ListIndex (LinkedListname()) ; ;Mit dieser Funktion ist es moeglich, die Position des aktuellen Elementes auszumachen. Nuetzlich fuer Index- ;abhaengige Algorithmen oder derartiges. ; ; Syntax: ChangeCurrentElement (LinkedListName, Adresse) ; ;Dieser Befehl ist vorallem dann nuetzlich, wenn man des oefteren auf ein bestimmtes Element in der LinkedList ;zugreifen moechte. Hier ein kleines Beispiel: (Pseudocode) ; ; Im Moment sind wir an der Position in der LinkedList, wo sich unser ; immmer wieder zu gebrauchendes Element befindet. ; Jetzt speichern wir seine Position in einer 32-bit Variablen: ; ; *Adresse = @LinkedListName() ; ; Jetzt koennen wir mit der LinkedList machen, was wir wollen, ausser ; Elemente hinzufuegen oder loeschen. ; Wenn wir nun wieder unser bestimmtes Element auslesen oder editieren ; moechten, tun wir das Folgende: ; ; ChangeCurrentElement (LinkedListName(), *Adresse) ; ; Jetzt sind wir wieder an der Position in der LinkedList, an der wir ; auch am ANfang unsere Programms waren. ; ;Vorsicht: Bei falschen Adressen-Angaben droht ein Absturz des Programm ; oder sogar des Systems. ; ExecutableFormat=Windows ; CursorPosition=124 ; FirstLine=121 ; EOF