Dynamische Datenstrukturen in Pascal Flashcards
Unterschied zwischen statischen und dynamischen Datenstrukturen
Speicheplatzbedarf steht bei statischen Datenstrukturen schon bei der Übersetzung fest.
Bei dynamischen Datenstrukturen wird Speicherplatz erst während der Laufzeit (Standardprozedur new()) angelegt bzw. (Standardprozedur deipose()) wieder freigegeben.
Standad-Verbundobjekt als Listenelement
record
info : type;
next : tRefListe;
end;
Nachteile Linearer Listen gegenüber Feldern
- Liste kann nur entlang der Verzeigerung durchlaufen werden
- Suchen und “Anwählen” eines Objektes sowie damit jede darauf zurückgrufende Funktion (Löschen eines bestimmten Elements etc.)
=> einfach aber zeitaufwändig
Unterschied zwischen Zeigervariable und Variable
- Zeigervariable enthält Verweis (Speicheradresse) des zugehörigen Objekts
- Variable enthält Wert des Objekts direkt
Dereferenzierung
Zugriff auf ein Objekt über Zeigervariable
Wie wird ein Zeigertyp definiert?
tRefTyp = ^tTyp;
tTyp ist beliebiger Datentyp; Wertemenge für tReftyp sind alle Verweise auf Objekte vom Typ tTyp.
Beispiel: tRefListe = ^tListe; tListe = record info : integer; next : tRefListe; end;
Wie wird ein Objekt durch eine Zeigervariable angesprochen?
var
Zeig : tRefTyp;
[…]
Zeig^;
Wie wird eine Info-Komponente eines Objekts durch eine Zeigervariable ausgelesen?
var
Zeig : tRefTyp;
[…]
Zeig^.info;
Was macht dieser Befehl?
Zeig1 := Zeig2
Zeig1 verweist anschließend auf das gleiche Objekt wie Zeig2.
Was macht dieser Befehl?
Zeig1^ := Zeig2^
Das Objekt, auf das Zeig1 verweist, hat anschließend den gleichen Wert wie jenes, auf das Zeig2 verweist. Die Zeiger zeigen immernoch auf zwei verschiedene Objekte.
Was macht die Standardprozedur new ?
new(Zeig) legt ein neues Objekt vom Wertetyp von Zeig an und weist Zeig die Referenz auf dieses Objegt zu. Der Wert von Zeig^ ist bis zur initialisierung undefiniert.
Wie wird ein “Zeigerobjekt” initialisiert?
Normale Zuweisung:
Zeig^ := WERT;
Was macht die Standardprozedur dispose ?
dispose(Zeig) löscht das Detenobjekt, auf das Zeig verweist. Zeig^ ist anschließend undefiniert, ebenso wie alle anderen Zeigervariablen, die auf Zeig^ verwiesen haben.
Wann ist Zeig1 = Zeig2 true?
Wenn Zeig1 und Zeig2 auf das gleiche Datenobjekt verweisen.
Wann ist Zeig1^ = Zeig2^ true?
Wenn die Datenobjekte, auf die die Zeigervariablen verweisen, den gleichen Wert haben, unabhängig davon, ob sie auf das gleiche oder zwei verschiedene Objekte zeigen.
Was ist der Vorteil einer Linearen Liste gegenüber einem Feld?
Da der Speicherplatz dynamisch zugewiesen wird, wird kein solcher verschwendet.
Welche Schritte sind zur Initialisierung einer Liste zu ergreifen?
- Definition Zeigertyp (type)
- Definition Listenelementtyp (gleich unter Zeigertyp)
- Deklaration Anker (var)
- Initialisierung im Programmrumpf (:= nil)
Wie funktionieren Lineare Listen?
- Anfangszeiger zeigt auf erstes Objekt
- Objekt besteht aus Wert-Komponente und
- Verweis auf zweites Objekt
- usw.
- letztes Objekt verweist auf nil
Code: Listenelement am Listenanfang einfügen
Zeiger^.next := RefAnfang;
RefAnfang := Zeiger;
Code: Referenz auf Wert in Liste suchen
if Zeiger <> nil then { Liste nicht leer } begin while (Zeiger^.next <> nil) and (Zeiger^.info <> Wert) do Zeiger := Zeiger^.next; if Zeiger^.info <> Wert then { Listenende } Zeiger := nil; Ausgabe := Zeiger;
Typisches Vorgehen bei der Bearbeitung von Linearen Listen
- Sonderfälle abdecken:
- leere Liste
- Operation am Listenanfang
- Normalfall
- evtl. Sonderfall: Operation am Listenende
Algorithmus: sortiert in Liste einfügen
if RefAnfang = nil { Liste leer } Listenelement am Anfang einfügen else if RefAnfang^.info > Neuer Wert { Operation am Listenanfang } Listenelement am Anfang einfügen else { Position suchen } gefunden := false; Hilfszeiger := RefAnfang; Referenz auf Wert in Liste suchen; modifiziert durch Vergleich; gefunden true setzen if gefunden then Listenelement in der Mitte einfügen else Listenelement am Ende anhängen