Diskrete Mathe1 12345678910111213141516171819 Diskrete Mathematik I Listen Vorlesung 4.

Post on 06-Apr-2016

240 Views

Category:

Documents

4 Downloads

Preview:

Click to see full reader

Transcript

Diskrete Mathe11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

Diskrete Mathematik I

Listen

Vorlesung 4

Diskrete Mathe11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

• letzte Stunde:rekursive Definitionen und Methoden

• heute:rekursive Datenstrukuren: Listen

Rekursion

1

Diskrete Mathe11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 192

• Listen – ... als rekursive Struktur– ... als dynamische Datenstrukturen

• Die Klasse Element– ... mit Element-konstruktor

• Eine richtige kleine Liste• Ein UML-Diagramm für „Element“• Aber wie kommt man nun zu einer Liste?• Anfügen von Elementen - Beispiel

Übersicht I

Diskrete Mathe11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 193

• Einfügen am Anfang einer Liste– Problem– Beispiel– Problem der bisherigen Lösung

• Die Klasse „Liste“ (UML-Diagramm)• Die Klasse Element (vollständig)• Die Klasse „Liste“

Übersicht II

Diskrete Mathe11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 194

• Die leere Liste Null ist eine Liste. • Wenn E ein Element ist und L eine Liste, dann ist

E · L eine Liste.• Beispiele:

– die leere Liste { }– {1}– {1,3,2,5}

• Graphik für die leere Liste:

Listen als rekursive Struktur

Diskrete Mathe11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 195

• flexible Datenstruktur ohne vorherige Festlegung auf die Größe

• Vorteile gegenüber Arrays– beliebige Größenänderungen– effiziente Umordnung der Elemente

• Nachteil gegenüber Arrays– kein direkter Zugriff auf einzelne Elemente

Listen als Dynamische Datenstrukturen

Diskrete Mathe11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 196

class Element{ int wert; Element weiter;}

Die Klasse Element

5

Element

Zeiger auf ein Element

int

A 4x

Diskrete Mathe11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 197

... mit Element-konstruktor

Das ist neu

• Die Methode Element(int i) ist ein Konstruktor, der bei der Erzeugung eines Elements mit new Element(i) automatisch aufgerufen wird.

class Element { Element(int i) { wert = i; weiter = null;}

int wert; Element weiter;

}

Diskrete Mathe11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 198

A 7x

Eine richtige kleine Liste

5

Die leere Liste

3 7

Der Kopf der Liste

Der Rest der Liste

Diskrete Mathe11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

Beachte:• „weiter“ ist kein Attribut, sondern eine Beziehung• eine (UML-) Beziehung wird (in Java) als Attribut einer zugehörigen Klasse

implementiert• eine UML-Beziehung kann auch rekursiv sein

9

A 13x

Ein UML-Diagramm für „Element“

weiter

0..1

Beziehung Konstruktor

Ein oderkein Nachfolger

0..1

Element

+Element(i : int)

-wert : int

Diskrete Mathe11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 1910

• Wir haben:– die Klasse Element

• Eine Liste entsteht durch Erzeugung und Verkettung von Objekten vom Typ Element– Erzeugen des ersten Elements

• mit dem Konstruktor „Element“– Anfügen eines Elements

• zusätzliche Prozedur

Aber wie kommt man nun zu einer Liste?

Diskrete Mathe11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 1911

void FügeAn(int neuerWert){ Element lauf = this; while (lauf.weiter != null) lauf = lauf.weiter; lauf.weiter = new Element(neuerWert);}

Anfügen von Elementen

Sucht das letzte Element

Zeiger auf das aufrufende Objekt

fügt neues Element an

A 10x

Diskrete Mathe11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 1912

KopfElement kopf;

class Element{ Element(int i) { wert = i; weiter = null; } int wert; Element weiter;}

A 25x

Diskrete Mathe11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 1912

Element kopf;kopf = new Element(25);

class Element{ Element(int i) { wert = i; weiter = null; } int wert; Element weiter;}

Kopf

12

A 25x

Diskrete Mathe11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 1912

Element kopf;kopf = new Element(25);

class Element{ Element(int i) { wert = i; weiter = null; } int wert; Element weiter;}

25

Kopf

12

A 25x

Diskrete Mathe11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 1912

Element kopf;kopf = new Element(25);kopf.FügeAn(22);

void FügeAn(int neuerWert){ Element lauf = this; while (lauf.weiter != null) lauf = lauf.weiter; lauf.weiter = new Element(neuerWert);}

25

Kopf

12

A 25x

Diskrete Mathe11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 1912

Element kopf;kopf = new Element(25);kopf.FügeAn(22);

void FügeAn(int neuerWert){ Element lauf = this; while (lauf.weiter != null) lauf = lauf.weiter; lauf.weiter = new Element(neuerWert);}

lauf25

Kopf

12

A 25x

Diskrete Mathe11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 1912

Element kopf;kopf = new Element(25);kopf.FügeAn(22);

void FügeAn(int neuerWert){ Element lauf = this; while (lauf.weiter != null) lauf = lauf.weiter; lauf.weiter = new Element(neuerWert);}

Kopf

25 22

12

A 25x

Diskrete Mathe11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 1912

Element kopf;kopf = new Element(25);kopf.FügeAn(22);

void FügeAn(int neuerWert){ Element lauf = this; while (lauf.weiter != null) lauf = lauf.weiter; lauf.weiter = new Element(neuerWert);}

Kopf

25

22

12

A 25x

Diskrete Mathe11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 1912

void FügeAn(int neuerWert){ Element lauf = this; while (lauf.weiter != null) lauf = lauf.weiter; lauf.weiter = new Element(neuerWert);}

Kopf

22

25

Element kopf;kopf = new Element(25);kopf.FügeAn(22);kopf.FügeAn(28);

12

A 25x

Diskrete Mathe11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

Element kopf;kopf = new Element(25);kopf.FügeAn(22);kopf.FügeAn(28);

void FügeAn(int neuerWert){ Element lauf = this; while (lauf.weiter != null) lauf = lauf.weiter; lauf.weiter = new Element(neuerWert);}

Kopf

22

25 lauf

1212

A 25x

Diskrete Mathe11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

Element kopf;kopf = new Element(25);kopf.FügeAn(22);kopf.FügeAn(28);

void FügeAn(int neuerWert){ Element lauf = this; while (lauf.weiter != null) lauf = lauf.weiter; lauf.weiter = new Element(neuerWert);}

Kopf

25

lauf

22

1212

A 25x

Diskrete Mathe11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 1912

Element kopf;kopf = new Element(25);kopf.FügeAn(22);kopf.FügeAn(28);

void FügeAn(int neuerWert){ Element lauf = this; while (lauf.weiter != null) lauf = lauf.weiter; lauf.weiter = new Element(neuerWert);}

Kopf

25

lauf

22

1212

A 25x

Diskrete Mathe11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

Element kopf;kopf = new Element(25);kopf.FügeAn(22);kopf.FügeAn(28);

void FügeAn(int neuerWert){ Element lauf = this; while (lauf.weiter != null) lauf = lauf.weiter; lauf.weiter = new Element(neuerWert);}

Kopf

25

22

28

lauf

1212

A 25x

Diskrete Mathe11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

Element kopf;kopf = new Element(25);kopf.FügeAn(22);kopf.FügeAn(28);

void FügeAn(int neuerWert){ Element lauf = this; while (lauf.weiter != null) lauf = lauf.weiter; lauf.weiter = new Element(neuerWert);}

Kopf

25

22

28

1212

A 25x

Diskrete Mathe11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 1912

Element kopf;kopf = new Element(25);kopf.FügeAn(22);kopf.FügeAn(28);

void FügeAn(int neuerWert){ Element lauf = this; while (lauf.weiter != null) lauf = lauf.weiter; lauf.weiter = new Element(neuerWert);}

Kopf

25

22

28

1212

A 25x

Diskrete Mathe11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

• Problem: es gibt bislang nur die Klasse Element• die Operation Einfügen muß vom ersten Element aufgerufen

werden• Umsetzung der Referenz „kopf“ erforderlich• das Kopf-Element hat aber keinen Zugriff auf die Referenz „kopf“• Lösung: Umkopieren von Wert

13

A 8x

Problem: Einfügen am Anfang einer Liste

15 22 28

15 22 2817

kopf

kopf

Diskrete Mathe11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 1914

void FügeEin(int neuerWert){ Element neuesElement = new Element(wert); neuesElement.weiter = weiter; weiter = neuesElement; wert = neuerWert;}

Einfügen am Anfang einer Liste

Diskrete Mathe11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

void FügeEin(int neuerWert){ Element neuesElement = newElement(wert); neuesElement.weiter = weiter; weiter = neuesElement; wert = neuerWert;}

Einfügen am Anfang einer Liste

16

Kopf 25 22 28

kopf.FügeEin(17)

A 9x

1515

Diskrete Mathe11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 1915

void FügeEin(int neuerWert){ Element neuesElement = newElement(wert); neuesElement.weiter = weiter; weiter = neuesElement; wert = neuerWert;}

Einfügen am Anfang einer Liste

16

Kopf 25 22 28

neuesElement 25

15

A 9x

Diskrete Mathe11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 1915

void FügeEin(int neuerWert){ Element neuesElement = newElement(wert); neuesElement.weiter = weiter; weiter = neuesElement; wert = neuerWert;}

Einfügen am Anfang einer Liste

16

neuesElement 25

Kopf 25 22 28

15

A 9x

Diskrete Mathe11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 1915

void FügeEin(int neuerWert){ Element neuesElement = newElement(wert); neuesElement.weiter = weiter; weiter = neuesElement; wert = neuerWert;}

Einfügen am Anfang einer Liste

16

Kopf 25 22 28

25

15

A 9x

Diskrete Mathe11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 1915

void FügeEin(int neuerWert){ Element neuesElement = newElement(wert); neuesElement.weiter = weiter; weiter = neuesElement; wert = neuerWert;}

Einfügen am Anfang einer Liste

16

25 22 28Kopf

25

15

A 9x

Diskrete Mathe11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 1915

void FügeEin(int neuerWert){ Element neuesElement = newElement(wert); neuesElement.weiter = weiter; weiter = neuesElement; wert = neuerWert;}

Einfügen am Anfang einer Liste

16

25 22 28Kopf 25

15

A 9x

Diskrete Mathe11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 1915

void FügeEin(int neuerWert){ Element neuesElement = newElement(wert); neuesElement.weiter = weiter; weiter = neuesElement; wert = neuerWert;}

Einfügen am Anfang einer Liste

16

17 22 28Kopf 25

15

A 9x

Diskrete Mathe11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 1915

void FügeEin(int neuerWert){ Element neuesElement = newElement(wert); neuesElement.weiter = weiter; weiter = neuesElement; wert = neuerWert;}

Einfügen am Anfang einer Liste

16

17 22 28Kopf 25

15

A 9x

Diskrete Mathe11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 1916

• Einfügen am Anfang mehr als umständlich• Einfügen am Ende ineffizient, insbesondere wenn die Liste sehr lang ist• wo liegt das Problem?• bisheriges Modell

– wir haben zwar eine Klasse Element– aber keine Klasse Liste

• Lösung: Definition einer Klasse Liste– Verweis auf das erste Element– Verweis auf das letzte Element

Problem der bisherigen Lösung

Diskrete Mathe11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 1917

A 8x

Die Klasse „Liste“

Liste0..1kopf

0..1fuß

0..1

0..1Element

+Element(i : int)-wert : int

weiter

0..1

0..1

Diskrete Mathe11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 1918

class Element {private int wert; private Element weiter; Element(int i) { wert = i; weiter = null; }Element(int i, Element e) { wert = i; weiter = e; }void SetzeWert(int i) { wert = i; }int GibWert() { return wert; }void SetzeWeiter(Element e) { weiter = e; }Element GibWeiter() { return weiter; }

}

Beachte: • der Konstruktor Element kann sowohl ein- als auch zweistellig

aufgerufen werden („Überladung“)

Die Klasse Element (vollständig)

neu

Diskrete Mathe11 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 1919

class Liste {Liste() { kopf = fuß = null; }Liste(int w) { kopf = fuß = new Element(w); }private Element kopf, fuß;void FügeAn(int an) {

Element neu = new Element(an);if (fuß != null) {

fuß.SetzeWeiter(neu);fuß = neu;

}else

kopf = fuß = neu;}void FügeEin(int ein) {

kopf = new Element(ein, kopf);if (fuß == null)

fuß = kopf;}

}

beachte die Fallunterscheidung der leeren Liste!

Die Klasse „Liste“

leere Liste

leere Liste

top related