Luisengymnasium

Dynamische Datenstrukturen und Queue

Lernziele

Nach diesem Kapitel kannst du:

  • die Zugriffsregel einer Warteschlange von ihrer technischen Umsetzung unterscheiden,
  • die Grundidee verketteter Knoten (content + next) beschreiben,
  • die vier Queue-Methoden (enqueue, dequeue, front, isEmpty) anwenden und die Ausgabe vorhersagen,
  • ein Objektdiagramm einer Queue mit head, tail und next zeichnen,
  • für eine konkrete Operation Vorteile und Grenzen von Array und Verkettung begründen.

Leitfrage: Wie organisierst du eine wachsende Warteschlange, die immer den ältesten Auftrag zuerst bearbeitet?

Dein Lernweg

A1 und A2 sowie der Kompetenzcheck sind der gemeinsame Kern. A3 nutzt du bei Unsicherheit zum leeren Zustand. Wähle danach den Shop-Transfer oder einen eigenen FIFO-Kontext mit denselben Anforderungen; A4/A5 sind zusätzliche Vertiefung.

Mermaid-Diagramm
Mermaid-Diagramm wird geladen…

Arbeitsweise: Abruffragen und Kompetenzchecks beantwortest du zuerst allein ohne Unterlagen und KI. Speichere deine eigene Antwort, bevor du die Rückmeldung öffnest. Im Übungsteil darfst du Hilfen nutzen; nenne anschließend, welche Hilfe du gebraucht hast. Bei jedem Programm: erst erwartete Ausgabe und einen Leerfall notieren, dann ausführen und vergleichen.

Voraussetzungen

Hinweis

Du solltest Referenzen, null, Aliasing und Arrays von Referenzen aus Kurs Lineare Datenstrukturen 1: Referenzen und Speichermodell sicher beherrschen. Besonders wichtig: Eine Referenz ist ein Pfeil auf ein Objekt. null bedeutet „zeigt auf nichts".

Übergang: Von festen Plätzen zu beweglichen Knoten

Arrays geben uns viele Plätze auf einmal. Das ist nützlich, solange die Größe ungefähr feststeht.

Bei Warteschlangen, Bestellungen oder Patientenlisten ist die Anzahl aber ständig in Bewegung. Neue Elemente kommen dazu, alte verschwinden. Wenn man dafür immer verschieben oder umkopieren muss, wird das Array unbequem.

Die neue Idee lautet: Elemente liegen nicht mehr auf festen Plätzen nebeneinander. Sie kennen ihren Nachfolger.


Phase 1: Einstieg — Aufträge in Ankunftsreihenfolge

Hinweis

Retrieval-Check:

  1. Was passiert bei einem vollen Array, wenn du ein neues Element einfügen willst?
  2. Was ist eine Referenz — und was ist null?
Textabgabe

Abgabe bis: 2027-07-31T23:59:00+02:00

Die Warteschlange wächst

An einem Schulfest kommen Druckaufträge A, B und C an. Nach dem Drucken von A kommt D hinzu. Alle sollen in Ankunftsreihenfolge bedient werden.

Exploration – 4 Minuten allein, ohne KI: Zeichne zwei Zustände. Wie könntest du die Aufträge in einem Array verwalten? Was passiert mit freien Plätzen nach dem Drucken? Was tust du, wenn alle Plätze belegt sind? Notiere einen eigenen Vorschlag, bevor du die Auswertung öffnest.


Phase 2: Konzeptaufbau — Verkettung statt feste Plätze

Abruf 2 – ohne Nachlesen: Welche Reihenfolge muss die Druckerwarteschlange nach A entfernen und D anfügen haben? Was ändert sich an einer Referenz beim Umlenken?

Textabgabe

Abgabe bis: 2027-07-31T23:59:00+02:00

Beim folgenden Beispiel ohne KI: Sage das Ergebnis vorher. Erkläre anschließend einer anderen Person, welche Zeile die Datenstruktur verändert. Erst dann ausführen.

2.1 Was ist eine dynamische Datenstruktur?

Hinweis

Grundidee: Bei einer dynamischen Datensammlung kann sich die Anzahl der Elemente zur Laufzeit ändern. Eine mögliche Umsetzung sind verkettete Knoten. Auch arraybasierte Sammlungen können wachsen, indem sie bei Bedarf ein größeres Array verwenden.

Queue und Stack beschreiben vor allem erlaubte Zugriffe. Die hier verwendeten NRW-Klassen setzen diese Regeln durch Verkettung um. Zugriffsregel und Implementierung sind zwei verschiedene Ebenen.

2.2 Verkettete Knoten — der Grundbaustein

Jeder Knoten (Node) enthält zwei Dinge:

  • content — eine Referenz auf das eigentliche Datenobjekt (z.B. einen Patienten)
  • next — eine Referenz auf den nächsten Knoten (oder null, wenn es der letzte ist)
Mermaid-Diagramm
Mermaid-Diagramm wird geladen…
Hinweis

Verkettung: Die Knoten sind über Referenzen verbunden. An einer bereits bekannten Stelle genügen wenige Referenzänderungen. Eine beliebige Stelle erst zu suchen kann dagegen einen Durchlauf verlangen. Jeder Knoten benötigt zusätzlichen Speicher.

2.3 Die Queue — Warteschlange nach dem FIFO-Prinzip

Eine Queue arbeitet nach dem FIFO-Prinzip (First In, First Out): Wer zuerst eingefügt wird, wird zuerst entnommen. Wie eine Warteschlange beim Arzt.

Die verkettete NRW-Queue hat zwei Referenzen:

  • head — zeigt auf den ersten Knoten (vorne, wird als nächstes entnommen)
  • tail — zeigt auf den letzten Knoten (hinten, dort wird eingefügt)

2.4 Die vier Queue-Methoden

MethodeVerändert die Queue?Bedeutung
enqueue(x)jafügt x hinten ein
dequeue()jaentfernt das vorderste Element
front()neinliefert das vorderste Element oder null
isEmpty()neinprüft, ob die Queue leer ist
Tipp

front() schaut nur nach vorne — das Element bleibt in der Queue. Erst dequeue() nimmt es heraus.

Sage vorher, dann teste:

Vorhersage: Wer wird zuerst behandelt?

IDE lädt…

Reflexionsfrage: Warum gibt front() auf einer leeren Queue null zurück statt abzustürzen? Was ist der Vorteil für den Programmierer?

Objektdiagramm: Queue mit 3 Elementen

Nach enqueue(Ada), enqueue(Ben), enqueue(Cem):

Mermaid-Diagramm
Mermaid-Diagramm wird geladen…
Hinweis

Zähle: 7 Objekte (1 Queue + 3 Nodes + 3 Patienten). Die Nodes sind die „Infrastruktur" — die Patienten sind die eigentlichen Daten.

Ruhige Sicherung: Was die Queue einfacher macht

Tipp

Die Queue nimmt dir eine Entscheidung ab: Du musst nicht überlegen, wo eingefügt oder entfernt wird.

  • Neues Element: immer hinten.
  • Nächstes Element: immer vorne.
  • Reihenfolge: First In, First Out.

Diese Einschränkung ist keine Schwäche, sondern die Stärke der Queue. Sie macht Warteschlangen berechenbar.

Code-Patterns

Queue-Pattern
// Sicher ein Element entnehmen
if (!q.isEmpty())
{
    Typ element = q.front();  // Ansehen
    q.dequeue();              // Entfernen
    // element weiterverarbeiten
}

Zwei Mini-Checks vor der Übung

1. Eine Queue enthält A,B. Was steht nach zweimal front() vorne?

2. Beim letzten dequeue: Wohin zeigen head und tail danach?

Fading – Hilfen nach Bedarf

Wähle Parsons oder Completion. Schreibe vor dem Ausführen: „Die Ausgabe ist Ada; danach steht Ben vorne.“ Beim Modify-Auftrag muss dieselbe Reihenfolge erhalten bleiben.


Hilfen zu den Queue-Aufgaben

Phase 3: Üben

Hinweis

Retrieval-Check:

  1. Was gibt front() auf einer leeren Queue zurück?
  2. Was passiert bei flotte[0].setGroesse(100) nach new Raumschiff[3]? (Rückbezug Kurs Lineare Datenstrukturen 1: Referenzen und Speichermodell)
Textabgabe

Abgabe bis: 2027-07-31T23:59:00+02:00

Abgabe-Aufgaben

A1: Trace — Queue-Operationen (Pflicht)

Sage die Ausgabe des folgenden Codes vorher:

Queue<String> q = new Queue<String>();
q.enqueue("X");
q.enqueue("Y");
q.enqueue("Z");
System.out.println(q.front());   // ?
q.dequeue();
System.out.println(q.front());   // ?
q.enqueue("W");
q.dequeue();
System.out.println(q.front());   // ?
System.out.println(q.isEmpty()); // ?
Textabgabe

Abgabe bis: 2027-07-31T23:59:00+02:00

A2: Objektdiagramm (Pflicht)

Zeichne das Objektdiagramm der Queue nach folgenden Operationen:

  1. enqueue(new Patient("Ada"))
  2. enqueue(new Patient("Ben"))
  3. enqueue(new Patient("Cem"))
  4. dequeue()

Zeige: Queue-Objekt (head, tail), alle Nodes (next), alle Patienten (content). Wie viele Queue-, Knoten- und Patient-Objekte sind danach von der Queue aus erreichbar? Ignoriere String-Objekte und nimm an, dass es keine weiteren Referenzen auf die Patienten gibt. Erkläre, was mit Adas Patient-Objekt geschehen kann.

Textabgabe

Abgabe bis: 2027-07-31T23:59:00+02:00

A3: Debugging — isEmpty-Check fehlt (Förderübung, AFB II)

Der folgende Code stürzt ab. Finde den Fehler und behebe ihn.

Queue<Patient> q = new Queue<Patient>();
q.enqueue(new Patient("Ada"));
q.dequeue();
 
// Nächsten Patienten anzeigen
System.out.println(q.front().getName());
Textabgabe

Abgabe bis: 2027-07-31T23:59:00+02:00

A4: Analyse — Queue vs. Array (Vertiefung)

Vergleiche zwei Umsetzungen derselben FIFO-Warteschlange:

  • Array: Nach jeder Entnahme wird der gesamte Rest nach vorn verschoben.
  • Verkettete Queue mit head und tail.

Welche Arbeit fällt bei einer Entnahme an? Warum beweist das nicht, dass jede Queue-Umsetzung schneller als jedes Array ist? Welchen Vorteil hat ein Array beim Zugriff auf Position 100?

Textabgabe

Abgabe bis: 2027-07-31T23:59:00+02:00

A5: Design — Druckerwarteschlange (Vertiefung)

Entwirf ein Klassendiagramm für eine Druckerwarteschlange:

  • Klasse Druckauftrag mit Attributen (Dateiname, Seitenanzahl)
  • Klasse Drucker mit einer Queue<Druckauftrag>
  • Methoden: auftragHinzufuegen(...), naechstenDrucken()

Warum gehört die Queue-Logik in die Klasse Drucker und nicht in Druckauftrag?

Textabgabe

Abgabe bis: 2027-07-31T23:59:00+02:00


Kompetenzcheck – allein, 8–10 Minuten (Pflicht)

Beantworte die drei Aufgaben ohne Vorlage, Ausführen oder KI. Speichere deine erste Antwort vor dem Vergleich. Eine Partnerlösung ersetzt deine Antwort nicht.

  1. Eine leere Queue erhält A und B. Danach folgen dequeue() und enqueue(C). Nenne front() und die gesamte Entnahmereihenfolge.
  2. Zeichne für diesen Zustand die Queue, ihre Knoten und Inhalte mit head, tail, next und content. Erkläre, warum front() allein kein Element entfernt.
  3. Nach vollständiger Entnahme: Was liefern front() und isEmpty()? Was tut dequeue()? Warum wäre front().toString() gefährlich?
Textabgabe

Abgabe bis: 2027-07-31T23:59:00+02:00

Neuer Versuch nach gezielter Übung

Neue leere Queue: enqueue(P), enqueue(Q), dequeue(), enqueue(R), dequeue(). Zeichne den Endzustand und erkläre das anschließende Leeren.

Textabgabe

Abgabe bis: 2027-07-31T23:59:00+02:00

Phase 4: Transfer und Vernetzung

Transferaufgabe

Durchgaengiges Projekt: Online-Shop

Der Online-Shop dient als gemeinsamer Beispielkontext. Du entwickelst hier einen ersten Baustein; später darfst du für dein eigenes Projekt einen anderen Kontext wählen. Die Queue verwaltet hier die Bestellwarteschlange -- Bestellungen werden in der Reihenfolge bearbeitet, in der sie eingehen.

Projektstand Online-Shop

Das Lager aus dem ersten Kurs hatte feste Plätze. Jetzt bekommt der Shop eine Bestellwarteschlange: Bestellungen kommen hinten dazu und werden vorne bearbeitet.

Neue Bestellungen benötigen keine vorher festgelegten Arrayplätze. Über die Queue-API sieht man immer nur die nächste Bestellung.

Online-Shop: Bestellwarteschlange

Transfer (AFB II): Skizziere zuerst 4 Minuten ohne KI Klassen und Beziehungen. Nutze dann das Gerüst oder übertrage dieselben Anforderungen auf deinen eigenen FIFO-Kontext. Bei eigener Idee ersetzt du auch die Demonstrationsaufrufe im Main.

Erwartungs-Check: Drei Aufträge werden in Eingangsreihenfolge ausgegeben; der vierte Bearbeitungsaufruf meldet eine leere Warteschlange. Ein neuer Auftrag danach muss wieder bedient werden können.

Modelliere eine Bestellwarteschlange für einen Online-Shop:

  • Klasse Bestellung (kundeName, produktName, menge)
  • Klasse FulfillmentCenter mit Queue<Bestellung>
  • Methode bestellungAufgeben(String kunde, String produkt, int menge) -- neue Bestellung erstellen und enqueuen
  • Methode naechsteBearbeiten() -- naechste Bestellung bearbeiten (front + dequeue)

IDE lädt…

Vernetzung

Heute gelöst: FIFO legt die Reihenfolge fest; Verkettung ist eine mögliche Umsetzung. Die NRW-Queue wächst durch neue Knoten. Welche Umsetzung sinnvoll ist, hängt von den benötigten Operationen ab.

Noch offen: Die Queue ist bequem, solange du nur vorne bedienen willst. Schwieriger wird es, wenn du etwas wissen möchtest: Wie viele Bestellungen sind offen? Ist eine bestimmte Bestellung dabei? Dafür musst du in die Queue hineinschauen, und das geht nur, indem du Elemente entnimmst.

Nächster Schritt: Im nächsten Kapitel wird genau diese Zugriffskrise gelöst: Wie untersucht man eine Queue, ohne sie zu zerstören?

Reflexion

Hinweis

Beantworte die Leitfrage: Was macht die Queue besser als ein Array — und wann reicht ein Array trotzdem?

Textabgabe

Abgabe bis: 2027-07-31T23:59:00+02:00

Selbstdiagnose

  • Ich kann erklären, warum Arrays bei dynamischen Daten unpraktisch sind.
  • Ich kenne die 4 Queue-Methoden und kann die Ausgabe vorhersagen.
  • Ich kann ein Objektdiagramm einer Queue zeichnen (head, tail, next, content).
  • Ich weiß, dass dequeue() das Objekt nicht löscht, sondern nur aus der Queue aushängt.

Partnerprüfung oder Solo-Erklärung (5 Minuten)

Erkläre 2 Minuten lang deine gewählte Methode. Dein Gegenüber prüft einen Randfall und fragt: „Warum bleibt die Reihenfolge hier erhalten oder ändert sich?“ Wechselt dann die Rollen. Allein: Schreibe die Erklärung und beantworte dieselbe Frage schriftlich. Vergleiche mit dem passenden Beispiel und verbessere einen unklaren Satz.

Selbstdiagnose: Welchen Ablauf, welche Begründung und welchen Randfall kannst du ohne Hilfe erklären? Nenne jeweils eine konkrete Aufgabe als Beleg. Wie sicher bist du (1–5)? Bei 1–2 bearbeitest du eine passende Hilfe und den neuen Versuch; bei 4–5 wählst du eine eigene Erweiterung.