C-‐Kurs 09 Dynamische Datenstrukturen

Werbung
Institut für Informatik
C-­‐Kurs 09 Dynamische Datenstrukturen Dipl.-­‐Inf. Jörn Hoffmann jhoff[email protected]­‐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
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");
(*ptr2)(2);
!
return 0;!
// Aufruf !
// Aufruf (alternativ)!
}!
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
Dr. Monika Meiler
13.3
Spezielle verkettete lineare Listen und Bäume
13.3.1 Listen
Institut für Informatik
Lineare Listen
Typen
Einfach verkettete lineare Listen
...
anfang
NULL
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.
Zyklisch verkettete lineare Listen (Listenende zeigt auf den Anfang):
anfang
...
Doppelt verkettete lineare Listen (Verweis auf Vorgänger und Nachfolger):
Jörn Hoffmann
...
C-Kurs
Folie 20
...
...
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.
Lineare Listen
Typen
Institut für Informatik
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
Auch hier gibt es gewisse Strategien zum Suchen, Einfügen und Entfernen von Elementen,
insbesondere um große Datenmengen schnell zu verarbeiten, die aber programmiertechnisch
Bäume
wesentlich aufwendiger sind.
Institut für Informatik
Wurzel
NULL
NULL
NULL
NULL
Blatt
NULL
Jörn Hoffmann
NULL
NULL
C-Kurs
NULL
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
Universität Leipzig
Institut für Informatik
Institut für Informatik
Dr. Monika Meiler
13.3.2 Bäume
Bäume:
Ein Baum hat ein ausgezeichnetes Element, die Wurzel. Diese hat keinen Vorgänger. Jedes
weitere Element eines Baumes besitzt genau einen Vorgänger und beliebig viele Nachfolger.
Elemente ohne Nachfolger nennt man Blätter.
Binärbaum
•  Alle Elemente besitzen höchstens zwei Nachfolger
Binärbäume:
•  Viele Strategien zum Suchen, Einfügen,
Entfernen
von höchstens
Elementen
bekannt
Ein Binärbaum ist
ein Baum, dessen Elemente
zwei Nachfolger
besitzen.
•  Insb. um große Datenmengen
zu verarbeiten
Auchschnell
hier gibt es gewisse
Strategien zum Suchen, Einfügen und Entfernen von Elementen,
insbesondere um große Datenmengen schnell zu verarbeiten, die aber programmiertechnisch
wesentlich aufwendiger sind.
•  Programmiertechnisch aufwendig
Wurzel
NULL
NULL
NULL
NULL
Blatt
NULL
Jörn Hoffmann
C-Kurs
NULL
NULL
NULL
Folie 24
Herunterladen