Dynamisches Array als "verkettete Liste"

Slides:



Advertisements
Ähnliche Präsentationen
Forschungszentrum caesar
Advertisements

Sortieren I - Bubblesort -
Sequentielle Liste - Array
FH-Hof Indirekte Adressierung Richard Göbel. FH-Hof Einfache Speicherung von Daten Eine "einfache" Deklaration definiert direkt eine Speicherplatz für.
Datentyp- umwandlung. Literale sind: Bezeichner mit einem festen Wert wie z.B:
Strukturen. In einer Struktur kann eine beliebige Anzahl von Komponenten (Daten) mit unterschiedlichen Datentypen (im Gegensatz zu Feldern) zusammengefaßt.
ARRAY oder FELD oder VEKTOR
Dynamischer Speicher. Ein Vergleich aus dem täglichen Leben...
Dynamisches Array als "verkettete Liste". Ein Vergleich.
Dynamischer Speicher und Struktur
Pointer. Grundsätzliches: Im Arbeitsspeicher werden Daten gespeichert. Um auf die Daten eindeutig zugreifen zu können, werden diesen Daten Adressen zugeordnet.
Konstruktoren.
Objekte werden als Adressen (Referenzen) übergeben. Dies führt manchmal zu unerwarteten Ergebnissen...
Polymorphie (Vielgestaltigkeit)
Assoziationen (Beziehungen). Zwischen Objekten kann es eine Beziehung geben.
Polymorphie (Vielgestaltigkeit)
Objekte und Arbeitsspeicher
V AdresseWert public static void main(...){ int[] v; v=new int[2]; } Was veranlasst diese Anweisung im Arbeitsspeicher ? Es wird im Arbeitsspeicher.
Dynamischer Speicher. In einer Funktion wird z.B. mit der Deklaration int i; Speicher auf dem sogenannten Stack reserviert. Wenn die Funktion verlassen.
ARRAY oder FELD oder VEKTOR
Vorlesung Informatik 2 Algorithmen und Datenstrukturen (05 – Elementare Datenstrukturen) Prof. Th. Ottmann.
Informatik II, SS 2008 Algorithmen und Datenstrukturen Vorlesung 6 Prof. Dr. Thomas Ottmann Algorithmen & Datenstrukturen, Institut für Informatik Fakultät.
EINI-I Einführung in die Informatik für Naturwissenschaftler und Ingenieure I Kapitel 7 Claudio Moraga, Gisbert Dittrich FBI Unido
EINI-I Einführung in die Informatik für Naturwissenschaftler und Ingenieure I Vorlesung 2 SWS WS 99/00 Gisbert Dittrich FBI Unido
IKG - Übung Diskrete Mathe I – Jörg Schmittwilken
PRJ 2007/1 Stefan Dissmann Motivation Problem: gleiche Datenstrukturen werden für verschiedene Objekte gebraucht: z.B. Listen von Studierenden, Kunden,
PKJ 2005/1 Stefan Dissmann Rückblick auf 2005 Was zuletzt in 2005 vorgestellt wurde: Klassen mit Attributen, Methoden und Konstruktoren Referenzen auf.
EDV1 - Komplexe Datentypen
Einfach verkettete Listen
Einfach verkettete Listen (OOP)
PRJ 2007/1 Stefan Dissmann Verkettete datenstruktur: Liste Problem: Liste, die eine beliebige Zahl von Elementen verwaltet Operationen: Erzeugen, Anfügen,
Einführung in die Programmiersprache C 1
Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr. Günter Rudolph Fachbereich.
Javakurs FSS 2012 Lehrstuhl Stuckenschmidt
Effiziente Algorithmen
Einführung in die Programmiersprache C 4
Programmierung 1. Einführung Seite 1
Variablenkonzept Klassisch, in Java Basistyp
Arrays / Felder Themen: Arrays / Felder / Vektoren Was soll das eigentlich? Erstellen von Arrays Arrays auslesen. Wie sie verwaltet werden.
Programmieren in C Grundlagen C 2
Polymorphie (Vielgestaltigkeit). Wenn eine Methode, wie z.B. print für verschiedene Programmteile steht (und z.B. einmal Objekte verschiedener Klassen.
early binding (frühe Bindung) late binding (späte Bindung)
Mag. Thomas Hilpold, Universität Linz, Institut für Wirtschaftsinformatik – Software Engineering 1 Algorithmen und Datenstrukturen 1 SS 2002 Mag.Thomas.
Erweiterte Zuweisungskompatibilität. Wie kann man Objekte verschiedener Klassen einer Klassenhierarchie einander zuweisen ?
Funktionen. Aufgabe : Eingabe zweier Zahlen ---> Minimum bestimmen Dann nochmals Eingabe zweier Zahlen ---> Minimum bestimmen.
Dynamisches Array als "verkettete Liste". Ein Vergleich.
Pointer. Grundsätzliches: Im Arbeitsspeicher werden Daten gespeichert. Um auf die Daten eindeutig zugreifen zu können, werden diesen Daten Adressen zugeordnet.
Funktionen, Felder und Parameter- übergabe. Funktionsaufruf mit Feld als Parameter: Parameter = Name des Feldes.
1 // Verkettete Liste 2 // demonstriert verkettete Listen und // Rekursion // (Einfügen am "Fuß") // #include struct Liste { int Element; Liste *weiter;
Tutorium Software-Engineering SS14 Florian Manghofer.
Tutorium Software-Engineering SS14 Florian Manghofer.
Pointer, Arrays und verkettete Listen. Mehrdimensionale Arrays  Pointer auf ein Array von Pointern  int32 **matrix = new int32*[3];  matrix: Zeiger.
Tutorium Software-Engineering SS14 Florian Manghofer.
Funktionen (Zweck und Eigenschaften) Funktionen sind Unterprogramme, die einen bestimmten Zweck erfüllen Sie zerlegen Probleme in kleine, abgeschlossene.
Strukturen (Eigenschaften) Strukturen dienen zur Zusammenfassung mehrerer Komponenten verschiedener Typen zu einer Einheit, die dann mit gemeinsamen Namen.
Pointer. * und &  Bei der Definition int var1; ○ // „normale“ Variable int *var2; ○ // Zeiger auf einen Integer int *var2 = NULL; ○ // … incl. Initialisierung.
Anforderungen an die neue Datenstruktur
Programmieren in C Dynamische Listen / Bäume
Konstruktoren.
Klausur „Diskrete Mathematik II“
Dynamischer Speicher malloc wird in c++ eher nicht mehr verwendet.
Von Cem, Maurice und lars
Arrays in Java Ein Array ist eine Variable, die aus einer An-zahl von Elementen des gleichen Datentyps besteht, die aufeinanderfolgend im Speicher liegen.
Es gibt Klassen, die mit der Entwicklungsumgebung ausgeliefert werden
Arrays in Java Ein Array ist eine Variable, die aus einer An-zahl von Elementen des gleichen Datentyps besteht, die aufeinanderfolgend im Speicher liegen.
Arrays in C Ein Array ist eine Variable, die aus einer Anzahl von Elementen des gleichen Datentyps besteht, die aufeinanderfolgend im Speicher liegen.
1. Die rekursive Datenstruktur Liste 1.5 Das Entwurfsmuster Kompositum
REKURSION + ITERATION.
Zufallszahlen in C erzeugen
Datentyp- umwandlung.
 Präsentation transkript:

Dynamisches Array als "verkettete Liste"

Ein Vergleich

Durch die intensive Nutzung jeden Quadratmeters Bodenfläche (Hausbau und Tomatenplantagen) gibt es in Amsterdam keine Möglichkeit mehr eine freie Bodenfläche zu finden.

Deswegen wird mittlerweile eine neue Bebauungsfläche genutzt: das Wasser in den Kanälen. Diese neue genutzte Fläche wird mit Hausbooten versehen.

X Land (Bootsteg mit nur einem Anlegepunkt) Das Boot muss mit dem Land verbunden werden. Wie wird dieses Boot mit dem Land verbunden, obwohl der Anlegepunkt belegt ist? Wie wird dieses Boot mit dem Land verbunden, obwohl der Anlegepunkt belegt ist?

Bevor wir uns zu lange in Holland aufhalten - und dabei die Tomatenbauern bei ihrer wichtigen Arbeit stören – und bevor sich unser neu erworbenes Wissen in Rauch auflöst, schnell noch ein anderer Vergleich...

In der Klasse wurde ausgemacht: Wenn jemand ein wichtiges Ereignis erfährt (wie z.B. nächste Kurzarbeit im Mathe), sollen alle Schüler der Klasse benachrichtigt werden. Wie kann man dies realisieren, ohne daß ein Schüler alle anderen anruft bzw. jeder Schüler daran beteiligt wird ?

Durch eine Telefonkette benachrichtigen sich die Schüler Gustav, Olaf, Miroslav, Wiglaf und Stanislav der Klasse Name ruft an Gustav Olaf Miroslav Wiglaf Stanislav ????????

Wen soll Stanislav anrufen? Name ruft an Gustav Olaf Miroslav Wiglaf Stanislav

Niemandem mehr, oder … Name ruft an Gustav Olaf Miroslav Wiglaf Stanislav

Gustav, dann hat man einen Telefonring Name ruft an Gustav Olaf Miroslav Wiglaf Stanislav

Von Holland, Ketten und Ringen zurück zur EDV nach Deutschland...

Warum kann man nicht beliebig viele Zahlen immer wieder hintereinander in einem Array anfügen?

Weil ein Array eine feste Länge haben muss.

Was müsste man also bei jedem Anfügevorgang machen?

dynamischen Speicher reservieren!

Beispiel:

... 0911 0345 0007 Annahme: Man will hintereinander die folgenden Zahlen abspeichern: 19 -93 , 71 , 19 -93 Man reserviert also dynamisch (d.h.während der Laufzeit) Speicher für eine Zahl, dann Speicher für die nächste Zahl, usw. Die reservierten Speicher (mit den Adressen) liefert jeweils das Betriebssystem. 71

... 0911 0345 0007 Welches Problem hat man, wenn man diese Zahlen (in der Reihenfolge wie sie abgelegt wurden) auf dem Bildschirm ausgeben will 19 Man kennt nicht die Adressen dieser Zahlen, weil diese Adressen nicht gespeichert wurden. -93 Was muss man also machen, um diese Zahlen ausgeben zu können? 71

... 0911 0345 0007 Man muss jeweils neben der Zahl auch die Adresse der nächsten Zahl speichern. 19 Man braucht also einen Datentyp, in dem neben einer Zahl eine Adresse gespeichert wird. -93 Wir nennen den Datentyp hier "dtelement" und stellen dies schematisch wie folgt dar: 71 dtelement Zahl Adresse

... 0911 0345 0007 Wie sieht dann die Verlinkung dieser Speicherblöcke mit dem Datentyp element aus? (-93 , 71 , 19) Schreiben Sie die 3 Speicherblöcke auf und verlinken sie 19 -93 71

... 0911 0345 0007 -93 0911 71 0007 19 ? ...wie kann man dieses Element als das Letzte markieren? Welche Adresse soll hier eingetragen werden und ... 19 -93 71

... 0911 0345 0007 -93 0911 71 0007 19 19 -93 71

... 0911 0345 0007 -93 0911 71 0007 19 NULL NULL ist eine spezielle Adresse, die z.B. für diesen Zweck verwendet werden kann. 19 -93 71

... 0911 0345 0007 Wie sieht die genaue Belegung im Arbeitsspeicher aus? Der Speicherblock (Zahl, Adresse), der –93 in das dynamische Array einträgt, soll abgespeichert werden. 19 NULL Was fehlt noch? -93 71 soll angefügt werden. 0911 19 soll angefügt werden. Man hat also mit dem 1. Element das ganze dynamische Array als sogenannte "verkettete Liste". 71 0007

Umsetzung in C:

#include <stdio.h> #include <malloc.h> #include "stdafx.h" #include <stdio.h> #include <malloc.h> struct dtelement{ int zahl; struct dtelement *next; }; int main(){ ... } Name der Adresse (frei wählbar) Name der Struktur (frei wählbar) Diese Adresse muss wieder auf eine Variable zeigen, die den Datentyp dtelement hat!

Reservieren Sie jeweils für die Zahl 10 und 20 dynamisch Speicher und verlinken diese Speicherplätze dann miteinander. Geben Sie anschließend - vom Anfang der verketteten Liste ausgehend - die Zahlen auf dem Bildschirm aus.

struct dtelement *anf; struct dtelement *e; anf = (struct dtelement *) int main(){ struct dtelement *anf; struct dtelement *e; anf = (struct dtelement *) malloc(sizeof( struct dtelement)); e = (struct dtelement *) Welchen Wert hat anf und e an dieser Stelle ? anf 0050 ? e 0060 ? Annahme: Die Variablen anf und e werden an der Adresse 0050 und 0060 gespeichert.

struct dtelement *anf; struct dtelement *e; anf = (struct dtelement *) int main(){ struct dtelement *anf; struct dtelement *e; anf = (struct dtelement *) malloc(sizeof( struct dtelement)); e = (struct dtelement *) Welchen Wert hat anf und e an dieser Stelle ? (also nach e = ... anf 0050 ? Annahme: Der 1. reservierte Speicher beginnt bei der Adresse 0100, Der 2. reservierte Speicher beginnt bei der Adresse 0200. e 0060 ?

struct dtelement *anf; struct dtelement *e; anf = (struct dtelement *) int main(){ struct dtelement *anf; struct dtelement *e; anf = (struct dtelement *) malloc(sizeof( struct dtelement)); e = (struct dtelement *) Wie werden die einzelnen Bereiche des Speichers an der Adresse 0100 (bzw. 0200) interpretiert bzw. was bedeuten sie? Eine Integer-Zahl Eine Adresse, die als Datentyp die Struktur dtelement hat. Eine Integer-Zahl Eine Adresse, die als Datentyp die Struktur dtelement hat. 0100 anf 0050 0100 ... e 0060 0200 ... 0200 ...

struct dtelement *anf; struct dtelement *e; anf = (struct dtelement *) int main(){ struct dtelement *anf; struct dtelement *e; anf = (struct dtelement *) malloc(sizeof( struct dtelement)); e = (struct dtelement *) Welche Werte stehen an diesen 4 Stellen? ... 0200 0100 anf 0050 0100 e 0060 0200

struct dtelement *anf; struct dtelement *e; anf = (struct dtelement *) int main(){ struct dtelement *anf; struct dtelement *e; anf = (struct dtelement *) malloc(sizeof( struct dtelement)); e = (struct dtelement *) ... 0200 0100 ? anf 0050 0100 ? e 0060 0200 ? ?

struct dtelement *anf; struct dtelement *e; anf = (struct dtelement *) int main(){ struct dtelement *anf; struct dtelement *e; anf = (struct dtelement *) malloc(sizeof( struct dtelement)); e = (struct dtelement *) Durch welche Anweisungen wird im 1. reservierten Speicher die Zahl 10 und im 2. reservierten Speicher die Zahl 20 abgespeichert? ... 0200 0100 ? anf 0050 0100 ? e 0060 0200 ? Programm geht gleich weiter... ?

(*anf).zahl = 10; ? anf 0100 ? e 0200 ? ? * 0100 .zahl ... 0200 0100 0050 0100 ? e 0060 0200 ? ?

(*anf).zahl = 10; anf 0100 ? e 0200 ? ? * 0100 .zahl ... 0200 0100 0050 0100 ? e 0060 0200 ? ?

(*anf).zahl = 10; 10 anf 0100 ? e 0200 ? ? * 0100 .zahl ... 0200 0100 0050 0100 ? e 0060 0200 ? ?

(*anf).zahl = 10; (*e).zahl = 20; 10 anf 0100 ? e 0200 ? ? * 0200 ... 0200 0100 10 anf 0050 0100 ? e 0060 0200 ? ?

(*anf).zahl = 10; (*e).zahl = 20; 10 anf 0100 ? e 0200 ? * 0200 .zahl ... 0200 0100 10 anf 0050 0100 ? e 0060 0200 ?

(*anf).zahl = 10; (*e).zahl = 20; 10 anf 0100 ? e 0200 20 ? * 0200 Durch welche Anweisung wird der 1. reservierte Speicher mit dem 2. reservierten Speicher verlinkt? (*e).zahl = 20; * 0200 .zahl ... 0200 0100 10 anf 0050 0100 ? e 0060 0200 20 ?

(*anf).zahl = 10; (*e).zahl = 20; (*anf).next = e; 10 anf 0100 ? e 0200 ... 0200 0100 10 anf 0050 0100 ? e 0060 0200 20 ?

(*anf).zahl = 10; (*e).zahl = 20; (*anf).next = e; 10 anf 0100 e 0200 ... 0200 0100 10 anf 0050 0100 e 0060 0200 20 ?

(*anf).zahl = 10; (*e).zahl = 20; (*anf).next = e; 10 anf 0100 0200 e ... 0200 0100 10 anf 0050 0100 0200 e 0060 0200 20 ?

(*anf).zahl = 10; (*e).zahl = 20; (*anf).next = e; (*e).next = NULL; Durch welche Anweisung kann man das 2. angefügte element als das Letzte markieren? (*e).zahl = 20; (*anf).next = e; (*e).next = NULL; * 0200 .next ... 0200 0100 10 anf 0050 0100 0200 e 0060 0200 20 ?

(*anf).zahl = 10; (*e).zahl = 20; (*anf).next = e; (*e).next = NULL; Durch welche Anweisung kann man das 2. angefügte element als das Letzte markieren? (*e).zahl = 20; (*anf).next = e; (*e).next = NULL; * 0200 .next ... 0200 0100 10 anf 0050 0100 0200 e 0060 0200 20

(*anf).zahl = 10; (*e).zahl = 20; (*anf).next = e; (*e).next = NULL; Durch welche Anweisung kann man das 2. angefügte element als das Letzte markieren? (*e).zahl = 20; (*anf).next = e; (*e).next = NULL; * 0200 .next ... 0200 0100 10 anf 0050 0100 0200 e 0060 0200 20 NULL

(*anf).zahl = 10; (*e).zahl = 20; (*anf).next = e; (*e).next = NULL; Damit hat man folgende Verlinkung der Elemente im Arbeitsspeicher (*e).zahl = 20; (*anf).next = e; (*e).next = NULL; return 0; } In anf (wie Anfang) ist die Adresse des 1. Elements gespeichert. Damit kann man die Liste durchlaufen. In e wird die Adresse eines neu anzufügenden Elements zwischengespeichert und dann in die Liste eingetragen (als Link auf das neue Element). ... 0200 0100 10 anf 0050 0100 0200 e 0060 0200 20 NULL

Was würde folgende zusätzliche Anweisung im Speicher veranlassen? ... (*(*anf).next).zahl = 30; Was würde folgende zusätzliche Anweisung im Speicher veranlassen? * 0100 .next * 0200 .zahl ... 0200 0100 10 anf 0050 0100 0200 e 0060 0200 20 NULL

Was würde folgende zusätzliche Anweisung im Speicher veranlassen? ... (*(*anf).next).zahl = 30; Was würde folgende zusätzliche Anweisung im Speicher veranlassen? * 0100 .next * 0200 .zahl ... 0200 0100 10 anf 0050 0100 0200 e 0060 0200 NULL

Was würde folgende zusätzliche Anweisung im Speicher veranlassen? ... (*(*anf).next).zahl = 30; Was würde folgende zusätzliche Anweisung im Speicher veranlassen? * 0100 .next * 0200 .zahl ... 0200 0100 10 anf 0050 0100 0200 e 0060 0200 30 NULL

Achtung aufgepasst: Angenommen, die rote Klammer bei (. anf) Achtung aufgepasst: Angenommen, die rote Klammer bei (*anf).zahl = 30; würde man weglassen: *anf.zahl = 30; Wie wird dann diese Anweisung vom Compiler interpretiert ?

Nicht als: (. anf). zahl = 30; sondern als. (anf Nicht als: (*anf).zahl = 30; sondern als *(anf.zahl) = 30; weil der Punkt . eine höhere Priorität hat als der Stern * Das ergibt aber eine Fehlermeldung des Compilers, weil *(anf.zahl) = 30; keinen Sinn ergibt.

Aufgabe: Erstellen Sie die folgenden Funktionen ...

struct dtelement. anfuegen(struct dtelement struct dtelement *anfuegen(struct dtelement *dynArray, int wert) Beschreibung: fügt an ein dynamisches Array (verkettete Liste) eine Zahl an. Gibt Adresse des (letzten) neu angefügten Elements zurück. dynArray ist die Adresse des letzten Elements

#include "stdafx. h" #include <stdio. h> #include <malloc #include "stdafx.h" #include <stdio.h> #include <malloc.h> struct dtelement{ int zahl; struct dtelement *next; }; struct dtelement *anfuegen( struct dtelement *dynArray, int wert);

int main(){ struct dtelement. dynArray; struct dtelement int main(){ struct dtelement *dynArray; struct dtelement *anfang; dynArray = anfuegen(NULL, 9); anfang = dynArray; dynArray = anfuegen(dynArray, 5); dynArray = anfuegen(dynArray, 13); return 0; }

struct dtelement. anfuegen( struct dtelement struct dtelement *anfuegen( struct dtelement *dynArray, int wert){ struct dtelement *kg; kg bedeutet Kettenglied. In Ihrem Quellcode bitte Variable mit kettenglied bezeichnen

Dieser ist die dynamische Liste. struct dtelement *anfuegen( struct dtelement *dynArray, int wert){ struct dtelement *kg; if(dynArray == NULL){ NULL bedeutet: es existiert noch keine verkettete Liste, also muß der folgende Speicherblock erzeugt werden. Dieser ist die dynamische Liste. wert NULL

struct dtelement. anfuegen( struct dtelement struct dtelement *anfuegen( struct dtelement *dynArray, int wert){ struct dtelement *kg; if(dynArray == NULL){ kg=(struct dtelement*) malloc(sizeof( struct dtelement)); Hole Speicher für ein neues Element und speichere die Anfangsadresse des Speichers in kg

Trage den Wert in das dynamische Array ein struct dtelement *anfuegen( struct dtelement *dynArray, int wert){ struct dtelement *kg; if(dynArray == NULL){ kg=(struct dtelement*) malloc(sizeof( struct dtelement)); (*kg).zahl = wert; Trage den Wert in das dynamische Array ein

Trage das letzte Element des dynamischen Arrays ein struct dtelement *anfuegen( struct dtelement *dynArray, int wert){ struct dtelement *kg; if(dynArray == NULL){ kg=(struct dtelement*) malloc(sizeof( struct dtelement)); (*kg).zahl = wert; (*kg).next = NULL; Trage das letzte Element des dynamischen Arrays ein

Gib dieses Element zurück struct dtelement *anfuegen( struct dtelement *dynArray, int wert){ struct dtelement *kg; if(dynArray == NULL){ kg=(struct dtelement*) malloc(sizeof( struct dtelement)); (*kg).zahl = wert; (*kg).next = NULL; return kg; } Gib dieses Element zurück

Dann muß ein Element angefügt werden… else{ verkettete Liste existiert schon (wir nehmen hier an, daß sie aus 2 Elementen besteht). Dann muß ein Element angefügt werden… Da es jetzt das letzte Element ist, wird es mit NULL bestückt und es muß noch mit der aktuellen verkettenen Liste verbunden werden. Was ist zu tun ? wert1 0911 wert2 Null wert3 NULL

Dann muß ein Element angefügt werden… else{ Adresse des Speicherblocks, der den Wert wert3 hat eintragen verkettete Liste existiert schon (wir nehmen hier an, daß sie aus 2 Elementen besteht). Dann muß ein Element angefügt werden… Da es jetzt das letzte Element ist, wird es mit NULL bestückt und es muß noch mit der aktuellen verkettenen Liste verbunden werden. Was ist zu tun ? In die Schublade ADRESSE des zweiten Speicherblocks die Adresse des neu anzufügenden Elements eintragen! wert1 0911 wert2 wert3 NULL

else{ kg=(struct dtelement*) malloc(sizeof( struct dtelement)); Hole Speicher für ein neues Element und speichere die Anfangsadresse des Speichers in kg

Bestücke das Kettenglied mit den entsprechenden Werten else{ kg=(struct dtelement*) malloc(sizeof( struct dtelement)); (*kg).zahl = wert; (*kg).next = NULL; Bestücke das Kettenglied mit den entsprechenden Werten

Verknüpfe das Kettenglied mit dem dynamischen Array else{ kg=(struct dtelement*) malloc(sizeof( struct dtelement)); (*kg).zahl = wert; (*kg).next = NULL; (*dynArray).next=kg; Verknüpfe das Kettenglied mit dem dynamischen Array

Gib das Kettenglied zurück else{ kg=(struct dtelement*) malloc(sizeof( struct dtelement)); (*kg).zahl = wert; (*kg).next = NULL; (*dynArray).next=kg; return kg; } } Gib das Kettenglied zurück

int main(){ struct dtelement. dynArray; struct dtelement int main(){ struct dtelement *dynArray; struct dtelement *anfang; dynArray = anfuegen(NULL, 9); anfang = dynArray; dynArray = anfuegen(dynArray, 5); dynArray = anfuegen(dynArray, 13); return 0; } In dynArray ist nur die Adresse des letzten Elements der Liste gespeichert. Daher kann man über die in dynArray gespeicherte Adresse nicht mehr auf die in der Liste gespeicherten Werte zugreifen! Warum ist diese Anweisung notwendig, wenn man alle in der Liste gespeicherten Werte auf dem Bildschirm ausgeben will ?

Weiter mit den Funktionen,die Sie nun implementieren müssen:

void printList(struct dtelement void printList(struct dtelement *dynArray) Beschreibung: gibt ein dynamisches Array (verkettete Liste) auf dem Bildschirm aus.

void delList (struct dtelement void delList (struct dtelement *dynArray) Beschreibung: löscht das ganze dynamische Array (verkettete Liste). void delElement (struct dtelement *element) Beschreibung: löscht ein Element des dynamischen Arrays (verkettete Liste).

Bemerkungen zur Funktion: void delElement (struct dtelement Bemerkungen zur Funktion: void delElement (struct dtelement *element) Beispiel: Das Element mit der Adresse 0070 soll aus der Liste gelöscht werden. Also...

Dieses komplette Element soll gelöscht werden Dieses komplette Element soll gelöscht werden. Reicht es aus, diesen Speicherbereich mit free freizugeben ? Also ... 0050 10 0070 30 0090 20 0060 0070 0080 0090 0100 NULL

10 20 0070 NULL 0050 0090 0060 0100 Welche Probleme gibt es jetzt ? Die Verlinkung stimmt nicht mehr! Das Element, das die Zahl 10 enthält, zeigt nicht mehr auf das Element, das die Zahl 20 enthält. Also ... 0050 10 0090 20 0060 0070 0100 NULL

Was muss also noch gemacht werden? 0050 10 0070 30 0090 20 0060 0070 0080 0090 0100 NULL Von diesem Element muss die Adresse des Vorgängers und die Adresse des Nachfolgers ermittelt werden und dann der Vorgänger mit dem Nachfolger verlinkt werden. Dann muss das Element gelöscht werden.

Was muss also noch gemacht werden? 0050 10 0070 30 0090 20 0060 0070 0080 0090 0100 NULL Von diesem Element muss die Adresse des Vorgängers und die Adresse des Nachfolgers ermittelt werden und dann der Vorgänger mit dem Nachfolger verlinkt werden. Dann muss das Element gelöscht werden.

Was muss also noch gemacht werden? 0050 10 0070 30 0090 20 0060 0080 0090 0100 NULL Von diesem Element muss die Adresse des Vorgängers und die Adresse des Nachfolgers ermittelt werden und dann der Vorgänger mit dem Nachfolger verlinkt werden. Dann muss das Element gelöscht werden.

Was muss also noch gemacht werden? 0050 10 0070 30 0090 20 0060 0090 0080 0090 0100 NULL Von diesem Element muss die Adresse des Vorgängers und die Adresse des Nachfolgers ermittelt werden und dann der Vorgänger mit dem Nachfolger verlinkt werden. Dann muss das Element gelöscht werden.

Was muss also noch gemacht werden? 0050 10 0090 20 0060 0090 0100 NULL

Wie kann die Adresse des Vorgängers ermittelt werden? 0050 10 0090 20 0060 0090 0100 NULL Indem man z.B. in der Liste in jedem Element nicht nur die Adresse des Nachfolgers, sondern auch die des Vorgängers speichert (dies heißt eine doppelt verkettete Liste).

Gibt es auch noch eine andere Lösung? 0050 10 0090 20 0060 0090 0100 NULL Man gibt in der Funktion als Parameter nicht die Adresse des zu löschenden Elements an, sondern .... die Adresse des Vorgängers des zu löschenden Elements ... dann kann in der Funktion die Adresse des Nachfolgers und des Nach-Nachfolgers ermittelt werden und die Liste muss nur einfach verkettet sein (nur jeweiligen Nachfolger eines Elements speichern).

Welches Element der Liste könnte dann aber nicht gelöscht werden? Warum? Das 1. Element könnte nicht gelöscht werden, weil es keinen Vorgänger hat. Wie könnte man dies trotzdem noch erreichen? In dem man die Parameterliste um einen Parameter erweitert. In diesem wird angegeben, ob das 1. Element gelöscht werden soll oder nicht.