C- Kurs 09 Dynamische Datenstrukturen Dipl.- Inf. Jörn Hoffmann jhoffmann@informaak.uni- leipzig.de Universität Leipzig InsAtut für InformaAk Technische InformaAk
Flexible Datenstrukturen Institut für Informatik Dynamische Datenstrukturen Strukturen, die zur Laufzeit angelegt werden Skalierbar, Flexibel Benötigen zusätzliche Verwaltungs- und Zugriffsoperationen Inhalt 1. Elementzugriff *(ptr). ó ptr-> 2. Funktionszeiger int (*ptr)(int); 3. Lineare Listen knoten->; 4. Bäume knoten->a knoten->b; Jörn Hoffmann C-Kurs Folie 2
Zeiger Elementzugriff Syntax *(Strukturzeiger).Komponenten; Strukturzeiger -> Komponenten ; Semantik Zugriff auf die Komponente einer struct bzw. union, auf die der Strukturzeiger verweist Vereinfachung der Schreibweise der beiden Operationen 1. Zeiger Dereferenzierung 2. Komponentenzugriff Jörn Hoffmann C-Kurs Folie 3
Zeiger Elementzugriff Beispiel // zugriff.c typedef struct { char name[100]; int alter; } person_t; person_t pers = { Max, 25}; person_t *ptr = &pers; printf ( pers.name = %s, pers.alter = %d\n, pers.name, pers.alter); printf ( ptr->name = %s, ptr->alter = %d\n, ptr->name, ptr->alter); Jörn Hoffmann C-Kurs Folie 4
Funktionszeiger Institut für Informatik Syntax Deklaration : Rückgabetyp (*Funktionszeigervariable)( Parameterliste ) Zuweisung : Funktionszeigervariable = Funktionsname; Aufruf : Funktionszeigervariable (Parameter); Semantik Deklarieren einer Zeigervariablen, die auf eine Funktion mit dem angegebene Rückgabetypen und Parameterliste verweisen kann. Zuweisen des Funktionszeigers einfach über Angabe des Funktionsnamens Aufruf analog wie bei Funktion direkt Nutzen Wiederverwendung einer Implementierung Generische Programmierung Jörn Hoffmann C-Kurs Folie 5
Beispiel // funktionszeiger.c #include <stdio.h> void printzahl(int zahl) { printf("%d\n", zahl); } int main() { int (*ptr1) (const char*,...) = printf; void (*ptr2)(int) = printzahl; ptr1("hallo Welt\n"); // Aufruf (*ptr2)(2); // Aufruf (alternativ) return 0; } Jörn Hoffmann C-Kurs Folie 6
Flexible Datenstrukturen Zweck Anforderung Programm zur Verwaltung von Kunden benötigt Viele Kunden Hohes Neuaufkommen von Kunden Suche und Sortierung nötig Jörn Hoffmann C-Kurs Folie 7
Statisches Array Institut für Informatik 1. Lösung (Statisches Array) typedef struct { int knr; char *name; /*... */ }kunde_t; // Statisches Array kunde_t kundendaten[10000]; Eigenschaften Einfach Speicherverschwendung Keine flexible Verwaltung Aufwändige Sortierung und Suche Jörn Hoffmann C-Kurs Folie 8
Dynamisches Array Institut für Informatik 2. Lösung (Dynamisches Array) typedef struct { int knr; char *name; /*... */ }kunde_t; // Dynamisches Array (Halbstatisch) kunde_t *kundendaten = malloc(anzahlkunden * sizeof(kunde_t)); Eigenschaften Bedarfsgerechte Speichernutzung Aufwändiges Umkopieren bei neuen Kunden Aufwändige Sortierung und Suche Jörn Hoffmann C-Kurs Folie 9
Lineare Liste Institut für Informatik 3. Lösung (Lineare Liste) typedef struct _knoten { kunde_t ; struct _knoten *; } knoten_t; // Lineare Liste knoten_t *k1 = malloc(sizeof(knoten_t)); knoten_t *k2 = malloc(sizeof(knoten_t)); k1. = k2; k2. = ; Eigenschaften Flexibel, Skalierbar Geringer Mehraufwand durch indirekte Zeigerzugriffe Jörn Hoffmann C-Kurs Folie 10
Lineare Liste Institut für Informatik Lineare Liste Dynamische Datenstruktur Verwaltung von Elementen eines Typs Verknüpft durch Zeiger Kopf-Zeiger bestimmt aktuelle Einfügeposition Letztes Element verweist auf *kopf *(kopf.) kopf Jörn Hoffmann C-Kurs Folie 11
Lineare Liste Einfügen (Idee) Einfügen Ermittlung des Einfügeplatzes Änderung von zwei Verweisen (1) Vorgänger auf neues Element verweisen (2) Nachfolger im neuen Element setzen Neuer Knoten (1) (2) *kopf Listenende kopf Jörn Hoffmann C-Kurs Folie 12
Lineare Liste Einfügen 0. Funktion Aufrufen Funktion aufrufen Parameter kopf zeigt auf Anfang der Liste Parameter neuerknoten wird fertig initialisiert übergeben Element-Wert wird für Vergleiche benötig neu *kopf * *... kopf Jörn Hoffmann C-Kurs Folie 13
Lineare Liste Einfügen 1. Einfügeplatz finden Liste mittels Schleife durchsuchen Entscheidung ob aktueller Knoten durch Neuen ersetzen werden soll Falls ja, Suche beenden Falls nein, Speicheradresse des Next-Zeigers in Hilfszeiger ablegen Nächsten Knoten wählen neu hilf *kopf * *... kopf Jörn Hoffmann C-Kurs Folie 14
Lineare Liste Einfügen 2. Knoten einfügen Wert des -Zeigers vom neuen Knoten auf aktuellen Knoten setzen neu hilf *kopf *, neu-> * kopf... Jörn Hoffmann C-Kurs Folie 15
Lineare Liste Einfügen 3. Vorgänger anpassen Next-Zeiger vom Vorgängerknoten auf neuen Knoten setzen Dieser kann mittels Hilfszeiger direkt manipulieren werden neu hilf *kopf *, neu-> *... kopf Jörn Hoffmann C-Kurs Folie 16
Lineare Liste Einfügen 4. Liste anpassen Kopf muss angepasst werden, falls es keinen Vorgänger gab Kann ebenfalls über Hilfszeiger direkt manipuliert werden Hilfszeiger muss am Anfang auf Kopf verweisen neu hilf neu-> *... kopf Jörn Hoffmann C-Kurs Folie 17
Lineare Liste Einfügen 4. Fertig Knoten ist jetzt eingefügt Kopf wurde möglicherweise verändert *kopf * *... kopf Jörn Hoffmann C-Kurs Folie 18
Lineare Liste Beispiel void knoteneinfuegen(knoten_t **kopf, knoten_t *neuerknoten) { knoten_t **hilf, *knoten; // Aktuellen Knoten auf Listenanfang setzen knoten = *kopf; hilf = kopf; // Finden der Einfügeposition while (knoten = ) { if(knoten-> > neuerknoten->)// Vergleich zur Entscheidung break; hilf = &knoten->; // Adresse des Next-Zeiger speichern (kann direkt manipuliert werden) knoten = knoten->; // Nächster Knoten } // Vorhandene Knoten an neuen Knoten anfügen neuerknoten-> = knoten; // Vorgänger bzw. Kopf direkt anpassen *hilf = neuerknoten; } Jörn Hoffmann C-Kurs Folie 19
Lineare Listen Typen Einfach verkettete lineare Listen anfang... Keller ( Stack, lifo-prinzip, last in first out): Elemente können nur am Anfang angehängt und entfernt werden. Warteschlange ( Queue, fifo-prinzip, first in first out): Elemente werden stets am Ende angehängt und am Anfang entfernt. Jörn Hoffmann C-Kurs Folie 20
Lineare Listen Typen Zyklisch verkettete lineare Listen (Listenende zeigt auf den Anfang): anfang... Doppelt verkettete lineare Listen (Verweis auf Vorgänger und Nachfolger):......... Mehrfach verkettete lineare Listen (Verweis auf die nächste Gruppe von Elementen):......... Allgemeine Listen erhält man, wenn man als Datentyp der Elemente wiederum Listen zulässt. C-Kurs Folie 21
Bäume Institut für Informatik Wurzel Blatt Jörn Hoffmann C-Kurs Folie 22
Bäume Institut für Informatik Bäume Wurzel Ist Ausgezeichnetes Element (Zugriffspunkt) Hat keine Vorgänger Element Blatt Hat genau ein Vorgänger Hat beliebig viele Nachfolger ist Element ohne Nachfolger Blätter können unterschiedliche Tiefe besitzen Jörn Hoffmann C-Kurs Folie 23
Bäume Binärbäume Binärbaum Alle Elemente besitzen höchstens zwei Nachfolger Viele Strategien zum Suchen, Einfügen, Entfernen von Elementen bekannt Insb. um große Datenmengen schnell zu verarbeiten Programmiertechnisch aufwendig Wurzel Blatt Jörn Hoffmann C-Kurs Folie 24