1 / 40

Diskrete Mathematik I

Diskrete Mathematik I. Vorlesung 5 11.11.99 -Listen-. Rekursion. letzte Stunde: rekursive Definitionen und Methoden heute: rekursive Datenstrukuren: Listen. Übersicht. Listen ... als rekursive Struktur ... als dynamische Datenstrukturen Die Klasse Element

ninon
Download Presentation

Diskrete Mathematik I

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Diskrete Mathematik I Vorlesung 5 11.11.99 -Listen-

  2. Rekursion • letzte Stunde: rekursive Definitionen und Methoden • heute: rekursive Datenstrukuren: Listen

  3. Übersicht • 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

  4. Übersicht (Fortsetzung) • 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“

  5. Listen als rekursive Struktur • Die leere Liste Null ist eine Liste. • Wenn E ein Element ist und L eine Liste, dann istE L eine Liste. • Beispiele: • die leere Liste { } • {1} • {1,3,2,5} • Graphik für die leere Liste:

  6. Listen als Dynamische Datenstrukturen • flexible Datenstruktur ohne vorherige Festlegungauf 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

  7. 5 Die Klasse Element classElement { int wert; Element weiter; } Element int Zeiger auf ein Element

  8. ... mit Element-konstruktor classElement { Element(int i) { wert = i; weiter = null;} int wert; Element weiter;} Das ist neu • Die ProzedurElement(int i)ist ein Konstruktor, der bei der Erzeugung eines Elements mit new Element(i) automatisch aufgerufen wird.

  9. 5 3 7 Der Rest der Liste Eine richtige kleine Liste DerKopf der Liste Die leereListe

  10. Ein UML-Diagramm für „Element“ Element Ein oderkein Nachfolger 0..1 -wert : int Beziehung Konstruktor weiter +Element(i : int) 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 0..1

  11. Aber wie kommt man nun zu einer Liste? • 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 Elemente • zusätzliche Prozedur

  12. Anfügen von Elementen Sucht das letzte Element void FügeAn(int neuerWert) { Element lauf = this; while (lauf.weiter != null) lauf = lauf.weiter; lauf.weiter = new Element(neuerWert); } Zeiger auf dasaufrufende Objekt fügt neues Element an

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

  14. kopf Element kopf; kopf = new Element(25); class Element { Element(int i) { wert = i; weiter = null; } int wert; Element weiter; }

  15. kopf Element kopf; kopf = new Element(25); 25 class Element { Element(int i) { wert = i; weiter = null; } int wert; Element weiter; }

  16. 25 kopf 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); }

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

  18. 25 22 kopf 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); }

  19. 25 22 kopf 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); }

  20. 25 22 kopf 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); }

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

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

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

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

  25. 25 28 22 kopf 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); }

  26. 25 28 22 kopf 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); }

  27. 15 22 28 15 22 28 17 Problem: Einfügen am Anfang einer Liste • 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 kopf kopf

  28. Einfügen am Anfang einer Liste void FügeEin(intneuerWert) { Element neuesElement = new Element(wert); neuesElement.weiter = weiter; weiter = neuesElement; wert = neuerWert; }

  29. 25 22 28 Einfügen am Anfang einer Liste kopf kopf.FügeEin(17) void FügeEin(int neuerWert) { Element neuesElement = newElement(wert); neuesElement.weiter = weiter; weiter = neuesElement; wert = neuerWert; }

  30. 25 22 28 25 Einfügen am Anfang einer Liste kopf neuesElement void FügeEin(int neuerWert) { Element neuesElement = newElement(wert); neuesElement.weiter = weiter; weiter = neuesElement; wert = neuerWert; }

  31. 25 22 28 25 Einfügen am Anfang einer Liste kopf neuesElement void FügeEin(int neuerWert) { Element neuesElement = newElement(wert); neuesElement.weiter = weiter; weiter = neuesElement; wert = neuerWert; }

  32. 25 22 28 25 Einfügen am Anfang einer Liste kopf void FügeEin(int neuerWert) { Element neuesElement = newElement(wert); neuesElement.weiter = weiter; weiter = neuesElement; wert = neuerWert; }

  33. 25 22 28 25 Einfügen am Anfang einer Liste kopf void FügeEin(int neuerWert) { Element neuesElement = newElement(wert); neuesElement.weiter = weiter; weiter = neuesElement; wert = neuerWert; }

  34. 25 22 28 25 Einfügen am Anfang einer Liste kopf void FügeEin(int neuerWert) { Element neuesElement = newElement(wert); neuesElement.weiter = weiter; weiter = neuesElement; wert = neuerWert; }

  35. 17 22 28 25 Einfügen am Anfang einer Liste kopf void FügeEin(int neuerWert) { Element neuesElement = newElement(wert); neuesElement.weiter = weiter; weiter = neuesElement; wert = neuerWert; }

  36. 17 22 28 25 Einfügen am Anfang einer Liste kopf void FügeEin(int neuerWert) { Element neuesElement = newElement(wert); neuesElement.weiter = weiter; weiter = neuesElement; wert = neuerWert; }

  37. Problem der bisherigen Lösung • 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

  38. kopf Liste Element 0..1 -wert : int weiter +Element(i : int) fuß 0..1 Die Klasse „Liste“ 0..1 0..1 0..1 0..1

  39. Die Klasse Element (vollständig) 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 weden („Überladung“) neu

  40. Die Klasse „Liste“ 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! leere Liste leere Liste

More Related