Dieses Modul ist eine Listenverwaltung für eine sortierte Liste. Sie kann aber auch als unsortierte Liste verwendet werden, um damit z.B. als Container für einen Stack oder eine Queue zu dienen.
C, C++
#include <teramile/liste.h>
typedef void *ListeKeyType;Dies ist ein typloser Zeiger auf den Schlüssel in der Liste.
typedef void *ListeDataType;Dies ist ein typloser Zeiger auf die Daten, die in der Liste gespeichert werden sollen.
typedef struct liste_element {
ListeKeyType Key;
ListeDataType Data;
struct liste_element *Next;
} ListeElement, *ListeKnoten;
Dieser Datentyp definiert einen Knoten der Liste.
typedef struct {
ListeKnoten Daten;
ListeKnoten Aktuell;
CmpFkt Compare;
} Liste;
Dieser Datentyp ist die Wurzel der Liste.
typedef void (*ListeDelCbkFkt)(ListeKnoten Blatt);Dies ist eine Callback Funktion, die an ListeDestroy übergeben wird und den Key und die Daten eines Listenknotens aufräumen muss. Da Key und Daten typlose Zeiger sind, weiss die Listenverwaltung nicht, ob und wie für diese Zeiger Speicher freizugeben ist.
Liste *ListeCreate(CmpFkt Cmp); | |
| Diese Funktion erzeugt eine neue Liste. | |
| Cmp | Dies ist die Vergleichsfunktion für die Daten in der Liste. Diese Funktion bekommt zwei Argumente vom Typ ListeKeyType und muß einen Wert <0 liefern, wenn der erste Parameter kleiner als der zweite ist; 0 wenn beide gleich sind und einen Wert >0 wenn der erste Parameter grösser als der zweite ist. |
|---|---|
| Rückgabe: | Eine neue Liste im Erfolgsfall, NULL im Fehlerfall |
void ListeDestroy(Liste *Wurzel, ListeDelCbFkt Cb); | |
| Diese Funktion gibt Liste wieder frei. Auch sämtliche Listenknoten werden automatisch freigegeben. | |
| Wurzel | Dies ist die Adresse der Listenwurzel. Die Liste muss durch ListeCreate angelegt werden. |
| Cb | Dies ist eine Callback Funktion, die den Key und die Daten eines Listenknotens aufraeumen (freigeben) muss. |
BOOL ListeInsert(Liste *Wurzel, ListeKeyType Key, ListeDataType Daten); | |
| Diese Funktion fügt einen neuen Knoten in die Liste ein. | |
| Wurzel | Dies ist die Adresse der Listenwurzel. Die Liste muss durch ListeCreate angelegt werden. |
| Key | einzufügender Schlüssel (typloser Zeiger auf den Schlüssel). |
| Daten | einzufügende Daten (typloser Zeiger auf die Daten). |
| Rückgabe: | TRUE im Erfolgsfall, FALSE im Fehlerfall |
BOOL ListeAhead(Liste *Wurzel, ListeKeyType Key, ListeDataType Daten); | |
| Diese Funktion fügt einen neuen Knoten am Anfang der Liste ein. | |
| Wurzel | Dies ist die Adresse der Listenwurzel. Die Liste muss durch ListeCreate angelegt werden. |
| Key | einzufügender Schlüssel (typloser Zeiger auf den Schlüssel). |
| Daten | einzufügende Daten (typloser Zeiger auf die Daten). |
| Rückgabe: | TRUE im Erfolgsfall, FALSE im Fehlerfall |
BOOL ListeAppend(Liste *Wurzel, ListeKeyType Key, ListeDataType Daten); | |
| Diese Funktion fügt einen neuen Knoten am Ende der Liste ein. | |
| Wurzel | Dies ist die Adresse der Listenwurzel. Die Liste muss durch ListeCreate agelegt werden. |
| Key | einzufügender Schlüssel (typloser Zeiger auf den Schlüssel). |
| Daten | einzufügende Daten (typloser Zeiger auf die Daten). |
| Rückgabe: | TRUE im Erfolgsfall, FALSE im Fehlerfall |
BOOL ListeDelete(Liste *Wurzel, ListeKeyType Key); | |
| Diese Funktion löscht das Element mit dem Schlüssel key aus der Liste. Der ausgehängte Listenknoten wird zurückgeliefert. Der Benutzer muss selbst den Speicher für den Schlüssel, die Daten und den zurückgelieferten Knoten freigeben! | |
| Wurzel | Dies ist die Adresse der Listenwurzel. Die Liste muss durch ListeCreate angelegt werden. |
| Key | Schlüssel für die zu löschenden Daten. |
| Rückgabe: | TRUE im Erfolgsfall, FALSE im Fehlerfall |
ListeKnoten ListeFinde(Liste *Wurzel, ListeKeyType Key); | |
| Diese Funktion sucht das Element mit dem Schlüssel key. | |
| Wurzel | Dies ist die Adresse der Listenwurzel. Die Liste muss durch ListeCreate angelegt werden. |
| Key | Schlüssel für die zu suchenden Daten. |
| Rückgabe: | Zeiger auf den gefundenen Datensatz. |
ListeKnoten ListeFirst(Liste *Wurzel); | |
| Diese Funktion liefert das erste Element der Liste. | |
| Wurzel | Dies ist die Adresse der Listenwurzel. Die Liste muss durch ListeCreate angelegt werden. |
| Rückgabe: | Zeiger auf den gefundenen Datensatz. |
ListeKnoten ListeNext(Liste *Wurzel); | |
| Diese Funktion liefert das nächste Element der Liste. Der Benutzer muss zuerst mit ListeFinde oder ListeFirst eine Element gesucht haben! | |
| Wurzel | Dies ist die Adresse der Listenwurzel. Die Liste muss durch ListeCreate angelegt werden. |
| Rückgabe: | Zeiger auf den gefundenen Datensatz. |
Ein Program muss für jede neue Liste eine Variable vom Typ Liste anlegen. Als erste Aktion muss ListeCreate aufgerufen werden. Der Parameter ist eine Vergleichsfunktion, die zwei Keys übergeben bekommt und einen Wert <0 liefert, wenn der erste Key kleiner als der zweite ist, 0 bei Gleichheit und >0 wenn der erste Key grösser ist. Danach können neue Knoten eigefügt werden, nach Knoten mit einem vorgegebenen Schlüssel gesucht werden und Knoten gelöscht werden.
Das Beispiel benutzt als Schlüssel und für die Daten einen long. Da ein Pointer auf 68K Systemen gleich einem long ist, wird anstelle eines Pointers der long übergeben. Sollen Daten abgespeichert werden, die sich nicht per Cast in dem Pointer abspeichern lassen, muss per malloc Speicher angefordert werden und der Zeiger auf diese Daten uebergeben werden.
Wenn die Liste nicht mehr benötigt wird, sollten die Elemente wieder freigegeben werden. Dies kann dadurch geschehen, dass in einer Schleife das erste Element geholt wird und anschliessend gelöescht wird.
#include#include #include #include int MyCmp(void *d1, void *d2) { return((long)d2 - (long)d1); } int main(void) { Liste *TestListe; ListeKnoten Node; /* Liste anlegen */ TestListe = ListeCreate(MyCmp); if (TestListe != NULL) { /* ein Element einfuegen */ ListeInsert(TestListe, (ListeKeyType)3L, (ListeDataType)5L); /* Ein element suchen */ Node = ListeFinde(TestListe, (ListeKeyType)3L); if (Node != NULL) printf("gefunden, Daten = %ld\n", (long)(Node->Data)); /* Alle Elemente wieder freigebene */ Node = ListeFirst(TestListe); while (Node != NULL) { ListeDelete(MyListe, Node->Key); Node = ListeFirst(TestListe); } ListeDestroy(TestListe); } else puts("Fehler beim Anlegen der Liste"); }