Dynamisches Array als verkettete Liste Ein Vergleich Durch
- Slides: 83
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?
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 in 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 Gustav Olaf Miroslav Wiglaf Stanislav ruft an Olaf Miroslav Wiglaf Stanislav ? ? ? ?
Wen soll Stanislav anrufen? Name Gustav Olaf Miroslav Wiglaf Stanislav ruft an Olaf Miroslav Wiglaf Stanislav
Niemandem mehr, oder … Name Gustav Olaf Miroslav Wiglaf Stanislav ruft an Olaf Miroslav Wiglaf Stanislav
Gustav, dann hat man einen Telefonring Name Gustav Olaf Miroslav Wiglaf Stanislav ruft an 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:
. . . Annahme: Man will hintereinander die folgenden Zahlen abspeichern: . . . 0007 19 . . . -93 , 71 , 19 . . . 0345 -93 . . . 0911 . . . 71 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.
. . . 0007 19 . . . 0345 -93 . . . 0911 . . . 71 Welches Problem hat man, wenn man diese Zahlen (in der Reihenfolge wie sie abgelegt wurden) auf dem Bildschirm ausgeben will Man kennt nicht die Adressen dieser Zahlen, weil diese Adressen nicht gespeichert wurden. Was muss man also machen, um diese Zahlen ausgeben zu können?
. . . 0007 19 . . . 0345 -93 . . . 0911 . . . 71 Man muss jeweils neben der Zahl auch die Adresse der nächsten Zahl speichern. Man braucht also einen Datentyp, in dem neben einer Zahl eine Adresse gespeichert wird. Wir nennen den Datentyp hier "dtelement" und stellen dies schematisch wie folgt dar: dtelement Zahl Adresse
. . . 0007 19 . . . 0345 -93 . . . 0911 . . . 71 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
. . . -93 0911 . . . 0007 19 . . . 0345 -93 . . . 0911 . . . 71 71 0007 Welche Adresse soll hier eingetragen werden und. . . wie kann man dieses Element als das Letzte markieren? 19 ?
. . . -93 0911 . . . 0007 19 . . . 0345 -93 . . . 0911 . . . 71 71 0007 19
. . . -93 0911 . . . 0007 19 . . . 0345 -93 . . . 0911 . . . 71 71 0007 NULL ist eine spezielle Adresse, die z. B. für diesen Zweck verwendet werden kann. 19 NULL
. . . 0007 . . . 19 NULL . . . 0345. . . -93 0911 . . . 71 0007 Wie sieht die genaue Belegung im Arbeitsspeicher aus? Der Speicherblock (Zahl, Adresse), der – 93 in das dynamische Array einträgt, soll abgespeichert werden. Was fehlt noch? 71 soll angefügt werden. 19 soll angefügt werden. Man hat also mit dem 1. Element das ganze dynamische Array als sogenannte "verkettete Liste".
Umsetzung in C:
#include "stdafx. h" #include <stdio. h> #include <malloc. h> Name der Adresse (frei wählbar) Name der Struktur (frei wählbar) struct dtelement{ int zahl; struct dtelement *next; }; int main(){. . . } 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.
int main(){ Welchen Wert hat anf und e an dieser Stelle ? struct dtelement *anf; struct dtelement *e; anf = (struct dtelement *) malloc(sizeof( struct dtelement)); e = (struct dtelement *) malloc(sizeof( struct dtelement)); anf 0050 ? e 0060 ? Annahme: Die Variablen anf und e werden an der Adresse 0050 und 0060 gespeichert.
int main(){ Welchen Wert hat anf struct dtelement *anf; und e an dieser Stelle ? (also nach e =. . . struct dtelement *e; anf = (struct dtelement *) malloc(sizeof( struct dtelement)); e = (struct dtelement *) malloc(sizeof( struct dtelement)); anf 0050 ? e 0060 ? Annahme: Der 1. reservierte Speicher beginnt bei der Adresse 0100, Der 2. reservierte Speicher beginnt bei der Adresse 0200.
Wie werden die einzelnen Bereiche int main(){ Eine Integer-Zahl des Speichers an der Adresse 0100 struct dtelement *anf; (bzw. 0200) interpretiert bzw. was Eine Adresse, die als struct dtelement *e; bedeuten sie? Datentyp die Struktur anf hat. = (struct dtelement *) dtelement malloc(sizeof( Eine Integer-Zahl struct dtelement)); e Adresse, = (struct dtelement *) Eine die als malloc(sizeof( Datentyp die Struktur dtelement hat. struct dtelement)); anf 0050 0100 e 0060 0200 0100. . . 0200. . .
int main(){ Welche Werte stehen an diesen 4 Stellen? struct dtelement *anf; struct dtelement *e; anf = (struct dtelement *) malloc(sizeof( struct dtelement)); e = (struct dtelement *) malloc(sizeof( struct dtelement)); anf 0050 0100 e 0060 0200 0100. . . 0200. . .
int main(){ struct dtelement *anf; struct dtelement *e; anf = (struct dtelement *) malloc(sizeof( struct dtelement)); e = (struct dtelement *) malloc(sizeof( struct dtelement)); anf 0050 0100 e 0060 0200 0100. . . 0200. . . ? ?
Durch welche Anweisungen wird im int main(){ 1. reservierten Speicher die Zahl 10 struct dtelement *anf; und im 2. reservierten Speicher die struct dtelement Zahl 20*e; abgespeichert? anf = (struct dtelement *) malloc(sizeof( struct dtelement)); e = (struct dtelement *) malloc(sizeof( struct dtelement)); 0100 ? anf 0050 0100. . . ? e 0060. . . 0200 ? Programm geht gleich weiter. . . ?
(*anf). zahl = 10; *0100. zahl anf 0050 0100 e 0060 0200 0100. . . 0200. . . ? ?
(*anf). zahl = 10; *0100. zahl anf 0050 0100 e 0060 0200 0100. . . 0200. . . ? ? ?
(*anf). zahl = 10; *0100. zahl anf 0050 0100 e 0060 0200 0100. . . 0200. . . 10 ? ? ?
(*anf). zahl = 10; (*e). zahl = 20; *0200. zahl anf 0050 0100 e 0060 0200 0100. . . 0200. . . 10 ? ? ?
(*anf). zahl = 10; (*e). zahl = 20; *0200. zahl anf 0050 0100 e 0060 0200 0100. . . 0200. . . 10 ? ?
(*anf). zahl = 10; (*e). zahl = 20; *0200. zahl anf 0050 0100 e 0060 0200 Durch welche Anweisung wird der 1. reservierte Speicher mit dem 2. reservierten Speicher verlinkt? 0100. . . 0200. . . 10 ? 20 ?
(*anf). zahl = 10; (*e). zahl = 20; (*anf). next = e; *0100. next 0200 anf 0050 0100 e 0060 0200 0100. . . 0200. . . 10 ? 20 ?
(*anf). zahl = 10; (*e). zahl = 20; (*anf). next = e; *0100. next 0200 anf 0050 0100 e 0060 0200 0100. . . 0200. . . 10 20 ?
(*anf). zahl = 10; (*e). zahl = 20; (*anf). next = e; *0100. next 0200 anf 0050 0100 e 0060 0200 0100. . . 0200. . . 10 0200 20 ?
(*anf). zahl (*e). zahl = (*anf). next (*e). next = = 10; 20; = e; NULL; Durch welche Anweisung kann man das 2. angefügte element als das Letzte markieren? *0200. next anf 0050 0100 e 0060 0200 0100. . . 0200. . . 10 0200 20 ?
(*anf). zahl (*e). zahl = (*anf). next (*e). next = = 10; 20; = e; NULL; Durch welche Anweisung kann man das 2. angefügte element als das Letzte markieren? *0200. next anf 0050 0100 e 0060 0200 0100. . . 0200. . . 10 0200 20
(*anf). zahl (*e). zahl = (*anf). next (*e). next = = 10; 20; = e; NULL; Durch welche Anweisung kann man das 2. angefügte element als das Letzte markieren? *0200. next anf 0050 0100 e 0060 0200 0100. . . 0200. . . 10 0200 20 NULL
} (*anf). zahl (*e). zahl = (*anf). next (*e). next = return 0; = 10; 20; = e; NULL; Damit hat man folgende Verlinkung der Elemente im Arbeitsspeicher 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). anf 0050 0100 e 0060 0200 0100. . . 0200. . . 10 0200 20 NULL
. . . (*(*anf). next). zahl = 30; *0100. next *0200. zahl anf 0050 0100 e 0060 0200 Was würde folgende zusätzliche Anweisung im Speicher veranlassen? 0100. . . 0200. . . 10 0200 20 NULL
. . . (*(*anf). next). zahl = 30; *0100. next *0200. zahl anf 0050 0100 e 0060 0200 Was würde folgende zusätzliche Anweisung im Speicher veranlassen? 0100. . . 0200. . . 10 0200 NULL
. . . (*(*anf). next). zahl = 30; *0100. next *0200. zahl anf 0050 0100 e 0060 0200 Was würde folgende zusätzliche Anweisung im Speicher veranlassen? 0100. . . 0200. . . 10 0200 30 NULL
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. 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 *dyn. Array, int wert) Beschreibung: fügt an ein dynamisches Array (verkettete Liste) eine Zahl an. Gibt Adresse des (letzten) neu angefügten Elements zurück. dyn. Array ist die Adresse des letzten Elements
#include "stdafx. h" #include <stdio. h> #include <malloc. h> struct dtelement{ int zahl; struct dtelement *next; }; struct dtelement *anfuegen( struct dtelement *dyn. Array, int wert);
int main(){ struct dtelement *dyn. Array; struct dtelement *anfang; dyn. Array = anfuegen(NULL, 9); anfang = dyn. Array; dyn. Array = anfuegen(dyn. Array, 5); dyn. Array = anfuegen(dyn. Array, 13); return 0; }
struct dtelement *anfuegen( struct dtelement *dyn. Array, int wert){ struct dtelement *kg; kg bedeutet Kettenglied. In Ihrem Quellcode bitte Variable mit kettenglied bezeichnen
struct dtelement *anfuegen( struct dtelement *dyn. Array, int wert){ struct dtelement *kg; if(dyn. Array == 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 *dyn. Array, int wert){ struct dtelement *kg; if(dyn. Array == NULL){ kg=(struct dtelement*) malloc(sizeof( struct dtelement)); Hole Speicher für ein neues Element und speichere die Anfangsadresse des Speichers in kg
struct dtelement *anfuegen( struct dtelement *dyn. Array, int wert){ struct dtelement *kg; if(dyn. Array == NULL){ kg=(struct dtelement*) malloc(sizeof( struct dtelement)); (*kg). zahl = wert; Trage den Wert in das dynamische Array ein
struct dtelement *anfuegen( struct dtelement *dyn. Array, int wert){ struct dtelement *kg; if(dyn. Array == NULL){ kg=(struct dtelement*) malloc(sizeof( struct dtelement)); (*kg). zahl = wert; (*kg). next = NULL; Trage das letzte Element des dynamischen Arrays ein
struct dtelement *anfuegen( struct dtelement *dyn. Array, int wert){ struct dtelement *kg; if(dyn. Array == NULL){ kg=(struct dtelement*) malloc(sizeof( struct dtelement)); (*kg). zahl = wert; (*kg). next = NULL; return kg; Gib dieses Element zurück }
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 ? wert 1 0911 wert 2 Null wert 3 NULL
Adresse des Speicherblocks, der den Wert wert 3 hat eintragen 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 ? In die Schublade ADRESSE des zweiten Speicherblocks die Adresse des neu anzufügenden Elements eintragen! wert 1 0911 wert 2 wert 3 NULL
else{ kg=(struct dtelement*) malloc(sizeof( struct dtelement)); Hole Speicher für ein neues Element und speichere die Anfangsadresse des Speichers in kg
else{ kg=(struct dtelement*) malloc(sizeof( struct dtelement)); (*kg). zahl = wert; (*kg). next = NULL; Bestücke das Kettenglied mit den entsprechenden Werten
else{ kg=(struct dtelement*) malloc(sizeof( struct dtelement)); (*kg). zahl = wert; (*kg). next = NULL; (*dyn. Array). next=kg; Verknüpfe das Kettenglied mit dem dynamischen Array
else{ kg=(struct dtelement*) malloc(sizeof( struct dtelement)); (*kg). zahl = wert; (*kg). next = NULL; (*dyn. Array). next=kg; return kg; } } Gib das Kettenglied zurück
In dyn. Array ist nur die Adresse des letzten Elements der Liste int main(){ gespeichert. Daher kann man über die in dyn. Array gespeicherte struct dtelement *dyn. Array; Adresse nicht mehr auf die in der Liste gespeicherten Werte zugreifen! struct dtelement *anfang; dyn. Array = anfuegen(NULL, 9); anfang = dyn. Array; dyn. Array = anfuegen(dyn. Array, 5); dyn. Array = anfuegen(dyn. Array, 13); return 0; } 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 print. List(struct dtelement *dyn. Array) Beschreibung: gibt ein dynamisches Array (verkettete Liste) auf dem Bildschirm aus.
void del. List (struct dtelement *dyn. Array) Beschreibung: löscht das ganze dynamische Array (verkettete Liste). void del. Element (struct dtelement *element) Beschreibung: löscht ein Element des dynamischen Arrays (verkettete Liste).
Bemerkungen zur Funktion: void del. Element (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. Reicht es aus, diesen Speicherbereich mit free freizugeben ? Also. . . 0050 10 0060 0070 30 0080 0090 20 0100 NULL
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 0060 0070 0090 20 0100 NULL
Was muss also noch gemacht werden? 0050 10 0060 0070 30 0080 0090 20 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 0060 0070 30 0080 0090 20 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 0060 10 0070 30 0080 0090 20 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 0060 0090 0070 30 0080 0090 20 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 0060 0090 20 0100 NULL
Wie kann die Adresse des Vorgängers ermittelt werden? 0050 10 0060 0090 20 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 0060 0090 20 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.
- Java doppelt verkettete liste
- Objekts
- Ein volk ein reich ein führer
- Mikrofon und lautsprecher physik
- Dynamisches periodensystem
- Partizip als attribut beispiel
- Ein hund ist ein herz auf vier pfoten
- Ist ein drache ein trapez
- Ein neuer tag und ein neuer morgen
- Slidetodoc.com
- Männer herbert grönemeyer analyse
- Serisen
- Heidenröslein analyse
- Ein tag der sagts dem anderen mein leben sei ein wandern
- Stromkreismodelle
- Ein neuer tag und ein neuer morgen
- Bildungsplan deutsch
- Sozialleistungen
- Software personalentwicklung freeware
- Der zusammenhang zwischen fotosynthese und zellatmung
- Entscheidungsmatrix
- Johann friedrich reichardt kompositionen
- Vergleich ameisenstaat bienenstaat
- Religionsgeschichtlicher vergleich
- Rosinenkuchenmodell
- Wie macht man ein schaubild
- Vergleich körperbau neandertaler mensch
- Bibel und koran im vergleich
- Verkehrsträgervergleich
- Learning management systeme im vergleich
- Jagged array vs multidimensional array
- Sparse array adalah array yang
- Associative array vs indexed array
- Perbedaan array 1 dimensi dengan array 2 dimensi
- Pga vs lga
- Endfire array
- Photovoltaic array maximum power point tracking array
- Array dimensi 3
- Array of array in c
- Les organisateurs textuels
- Schulnoten tabelle
- Principes moraux exemples
- Länderembargo liste
- Schindlers liste inhaltsangabe
- Denk pharma wikipedia
- Gode indledninger
- Kümelerde liste yöntemi
- Lexique rapport de stage
- Simplification des racines carrées
- Les courses difficiles du jour
- Liste calibre disjoncteur
- Exemple de liste
- Check liste formation prof
- Verbe 2 groupe
- Never events liste
- Zweisilber liste
- On considère
- Le complément de nom
- Liste de matériel
- Verbe intransitif
- Jak zrobic liste plac gratyfikant
- Aktive medizinprodukte liste zahnarztpraxis
- Na vedomie v liste
- Vba control tip text
- Liste des figures rapport de stage
- Never events liste
- Groupe lvmh entreprises
- Schreibanlass leserbrief
- Cosa sono le liste rosse
- Sestrinska lista
- Vde 0100-700
- Liste dissyllabique de lafon
- Ald demande
- Dm
- Sterke baser liste
- College asselin de beauville
- Macrocibles
- Lista numerica html
- Racine carre de 36
- Rutin olmayan problemler örnekleri ilkokul
- Grundbaustoffe der nahrung
- Esercizi liste concatenate c
- Liste a la.prevert
- Verb infinitive past simple past participle