Einfhrung rekursiver Datenstrukturen in C Timm Grams Fachhochschule

  • Slides: 23
Download presentation
Einführung rekursiver Datenstrukturen in C Timm Grams Fachhochschule Fulda Fachbereich Elektrotechnik und Informationstechnik ©

Einführung rekursiver Datenstrukturen in C Timm Grams Fachhochschule Fulda Fachbereich Elektrotechnik und Informationstechnik © Timm Grams, Fulda, 15. 02

Benutzerdefinierte Datentypen Der Strukturtyp (Beispiel: komplexe Zahlen) struct complex {float x, y; } a[3]

Benutzerdefinierte Datentypen Der Strukturtyp (Beispiel: komplexe Zahlen) struct complex {float x, y; } a[3] = {{3, 4}, {-6, 8}, { 9, -12}};

Benutzerdefinierte Datentypen Deklarationsspezifikator (declaration-specifier) struct complex {float x, y; } a[3] = {{3, 4},

Benutzerdefinierte Datentypen Deklarationsspezifikator (declaration-specifier) struct complex {float x, y; } a[3] = {{3, 4}, {-6, 8}, { 9, -12}};

Benutzerdefinierte Datentypen Deklarator (declarator) struct complex {float x, y; } a[3] = {{3, 4},

Benutzerdefinierte Datentypen Deklarator (declarator) struct complex {float x, y; } a[3] = {{3, 4}, {-6, 8}, { 9, -12}};

Benutzerdefinierte Datentypen Initialisator (initializer) struct complex {float x, y; } a[3] = {{3, 4},

Benutzerdefinierte Datentypen Initialisator (initializer) struct complex {float x, y; } a[3] = {{3, 4}, {-6, 8}, { 9, -12}};

Beispiel: ebene Bahnkurve Die Bahn eines Roboters in der Ebene ist mittels einer Punktfolge

Beispiel: ebene Bahnkurve Die Bahn eines Roboters in der Ebene ist mittels einer Punktfolge zu beschreiben: (0. 25, 0. 20), (0. 12, 0. 75), . . . , (-1. 77, 4. 65). Für die Punktfolge wird ein Array komplexer Zahlen eingeführt: struct complex Bahn[1000];

Nachteil des komplexen Arrays Die maximale Anzahl von Elementen der Bahnkurve (hier: 1000) muss

Nachteil des komplexen Arrays Die maximale Anzahl von Elementen der Bahnkurve (hier: 1000) muss dem ungünstigsten Fall Rechnung tragen. Werden - wie hier - nur 100 Plätze tatsächlich benötigt, wird Speicherplatz vergeudet. Stack 0 x: 0. 25 y: 0. 20 1 x: 0. 12 y: 0. 75. . . 99 x: -1. 77 y: 4. 65 100 x: ? y: ? . . . 999 x: ? y: ?

Besser: Array von Pointern und dynamische Speicherreservierung struct complex *Bahn[1000]; Bahn[2]= malloc(sizeof(struct complex)); Bahn[2]->x=0.

Besser: Array von Pointern und dynamische Speicherreservierung struct complex *Bahn[1000]; Bahn[2]= malloc(sizeof(struct complex)); Bahn[2]->x=0. 25; Bahn[2]->y=0. 2; 0 1 2 0 0 0 x: 0. 25 y: 0. 2 Stack 999 0 Heap

Dynamische Variablen sind heikel Typische Programmierfehler und Probleme Erzeugung von Datenmüll und Verlust von

Dynamische Variablen sind heikel Typische Programmierfehler und Probleme Erzeugung von Datenmüll und Verlust von Speicherplatz (garbage, memory leak) Baumelnde Zeiger (dangling references)

Garbage (memory leak) Bahn[2]= malloc(sizeof(struct complex)); Stack 0 1 2 0 0 0 999

Garbage (memory leak) Bahn[2]= malloc(sizeof(struct complex)); Stack 0 1 2 0 0 0 999 0 Heap x: 0. 25 y: 0. 2

Garbage (memory leak) Bahn[2]= malloc(sizeof(struct complex)); Stack 0 1 2 0 0 0 999

Garbage (memory leak) Bahn[2]= malloc(sizeof(struct complex)); Stack 0 1 2 0 0 0 999 0 Heap x: 0. 25 y: 0. 2

Baumelnder Zeiger (dangling reference) free(Bahn[2]); Stack 0 1 2 0 0 0 999 0

Baumelnder Zeiger (dangling reference) free(Bahn[2]); Stack 0 1 2 0 0 0 999 0 Heap x: 0. 25 Daten y: 0. 2 aus einem anderen Kontext

Nachteil des Pointer-Arrays Das Pointer-Array reduziert den Speicherbedarf etwas. Merklich wird der Effekt erst

Nachteil des Pointer-Arrays Das Pointer-Array reduziert den Speicherbedarf etwas. Merklich wird der Effekt erst bei komplexeren Strukturen. Aber immer noch ist die maximale Anzahl der Listenelemente vorab zu schätzen. Bei Großzügigkeit wird Speicherplatz vergeudet. Bei Knausrigkeit ist eine spätere Programmänderung höchstwahrscheinlich. Ziel: Nur den Speicherplatz reservieren, der tatsächlich benötigt wird. Methode: Rekursive Datenstrukturen.

Rekursive Datenstrukturen in C Neudefinition: complex als rekursiver Datentyp struct complex {float x, y;

Rekursive Datenstrukturen in C Neudefinition: complex als rekursiver Datentyp struct complex {float x, y; struct complex *next; }; So wird man das Schlüsselwort struct los: #define complex struct complex {float x, y; complex *next; }; So ist es besser (weil vom Compiler kontrolliert): typedef struct complex {float x, y; struct complex *next; } complex;

Lineare Liste komplexer Zahlen Aufbau der Liste complex *p=0, *h; unsigned char c='j'; while(c=='j')

Lineare Liste komplexer Zahlen Aufbau der Liste complex *p=0, *h; unsigned char c='j'; while(c=='j') { h=(complex*)malloc(sizeof(complex)); printf("n? x y = "); scanf("%f %f", &h->x, &h->y); h->next=p; p=h; printf("n? Weiter mit "j": "); scanf("%1 s", &c); }

Aufbau der linearen Liste Stack p 0 h ? Heap x: 0. 25 y:

Aufbau der linearen Liste Stack p 0 h ? Heap x: 0. 25 y: 0. 2 next: 0 h= (complex*)malloc. . . ; printf("n? x y = "). . . ; h->next=p; p=h;

Aufbau der linearen Liste Stack p 0 h= (complex*)malloc. . . ; Heap x:

Aufbau der linearen Liste Stack p 0 h= (complex*)malloc. . . ; Heap x: 0. 25 y: 0. 2 next: 0

Aufbau der linearen Liste Stack p 0 h 0 Heap x: 0. 25 y:

Aufbau der linearen Liste Stack p 0 h 0 Heap x: 0. 25 y: 0. 2 next: 0 x: 1. 2 y: 0. 75 next: h= (complex*)malloc. . . ; printf("n? x y = "). . . ; h->next=p; p=h;

Aufbau der linearen Liste Stack p 0 h 0 Heap x: 0. 25 y:

Aufbau der linearen Liste Stack p 0 h 0 Heap x: 0. 25 y: 0. 2 next: 0 x: 1. 2 y: 0. 75 next: h= (complex*)malloc. . . ; printf("n? x y = "). . . ; h->next=p; p=h;

Aufbau der linearen Liste „Begradigung der Zeichnung“ Stack p 0 h 0 Heap x:

Aufbau der linearen Liste „Begradigung der Zeichnung“ Stack p 0 h 0 Heap x: 1. 2 y: 0. 75 next: x: 0. 25 y: 0. 2 next: 0 Im Speicher (Heap) werden die Objekte NICHT bewegt!

Lineare Liste Der zuletzt eingegebene Punkt ist erstes Element der Liste. Durchlaufen der Elemente

Lineare Liste Der zuletzt eingegebene Punkt ist erstes Element der Liste. Durchlaufen der Elemente in Eingabereihenfolge mittels rekursiver Funktion. Anmerkung: Man hätte die Liste gleich in richtiger Folge aufbauen oder nachträglich umordnen können. Dann wäre ein Durchlaufen mittels Iteration möglich: cur=p; while (cur) {. . . cur=cur->next; }

Ausgabe mit rekursiver Funktion void show(complex *p) { if (p!=0) { show(p->next); printf("n%10 e",

Ausgabe mit rekursiver Funktion void show(complex *p) { if (p!=0) { show(p->next); printf("n%10 e", p->x, p->y); } }

Ende der Demonstration

Ende der Demonstration