C-Kurs 09 Dynamische Datenstrukturen

Werbung
Institut für Informatik
C-Kurs
09 Dynamische Datenstrukturen
Dipl.-Inf. Jörn Hoffmann
[email protected]
Universität Leipzig
Institut für Informatik
Technische Informatik
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
2. Funktionszeiger
3. Lineare Listen
4. Bäume
Jörn Hoffmann
*(ptr).element  ptr->element
int (*ptr)(int);
knoten->next;
knoten->a | knoten->b;
C-Kurs
Folie 2
Zeiger
Elementzugriff
Institut für Informatik
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
Institut für Informatik
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
Institut für Informatik
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
Institut für Informatik
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 element;
struct _knoten *next;
} knoten_t;
// Lineare Liste
knoten_t *k1 = malloc(sizeof(knoten_t));
knoten_t *k2 = malloc(sizeof(knoten_t));
k1.next = k2;
k2.next = NULL;
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 NULL
*kopf
*(kopf.next)
NULL
kopf
Jörn Hoffmann
element
next
element
C-Kurs
next
Folie 11
Lineare Liste
Einfügen (Idee)
Institut für Informatik
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
element next
(1)
(2)
*kopf
Listenende
NULL
kopf
Jörn Hoffmann
element
next
element
C-Kurs
next
Folie 12
Lineare Liste
Einfügen
Institut für Informatik
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
element
next
*kopf
*next
*next
NULL
...
kopf
element
Jörn Hoffmann
next
element
next
C-Kurs
element
next
Folie 13
Lineare Liste
Einfügen
Institut für Informatik
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
element
*kopf
next
*next
*next
NULL
...
kopf
element
Jörn Hoffmann
next
element
next
C-Kurs
element
next
Folie 14
Lineare Liste
Einfügen
Institut für Informatik
2. Knoten einfügen
• Wert des next-Zeigers vom neuen Knoten auf aktuellen Knoten setzen
neu
hilf
element
*kopf
next
*next, neu->next
*next
NULL
...
kopf
element
Jörn Hoffmann
next
element
next
C-Kurs
element
next
Folie 15
Lineare Liste
Einfügen
Institut für Informatik
3. Vorgänger anpassen
• Next-Zeiger vom Vorgängerknoten auf neuen Knoten setzen
• Dieser kann mittels Hilfszeiger direkt manipulieren werden
neu
hilf
element
*kopf
next
*next, neu->next
*next
NULL
...
kopf
element
Jörn Hoffmann
next
element
next
C-Kurs
element
next
Folie 16
Lineare Liste
Einfügen
Institut für Informatik
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
element
next
neu->next
*next
NULL
...
kopf
Jörn Hoffmann
element
next
C-Kurs
element
next
Folie 17
Lineare Liste
Einfügen
Institut für Informatik
4. Fertig
• Knoten ist jetzt eingefügt
• Kopf wurde möglicherweise verändert
*kopf
*next
*next
NULL
...
kopf
element
Jörn Hoffmann
next
element
next
C-Kurs
element
next
Folie 18
Lineare Liste
Beispiel
Institut für Informatik
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 != NULL)
{
if(knoten->element > neuerKnoten->element) // Vergleich zur Entscheidung
break;
hilf = &knoten->next;
// Adresse des Next-Zeiger speichern (kann direkt manipuliert werden)
knoten = knoten->next;
// Nächster Knoten
}
// Vorhandene Knoten an neuen Knoten anfügen
neuerKnoten->next = knoten;
// Vorgänger bzw. Kopf direkt anpassen
*hilf = neuerKnoten;
}
Jörn Hoffmann
C-Kurs
Folie 19
Lineare Listen
Typen
Institut für Informatik
Jörn Hoffmann
C-Kurs
Folie 20
Lineare Listen
Typen
Institut für Informatik
C-Kurs
Folie 21
Bäume
Institut für Informatik
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
• Hat genau ein Vorgänger
• Hat beliebig viele Nachfolger
• Blatt
• ist Element ohne Nachfolger
• Blätter können unterschiedliche Tiefe besitzen
Jörn Hoffmann
C-Kurs
Folie 23
Bäume
Binärbäume
Institut für Informatik
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
Jörn Hoffmann
C-Kurs
Folie 24
Herunterladen