🎯 Worum geht es?
Eine Liste von Zahlen wird als Balken angezeigt. Sortieren heißt: Am Ende stehen die Balken von links (klein) nach rechts (groß). Dein Programm zeigt dabei jeden Schritt an und zählt mit, wie viel Arbeit das Verfahren macht.
✅ Das kannst du danach erklären
Wie SelectionSort in jeder Runde das kleinste Element findet und warum links ein sortierter Bereich wächst.
💻 Das kannst du danach programmieren
Die Methode selectionSort() mit zwei Schleifen, einem Vergleich und einem Tausch, in deinem BlueJ-Projekt.
🔍 Das Minimum-Spiel: Du bist der Algorithmus
+30 XP · Abzeichen 🔍SelectionSort funktioniert wie ein Kartenspieler, der seine Karten ordnet: Such die kleinste Karte und leg sie ganz nach links. Dann such die nächstkleinste. Und so weiter.
Deine Aufgabe: Klicke immer auf die kleinste Zahl im noch unsortierten (weißen) Bereich. Sie wird dann automatisch nach links getauscht und grün markiert.
🆚 Zwei Sortierideen im Vergleich
+20 XP| 🫧 BubbleSort (kennst du schon) | 🔍 SelectionSort (deine Mission) | |
|---|---|---|
| Grundidee | Vergleicht immer zwei Nachbarn. Steht die größere links, wird getauscht. | Sucht erst das kleinste Element im unsortierten Bereich, tauscht dann einmal. |
| Was nach einer Runde feststeht | Die größte Zahl ist rechts angekommen. | Die kleinste Zahl steht links fest. |
| Wo der sortierte Bereich wächst | Von rechts nach links 🟩⬅️ | Von links nach rechts ➡️🟩 |
| Tausche | Viele kleine Tausche, oft mehrere pro Runde. | Höchstens ein Tausch pro Runde. |
| Vergleiche | Viele. | Genauso viele. Gespart wird nur beim Tauschen. |
⚙️ Der Simulator
+20 XP · Abzeichen ⚙️
Genau diese Anzeige baust du nachher in BlueJ. Beobachte besonders die gelbe Markierung:
Sie ist das Gedächtnis des Algorithmus und merkt sich die Stelle der bisher kleinsten Zahl,
im Programm heißt sie kleinsteStelle.
🤔 Beobachtungsaufgabe (für Schnelle)
a) Wann springt die gelbe Markierung um und wann bleibt sie stehen?
b) Warum muss die Suche nur rechts von der ersten freien Stelle beginnen?
c) Manchmal wird am Rundenende gar nicht getauscht. In welchem Fall passiert das?
🧠 Der Plan: erst denken, dann tippen
+20 XP · Abzeichen 🧠Eine Runde von SelectionSort besteht aus vier Schritten. Aber in welcher Reihenfolge? Klicke die Schritte in der richtigen Reihenfolge an (1, 2, 3, 4):
📜 Der fertige Pseudocode
So sieht der komplette Plan aus, mit der äußeren Schleife für die Runden:
für i von 0 bis anzahl - 2: // jede Runde: Stelle i wird besetzt kleinsteStelle = i // Merkzettel: vorerst ist i die kleinste Stelle für j von i + 1 bis anzahl - 1: // durchsuche den unsortierten Rest wenn zahlen[j] < zahlen[kleinsteStelle]: kleinsteStelle = j // neuen Fund auf den Merkzettel schreiben wenn kleinsteStelle nicht i ist: tausche(i, kleinsteStelle) // kleinste Zahl nach links holen
🧩 Lückentext: Sitzt der Plan?
+20 XP · Abzeichen 🧩Wähle in jeder Lücke das richtige Wort aus und prüfe dann.
i.i
.🛠️ BlueJ-Anleitung
Hast du das Projekt aus der letzten Stunde noch? Dann öffne es und springe zu Schritt 5. Sonst von vorn:
Sortieren. Wichtig: Die SuM-Bibliothek muss im Projekt verfügbar sein, frag sonst deine Lehrkraft.Main (großes M!).Main öffnen, alten Inhalt komplett löschen und die Vorlage aus Station 8 einfügen.Main → new Main(). Das Fenster mit den Balken erscheint.bubbleSort() ansehen, dann an selectionSort() arbeiten. Mit neueZahlen() bekommst du frische Balken.🚑 Erste Hilfe bei Fehlermeldungen
| Meldung | Was meistens los ist |
|---|---|
; expected | Am Zeilenende fehlt ein Semikolon, oft eine Zeile über der markierten. |
cannot find symbol | Variablenname falsch geschrieben (kleinsteStelle mit großem S!) oder Variable nicht deklariert. |
'}' expected / reached end of file | Geschweifte Klammern zählen: Jede { braucht ihre }. Einrücken hilft beim Zählen. |
class Main is public, should be declared in a file named Main.java | Die Klasse heißt nicht genau Main. Name in BlueJ und im Code müssen übereinstimmen. |
| Fenster reagiert nicht mehr | Wahrscheinlich eine Endlosschleife. Prüfe, ob i und j in den Schleifen wirklich hochgezählt werden. |
🧩 Programmierauftrag: selectionSort()
In der Vorlage ist bubbleSort() komplett fertig. Nutze es als Spickzettel:
Dort siehst du, wie Schleifen, Vergleiche, tausche(...), zeichne(...) und
uhr.warte(...) zusammenspielen. Deine Baustelle ist nur die Methode selectionSort()
mit ihren vier TODOs.
🎯 Mindestziel
selectionSort() sortiert jede neue Zahlenliste richtig. Die Anzeige darf dabei erstmal schlicht bleiben.
🌟 Profi-Ziel
Zusätzlich: Zähler hochzählen und mit zeichne(...) jeden Vergleich sichtbar machen, so wie bei bubbleSort().
import sum.kern.*; import sum.werkzeuge.*; /** * Vereinfachte Sortier-Visualisierung fuer BlueJ und die SuM-Bibliothek. * BubbleSort ist fertig vorgegeben. * SelectionSort ist die Schueleraufgabe. */ public class Main { // Bezugsobjekte Bildschirm derBildschirm; Buntstift stift; Uhr uhr; Rechner rechner; // Daten int[] zahlen; int anzahl; // Darstellung int links; int basis; int balkenBreite; int luecke; int faktor; // Zaehler int vergleiche; int tausche; /** * Konstruktor: Erzeugt Fenster und Startzahlen. */ public Main() { derBildschirm = new Bildschirm(720, 500, true); stift = new Buntstift(); uhr = new Uhr(); rechner = new Rechner(); anzahl = 8; links = 60; basis = 400; balkenBreite = 50; luecke = 18; faktor = 4; zahlen = new int[anzahl]; neueZahlen(); } /** * Erzeugt eine neue unsortierte Zahlenliste. */ public void neueZahlen() { int i; for(i = 0; i < anzahl; i++) { zahlen[i] = rechner.ganzeZufallsZahl(15, 80); } vergleiche = 0; tausche = 0; zeichne("Neue Zahlen", -1, -1, -1, -1, "Rufe jetzt bubbleSort() oder deine Methode selectionSort() auf."); } /** * BubbleSort ist als Beispiel komplett vorgegeben. * Idee: Nach jeder Runde ist rechts eine weitere Zahl sicher sortiert. */ public void bubbleSort() { int runde; int i; vergleiche = 0; tausche = 0; zeichne("BubbleSort", -1, -1, -1, anzahl, "Benachbarte Zahlen werden verglichen."); uhr.warte(900); for(runde = 0; runde < anzahl - 1; runde++) { for(i = 0; i < anzahl - 1 - runde; i++) { vergleiche++; zeichne("BubbleSort", i, i + 1, -1, anzahl - runde, "Vergleich: Stehen diese Nachbarn falsch herum?"); uhr.warte(700); if(zahlen[i] > zahlen[i + 1]) { tausche(i, i + 1); tausche++; zeichne("BubbleSort", i, i + 1, -1, anzahl - runde, "Tausch: Die groessere Zahl wandert nach rechts."); uhr.warte(700); } } zeichne("BubbleSort", -1, -1, -1, anzahl - runde - 1, "Runde fertig: Rechts ist ein weiterer Balken sortiert."); uhr.warte(500); } zeichne("BubbleSort fertig", -1, -1, -1, 0, "Fertig. Vergleiche die Anzahl der Vergleiche und Tausche."); } /** * AUFGABE: Programmiere SelectionSort. * * Idee: * 1. i zeigt auf die erste freie Stelle links. * 2. kleinsteStelle merkt sich die Stelle mit der kleinsten Zahl. * 3. j durchsucht den unsortierten Bereich rechts von i. * 4. Am Ende wird die kleinste gefundene Zahl nach i getauscht. */ public void selectionSort() { int i; int j; int kleinsteStelle; vergleiche = 0; tausche = 0; zeichne("SelectionSort: noch unvollstaendig", -1, -1, -1, -1, "Ersetze diese Methode mithilfe der Lernstrecke."); uhr.warte(1200); // TODO 1: aeussere Schleife fuer die Runden: // for(i = 0; i < anzahl - 1; i++) // TODO 2: Am Anfang jeder Runde den Merkzettel setzen: // kleinsteStelle = i; // TODO 3: innere Schleife, die den Rest durchsucht: // for(j = i + 1; j < anzahl; j++) // Vergleiche zahlen[j] mit zahlen[kleinsteStelle]. // Wenn zahlen[j] kleiner ist: kleinsteStelle = j; // TODO 4: Nach der inneren Schleife: // Wenn kleinsteStelle nicht i ist: tausche(i, kleinsteStelle); // Tipp fuer die Anzeige zwischendurch: // zeichne("SelectionSort", j, -1, kleinsteStelle, -1, "..."); // uhr.warte(700); // Damit wird j rot und kleinsteStelle gelb markiert. } /** * Tauscht zwei Werte im Feld zahlen. */ private void tausche(int a, int b) { int hilfe; hilfe = zahlen[a]; zahlen[a] = zahlen[b]; zahlen[b] = hilfe; } /** * Zeichnet das komplette Bild neu. * vergleichA und vergleichB werden rot markiert. * minimum wird gelb markiert. * sortiertAb bedeutet: ab diesem Index ist rechts sortiert (gruen). */ private void zeichne(String titel, int vergleichA, int vergleichB, int minimum, int sortiertAb, String meldung) { int i; int x; int y; int hoehe; // Hintergrund stift.setzeFuellmuster(Muster.GEFUELLT); setzeFarbe(245, 247, 250); stift.bewegeBis(0, 0); stift.zeichneRechteck(720, 500); // Kopf setzeFarbe(35, 50, 75); stift.bewegeBis(0, 0); stift.zeichneRechteck(720, 90); stift.setzeFarbe(Farbe.rgb(255, 255, 255)); stift.setzeSchriftgroesse(24); stift.bewegeBis(30, 28); stift.schreibeText(titel); stift.setzeSchriftgroesse(14); stift.bewegeBis(360, 25); stift.schreibeText("Vergleiche: "); stift.schreibeZahl(vergleiche); stift.bewegeBis(360, 50); stift.schreibeText("Tausche: "); stift.schreibeZahl(tausche); // Meldung stift.setzeFarbe(Farbe.rgb(40, 40, 40)); stift.setzeSchriftgroesse(15); stift.bewegeBis(30, 118); stift.schreibeText(meldung); // Grundlinie stift.setzeFuellmuster(Muster.DURCHSICHTIG); stift.setzeFarbe(Farbe.rgb(0, 0, 0)); stift.setzeLinienbreite(2); stift.bewegeBis(45, basis); stift.runter(); stift.bewegeBis(665, basis); stift.hoch(); stift.setzeLinienbreite(1); // Balken for(i = 0; i < anzahl; i++) { x = links + i * (balkenBreite + luecke); hoehe = zahlen[i] * faktor; y = basis - hoehe; if(i == vergleichA || i == vergleichB) { setzeFarbe(230, 80, 70); // rot: Vergleich } else if(i == minimum) { setzeFarbe(245, 200, 60); // gelb: gemerktes Minimum } else if(sortiertAb >= 0 && i >= sortiertAb) { setzeFarbe(100, 180, 110); // gruen: sortierter Bereich rechts } else { setzeFarbe(80, 140, 220); // blau: normal } stift.setzeFuellmuster(Muster.GEFUELLT); stift.bewegeBis(x, y); stift.zeichneRechteck(balkenBreite, hoehe); stift.setzeFuellmuster(Muster.DURCHSICHTIG); stift.setzeFarbe(Farbe.rgb(0, 0, 0)); stift.bewegeBis(x, y); stift.zeichneRechteck(balkenBreite, hoehe); stift.setzeSchriftgroesse(13); stift.bewegeBis(x + 10, y - 22); stift.schreibeZahl(zahlen[i]); stift.setzeFarbe(Farbe.rgb(90, 90, 90)); stift.setzeSchriftgroesse(12); stift.bewegeBis(x + 18, basis + 15); stift.schreibeZahl(i); } derBildschirm.zeichneDich(); } /** * Kleine Hilfsmethode, damit Farben fuer Schueler lesbarer bleiben. */ private void setzeFarbe(int r, int g, int b) { stift.setzeFarbe(Farbe.rgb(r, g, b)); } }
j = i + 1,
nicht bei 0, sonst durchsuchst du den schon sortierten Bereich nochmal.
Beim Vergleich werden die Zahlen verglichen (zahlen[j] < zahlen[kleinsteStelle]),
aber auf den Merkzettel kommt die Stelle (kleinsteStelle = j;, nicht = zahlen[j]!).
🛟 Gestufte Hilfen
Hänge nicht länger als 5 Minuten an einer Stelle fest. Öffne dann die nächste Hilfe, aber immer nur eine auf einmal.
🥉 Hilfe 1: TODO 1 und 2, äußere Schleife und Merkzettel
for(i = 0; i < anzahl - 1; i++) { kleinsteStelle = i; // hierhin kommt gleich die innere Schleife (TODO 3) // und danach der Tausch (TODO 4) }
Alles, was zu einer Runde gehört, steht innerhalb der geschweiften Klammern dieser Schleife. Schreib die Klammern zuerst hin, dann verrutscht nichts.
🥈 Hilfe 2: TODO 3, die Suche mit j
for(j = i + 1; j < anzahl; j++) { vergleiche = vergleiche + 1; zeichne("SelectionSort", j, -1, kleinsteStelle, -1, "Ist die rote Zahl kleiner als die gelbe?"); uhr.warte(700); if(zahlen[j] < zahlen[kleinsteStelle]) { kleinsteStelle = j; } }
Diese Schleife gehört komplett in die äußere Schleife aus Hilfe 1. Sie tauscht nichts, sie schaut nur und aktualisiert den Merkzettel.
🥇 Hilfe 3: TODO 4, der Tausch am Rundenende
if(kleinsteStelle != i) { tausche(i, kleinsteStelle); tausche = tausche + 1; } zeichne("SelectionSort", -1, -1, -1, -1, "Runde fertig: Stelle " + i + " ist endgueltig besetzt."); uhr.warte(600);
Dieser Block steht nach der inneren Schleife, aber noch innerhalb der äußeren.
Das != bedeutet „ungleich“: Steht die kleinste Zahl schon richtig, wird nicht unnötig getauscht.
🚨 Notfall-Hilfe: komplette Musterlösung (wirklich nur im Notfall!)
public void selectionSort() { int i; int j; int kleinsteStelle; vergleiche = 0; tausche = 0; zeichne("SelectionSort", -1, -1, -1, -1, "Suche immer das kleinste Element im unsortierten Bereich."); uhr.warte(900); for(i = 0; i < anzahl - 1; i++) { kleinsteStelle = i; zeichne("SelectionSort", -1, -1, kleinsteStelle, -1, "Runde " + (i + 1) + ": Merke Stelle " + i + " als kleinste (gelb)."); uhr.warte(700); for(j = i + 1; j < anzahl; j++) { vergleiche = vergleiche + 1; zeichne("SelectionSort", j, -1, kleinsteStelle, -1, "Ist die rote Zahl kleiner als die gelbe?"); uhr.warte(700); if(zahlen[j] < zahlen[kleinsteStelle]) { kleinsteStelle = j; zeichne("SelectionSort", -1, -1, kleinsteStelle, -1, "Ja! Neue kleinste Stelle gefunden."); uhr.warte(700); } } if(kleinsteStelle != i) { tausche(i, kleinsteStelle); tausche = tausche + 1; } zeichne("SelectionSort", -1, -1, -1, -1, "Runde fertig: Stelle " + i + " ist endgueltig besetzt."); uhr.warte(600); } zeichne("SelectionSort fertig", -1, -1, -1, 0, "Fertig! Rufe neueZahlen() und bubbleSort() auf und vergleiche die Zaehler."); }
Wenn du die Lösung kopierst: Geh sie Zeile für Zeile durch und schreib an jeden Block einen eigenen Kommentar, was er tut. In der nächsten Stunde erklärst du den Ablauf ohne Spickzettel. 😉
Hinweis zur Anzeige: Anders als im Browser-Simulator wird der fertige Bereich links im
BlueJ-Fenster nicht grün, denn zeichne kann bisher nur rechts grün färben (das brauchte BubbleSort).
Grün links ist Bonus-Mission D. 🌟
🚀 Bonus-Missionen
Fertig und alles läuft? Such dir eine Mission aus. Schwierigkeit steigt mit den Sternen.
⭐ Mission A: Der große Zähler-Vergleich
Tabelle im Heft: Lass bubbleSort() und selectionSort() je dreimal mit neuen Zahlen laufen
und notiere Vergleiche und Tausche. Bei welchem Zähler unterscheiden sich die Verfahren deutlich, bei welchem kaum? Begründe!
⭐ Mission B: Rückwärts sortieren
Schreibe eine Kopie deiner Methode als selectionSortAbsteigend(), die die größte Zahl nach links holt.
Tipp: Du musst nur ein einziges Zeichen ändern. Welches?
⭐⭐ Mission C: Der Schon-fertig-Test
Schreibe eine Methode sortierteZahlen(), die das Feld mit bereits sortierten Werten füllt (z. B. 10, 20, 30, ...).
Wie viele Tausche macht selectionSort() dann? Sage es erst voraus, teste dann. Und BubbleSort?
⭐⭐⭐ Mission D: Grün auch links!
Erweitere zeichne um einen Parameter int sortiertBis, der alle Balken mit
i <= sortiertBis grün färbt. Passe danach alle Aufrufe an
(bei BubbleSort übergibst du einfach -1). Dann wächst bei SelectionSort der grüne Bereich links, wie im Simulator.
🏆 Abschluss-Check
+40 XP · Abzeichen 🏆Hake ehrlich ab. Erst wenn alles sitzt, gibt es den Meistertitel.