Übungsaufgaben zu Sortieralgorithmen und Vergleichsfunktionen
https://bildung.social/@oerinformatik/
https://oer-informatik.de/sortieralgorithmen-uebungsaufgaben
Sortieralgorithmen, Bubblesort, Selectionsort, Insertionsort, Vergleichsfunktion, Stabilität, Schreibtischtest, Struktogramm, Übungsaufgaben, Prüfungsvorbereitung
tl/dr; (Bearbeitungszeit insgesamt 139 min, mehrere Aufgaben): Vier Übungsaufgaben zu Sortieralgorithmen. Zum Einstieg zwei kürzere Aufgaben: Uhrzeiten mit Ganzzahldivision und Modulo zerlegen, Bereichsbedingungen beurteilen, einen fehlerhaften Bubblesort per Schreibtischtest korrigieren, ein Überwachungsskript mit Start- und Endwerten vervollständigen und mehrere Arrays gemeinsam sortieren. Danach folgen zwei umfangreiche Aufgaben: Schreibtischtest und Lückencode, Bubblesort über Objekte, Vergleichsfunktionen mit Kommazahlen und mehreren Kriterien, Insertionsort mit einem
Comparator, Sortieren mit Java- und Python-Bibliothek, Filtern und zweistufig Sortieren in einer Funktion, Entfernen im Durchlauf, sortiertes Einfügen, Sortieren über ein Index-Array, Stabilität und Laufzeit. Alle Lösungen sind ausgeblendet und mit Punkteverteilung versehen [AI-Assisted]. (Zuletzt geändert am 29.10.2026)
Diese Übungsaufgaben gehören zum Artikel Sortieralgorithmen und Vergleichsfunktionen. Die Grundmuster für Arrays (Durchlaufen, Zählen, Extremwerte) erklärt der Artikel Prozedurale Algorithmen mit Arrays.
Hinweise zur Bearbeitung: Als FIA oder FISY musst Du zur Teil-2-Prüfung Aufgaben auf Kernkompetenz-Ebene lösen können, das sind Aufgabe 2.1 und Aufgabe 2.2. Von FIA wird zusätzlich erwartet, dass ihnen Aufgaben auf Profilkompetenz-Ebene (Aufgabe 3.1 und Aufgabe 3.2) keine Probleme bereiten. Wenn nichts anderes verlangt ist, darfst Du Deine Algorithmen in Pseudocode, als Struktogramm oder als Programmablaufplan angeben. Arrays und Listen beginnen mit dem Index 0; Variablen musst Du nicht deklarieren. Fertige Sortierfunktionen einer Programmiersprache darfst Du nicht verwenden, wenn ein Sortieralgorithmus verlangt ist. Die Beispiellösungen verwenden die Schreibweise aus dem Artikel (:= für die Zuweisung, = und <> für Vergleiche, zähle i von a bis b mit eingeschlossener Obergrenze). Die Aufgabentexte nennen die Datentypen wie in den Klassendiagrammen (int, real, Text); in den Beispiellösungen stehen dafür die Typen der jeweiligen Notation, im deutschen Pseudo-Pascal also integer, double und string. Andere korrekte Lösungen sind ebenfalls richtig. Schreib Deine Lösung zuerst vollständig auf, bevor Du die Beispiellösung aufklappst.
Die Codebeispiele kannst Du in vier Notationen anzeigen. Die Notationen sind im Artikel Algorithmen mit Pseudocode dokumentieren beschrieben.
anzahl: integer := laenge(zeiten)
zähle i von 0 bis anzahl - 1
Ausgabe zeiten[i]
Ende zähle
Du möchtest eigene Aufgaben zum Üben von einem KI-Sprachmodell generieren lassen?
Kopiere den Text in ein KI-Sprachmodell Deiner Wahl und passe Kompetenzstufe, Anzahl, Bearbeitungszeit und Szenario bei Bedarf an. Wie die Aufgaben aufgebaut sind, beschreibt der Artikel Wie sind die Aufgaben aufgebaut?. Prüfe die Ergebnisse mit dem Lehrartikel: KI-Sprachmodelle machen Fehler.
Erstelle neue Übungsaufgaben zum Thema „Sortieralgorithmen und
Vergleichsfunktionen“.
Bauplan: Halte Dich an Aufbau, Kompetenzstufen, Operatoren,
Anforderungsbereiche, Punkte und Zeitschätzung, die im Artikel
https://oer-informatik.de/aufgaben-aufbau beschrieben sind.
Fachliche Grundlage:
- https://oer-informatik.de/sortieralgorithmen
- https://oer-informatik.de/algorithmen-prozedural
- https://oer-informatik.de/algorithmen-objektorientiert
- https://oer-informatik.de/laufzeit-komplexitaet
- Stilbeispiel: https://oer-informatik.de/sortieralgorithmen-uebungsaufgaben
Die Aufgaben sollen Inhalte zu diesen Schlagwörtern abdecken:
- Sortieralgorithmen
- Bubblesort
- Selectionsort
- Insertionsort
- Vergleichsfunktion
- Stabilität
- Schreibtischtest
- Struktogramm
Kompetenzstufe: Kernkompetenz (alternativ: Basiskompetenz, Profilkompetenz, Expertise)
Anzahl: 1 Aufgabe mit Teilaufgaben
Bearbeitungszeit in Minuten ca.: <5 bis 30 min>
Szenario: eines der Szenarien aus dem Bauplan
Vorgehen:
1. Lies zuerst die verlinkten Artikel. Kannst Du keine Webseiten
abrufen, sag mir das, statt zu raten.
2. Steht bei einer Angabe noch ein Platzhalter in <…>, frag mich
zuerst danach. Richte Punkte und Zahl der Teilaufgaben nach der
Bearbeitungszeit (ca. 0,9 min je Punkt).
3. Gib je Aufgabe Titel mit Kompetenzstufe, Ausgangssituation und
Teilaufgaben mit Operator und Punktzahl aus, dazu die geschätzte
Bearbeitungszeit.
4. Gib die Beispiellösungen mit Punkteverteilung erst aus, wenn ich
danach frage.
Aufgabe 2.1: Rückfahrten am Flurmonitor prüfen und ordnen (Kernkompetenz)
(ca. 17 min Bearbeitungszeit)
Die Flurmonitore der Mitfahr-App RatzFahrt am Ratz und Rübe Berufskolleg sollen nachmittags die Rückfahrten ins Umland anzeigen, die früheste oben. Im Inserat speichert die App die Abfahrtszeit als ganze Zahl im Format hhmm: 1415 steht für 14:15 Uhr, 905 für 9:05 Uhr. Du entwickelst die Anzeige zusammen mit Deiner Mit-Azubi Oksana Melnyk. In Java liefert / bei ganzen Zahlen den ganzzahligen Anteil der Division und % den Rest.
a) Gib für eine Abfahrtszeit zeit je einen Ausdruck für die Stunde, für die Minute und für die Minuten seit Mitternacht an. Berechne damit, wie viele Minuten zwischen 13:50 Uhr und 14:15 Uhr liegen, und erkläre, warum 1415 - 1350 ein falsches Ergebnis liefert. (5 Punkte)
int stunde = zeit / 100; // 1415 / 100 = 14
int minute = zeit % 100; // 1415 % 100 = 15
int minutenSeitMitternacht = stunde * 60 + minute;- je Ausdruck 1 Punkt (gleichwertig:
zeit / 100 * 60 + zeit % 100) - 13:50 Uhr sind 13 · 60 + 50 = 830 Minuten, 14:15 Uhr sind 855 Minuten; dazwischen liegen 25 Minuten (1 Punkt).
1415 - 1350 = 65: Die beiden rechten Stellen zählen nur bis 59, die Zahl springt aber von 1359 auf 1400. Die Differenz rechnet so, als hätte eine Stunde 100 Minuten (1 Punkt).
b) Der Flurmonitor soll nur Rückfahrten zeigen, die zwischen 13:00 Uhr und 17:30 Uhr (jeweils einschließlich) starten. Weil Inserate früher von Hand eingetragen wurden, stehen im Bestand auch unsinnige Werte wie 1275. Oksana schlägt drei Bedingungen vor:
(1) zeit >= 1300 || zeit <= 1730
(2) zeit >= 1300 && zeit <= 1730
(3) zeit >= 1300 && zeit <= 1730 && zeit % 100 < 60Beurteile jede Bedingung mit je einem passenden Testwert und entscheide, welche in die App kommt. (4 Punkte)
- ist für jede Zahl wahr, z. B. auch für
1745: Jede Zahl ist mindestens 1300 oder höchstens 1730. Die Oder-Verknüpfung filtert nichts (1 Punkt).
- ist für jede Zahl wahr, z. B. auch für
- (2) prüft beide Grenzen richtig mit Und, lässt aber
1575durch – eine Uhrzeit mit 75 Minuten (1 Punkt). - (3) schließt zusätzlich unmögliche Minutenwerte aus:
1575 % 100 = 75ist nicht kleiner als 60 (1 Punkt). - Einbauen: Bedingung (3);
1300und1730liegen als Grenzwerte noch im Bereich (1 Punkt).
c) Für die Reihenfolge auf dem Monitor hat Oksana einen Bubblesort geschrieben. Die Rückfahrten liegen lückenlos im Array zeiten.
void sortiereAbfahrten(int[] zeiten) {
int n = zeiten.length;
for (int d = 0; d < n - 1; d++) {
for (int i = 1; i < n - 1 - d; i++) {
if (zeiten[i] > zeiten[i + 1]) {
zeiten[i] = zeiten[i + 1];
int hilf = zeiten[i];
zeiten[i + 1] = hilf;
}
}
}
}Mit den Testdaten {1540, 1315, 1505, 1640, 1300} zeigt der Monitor danach {1540, 1300, 1300, 1300, 1300}.
ca) Ermittle mit einem Schreibtischtest den Inhalt des Arrays nach dem ersten Durchlauf der äußeren Schleife (d = 0). (3 Punkte)
i |
Vergleich | Wirkung | zeiten danach |
|---|---|---|---|
| 1 | 1315 > 1505? nein | – | {1540, 1315, 1505, 1640, 1300} |
| 2 | 1505 > 1640? nein | – | {1540, 1315, 1505, 1640, 1300} |
| 3 | 1640 > 1300? ja | 1300 wird nach vorne kopiert, 1640 geht verloren | {1540, 1315, 1505, 1300, 1300} |
1 Punkt für den Start bei i = 1, 2 Punkte für das Array nach dem Durchlauf.
cb) Beschreibe die beiden Fehler und gib die korrigierten Anweisungen an. (4 Punkte)
- Startwert der inneren Schleife: Mit
i = 1wird das Element auf Index 0 nie verglichen; 1540 bleibt vorne stehen. Korrektur:for (int i = 0; i < n - 1 - d; i++)(2 Punkte). - Reihenfolge im Tausch: Der linke Wert wird überschrieben, bevor er in
hilfgesichert ist; danach steht der kleinere Wert doppelt im Array, der größere fehlt. Korrektur (Ringtausch, 2 Punkte):
int hilf = zeiten[i];
zeiten[i] = zeiten[i + 1];
zeiten[i + 1] = hilf;Mit beiden Korrekturen ergibt sich {1300, 1315, 1505, 1540, 1640}.
d) Oksana fragt, ob man vor dem Sortieren nicht erst alle Zeiten in Minuten seit Mitternacht umrechnen müsste. Begründe, ob der direkte Vergleich der hhmm-Zahlen für die Sortierung ausreicht. (2 Punkte)
Für die Reihenfolge reicht der direkte Vergleich: Eine spätere Stunde ergibt immer eine um mindestens 100 größere Zahl, und innerhalb einer Stunde wächst die Zahl mit der Minute (die Minute ist kleiner als 60) (1 Punkt). Für Abstände wie in a) muss dagegen umgerechnet werden, weil die Differenz zweier hhmm-Zahlen keine Minutenzahl ist (1 Punkt).
Aufgabe 2.2: Last der Container überwachen (Kernkompetenz)
(ca. 26 min Bearbeitungszeit)
Die Let’s Meet GmbH betreibt ihre App in fünf Containern (api, web, chat, suche, bilder). Jeder Container zählt seit seinem Start alle beantworteten Anfragen und alle fehlgeschlagenen Anfragen in je einem Zähler, der nur wächst. Entwicklungsleiter Yusuf Demir bittet Dich und Deinen Mit-Azubi Jonas Weber, ein Überwachungsskript zu vervollständigen, das alle 10 Sekunden die Last je Container anzeigt – der am stärksten belastete Container oben.
Zeile 1 container := ["api", "web", "chat", "suche", "bilder"]
Zeile 2 zähle i von 0 bis 4
Zeile 3 start[i] := leseAnfragen(container[i])
Zeile 4 fehlerStart[i] := leseFehler(container[i])
Zeile 5 Ende zähle
Zeile 6 wiederhole
Zeile 7 warte(10 s)
Zeile 8 zähle i von 0 bis 4
Zeile 9 ende[i] := leseAnfragen(container[i])
Zeile 10 fehlerEnde[i] := leseFehler(container[i])
Zeile 11 last[i] := ______________________ // Anfragen je Sekunde
Zeile 12 quote[i] := ______________________ // Fehlerquote in Prozent
Zeile 13 ______________________ // Werte für den
Zeile 14 ______________________ // nächsten Durchlauf
Zeile 15 Ende zähle
Zeile 16 sortiereAbsteigend(container, last, quote)
Zeile 17 zeige(container, last, quote)
Zeile 18 solange das Skript nicht beendet wird
a) Ergänze die Zeilen 11 und 12. Die Fehlerquote ist der Anteil der fehlgeschlagenen an allen Anfragen der letzten 10 Sekunden. (5 Punkte)
Zeile 11 last[i] := (ende[i] - start[i]) / 10
Zeile 12 quote[i] := (fehlerEnde[i] - fehlerStart[i]) / (ende[i] - start[i]) * 100
Zeile 11: 1 Punkt Differenz, 1 Punkt Division durch 10 s. Zeile 12: je 1 Punkt für Zähler- und Nenner-Differenz, 1 Punkt für den Faktor 100. Der Absolutwert eines Zählers (ohne Differenz) ergibt keine Punkte für den Zähler bzw. Nenner, weil er alle Anfragen seit dem Start enthält.
b) Ergänze die Zeilen 13 und 14 und begründe, warum diese Zuweisungen nach den Zeilen 11 und 12 stehen müssen. (4 Punkte)
Zeile 13 start[i] := ende[i]
Zeile 14 fehlerStart[i] := fehlerEnde[i]
Je Zeile 1 Punkt (Reihenfolge der beiden Zeilen beliebig). Begründung (2 Punkte): Die Endwerte dieses Durchlaufs sind die Startwerte des nächsten. Würden sie vor der Berechnung übernommen, wären Start- und Endwert gleich – die Differenz und damit die Last wären immer 0 (bei der Quote sogar eine Division durch 0).
c) Jonas weist darauf hin, dass ein Container in 10 Sekunden auch einmal gar keine Anfrage bekommen kann. Beschreibe, welches Problem dann in Zeile 12 entsteht, und wie Du es behebst. (3 Punkte)
Ist ende[i] - start[i] = 0, wird durch 0 geteilt – je nach Sprache bricht das Skript ab oder liefert „unendlich“/„NaN“ (1 Punkt). Abhilfe (2 Punkte): vorher prüfen, z. B.
wenn ende[i] - start[i] > 0 dann
quote[i] := (fehlerEnde[i] - fehlerStart[i]) / (ende[i] - start[i]) * 100
sonst
quote[i] := 0
Ende wenn
d) Schreibe die Prozedur sortiereAbsteigend(namen: Text[], last: real[], quote: real[]), die die drei Arrays mit Bubblesort so umordnet, dass der Container mit der höchsten Last vorne steht. Name, Last und Fehlerquote eines Containers müssen dabei zusammenbleiben. (11 Punkte)
Prozedur sortiereAbsteigend(namen: string[], last: double[], quote: double[])
n: integer := laenge(namen)
zähle p von 0 bis n - 2
zähle i von 0 bis n - 2 - p
wenn last[i] < last[i + 1] dann
hilfZahl: double := last[i]
last[i] := last[i + 1]
last[i + 1] := hilfZahl
hilfName: string := namen[i]
namen[i] := namen[i + 1]
namen[i + 1] := hilfName
hilfZahl := quote[i]
quote[i] := quote[i + 1]
quote[i + 1] := hilfZahl
Ende wenn
Ende zähle
Ende zähle
Ende sortiereAbsteigend
- 2 Punkte äußere Schleife mit
n - 1Durchläufen. - 2 Punkte innere Schleife: Zugriff auf
i + 1bleibt im Array (die Verkürzung umpist nicht verlangt). - 2 Punkte Vergleich der Last mit
<(absteigend). - 5 Punkte Tausch: Last 2, Name 2, Quote 1 Punkt. Wird nur
lastgetauscht, passen Namen und Quoten nicht mehr zu den Werten.
Gleichwertig ist eine Lösung mit einem Array von Objekten (Name, Last, Quote), in der ganze Objekte getauscht werden.
e) Nach einem Durchlauf liegen diese Werte vor: Namen ["api", "web", "chat", "suche", "bilder"], Last [12.5, 40.0, 7.3, 40.0, 3.1]. Gib die Reihenfolge der Namen nach dem Sortieren an und begründe, warum web vor suche steht. (3 Punkte)
["web", "suche", "api", "chat", "bilder"] (2 Punkte). web und suche haben dieselbe Last. Getauscht wird nur bei echtem <, Elemente mit gleichem Wert werden nie vertauscht – Bubblesort ist so stabil, und die ursprüngliche Reihenfolge (web vor suche) bleibt erhalten (1 Punkt).
f) Bestimme, wie viele Vergleiche Dein Algorithmus bei fünf Containern in jedem Durchlauf des Skripts ausführt. (2 Punkte)
Die innere Schleife vergleicht 4 + 3 + 2 + 1 = 10-mal (allgemein \frac{n \cdot (n-1)}{2}) (1 Punkt Rechenweg, 1 Punkt Ergebnis). Ohne die Verkürzung um p wären es 4 · 4 = 16 Vergleiche.
Aufgabe 3.1: Nachbestellliste und Händlerportal im Fahrrad-Onlineshop (Profilkompetenz)
(ca. 54 min Bearbeitungszeit)
Du bist Auszubildende*r im IT-Team der CSB-Rad GmbH in Bielefeld. Cem Sarıkaya, Geschäftsführer Technik und IT, hat Dich für zwei Projekte eingeteilt: Im Projekt „Lager 4.0“ zeigen Tablets in Werkstatt und Lager künftig Listen an, und das neue Händlerportal soll den 37 Fachhändlern das Sortiment in verschiedenen Sortierungen anbieten. Jonas, Dein Mit-Azubi, arbeitet mit Dir zusammen.
Im Shop-Backend gibt es die Klasse Artikel:
Artikel
- artikelnr: Text
- bezeichnung: Text
- kategorie: Text // Bezeichnung der Kategorie, z. B. "Bremsen"
- nettoPreis: real
- lagerbestand: int
- mindestbestand: int
+ getArtikelnr(): Text
+ getBezeichnung(): Text
+ getKategorie(): Text
+ getNettoPreis(): real
+ getLagerbestand(): int
+ getMindestbestand(): int
a) Die Werkstatt-Tablets zeigen die Montagezeiten der letzten Lastenräder in Minuten aufsteigend an. Ein Dienstleister hat dafür folgende Prozedur geliefert:
Prozedur sortiereZeiten(zeiten: integer[])
ende := laenge(zeiten) - 1
getauscht := true
solange getauscht
getauscht := false
zähle j von 0 bis ende - 1
wenn zeiten[j] > zeiten[j + 1] dann
hilf := zeiten[j]
zeiten[j] := zeiten[j + 1]
zeiten[j + 1] := hilf
getauscht := true
Ende wenn
Ende zähle
ende := ende - 1
Ende solange
Ende sortiereZeiten
aa) Ermittle mit einem Schreibtischtest für zeiten = [95, 40, 120, 40, 75] den Inhalt des Arrays sowie die Werte von getauscht und ende am Ende jedes Durchlaufs der solange-Schleife. Gib außerdem an, wie viele Vergleiche zeiten[j] > zeiten[j + 1] insgesamt ausgeführt werden. (4 Punkte)
| Durchlauf | Vergleiche (getauscht in Klammern) | zeiten am Ende |
getauscht |
ende |
|---|---|---|---|---|
| (Start) | – | [95, 40, 120, 40, 75] |
wahr | 4 |
| 1 | 95/40 (getauscht), 95/120, 120/40 (getauscht), 120/75 (getauscht) | [40, 95, 40, 75, 120] |
wahr | 3 |
| 2 | 40/95, 95/40 (getauscht), 95/75 (getauscht) | [40, 40, 75, 95, 120] |
wahr | 2 |
| 3 | 40/40, 40/75 | [40, 40, 75, 95, 120] |
falsch | 1 |
Nach dem dritten Durchlauf ist getauscht falsch, die Schleife endet. Insgesamt werden 4 + 3 + 2 = 9 Vergleiche ausgeführt.
Bewertung: je Durchlauf 1 Punkt (Array, getauscht und ende richtig), Anzahl der Vergleiche 1 Punkt.
ab) Nenne das Sortierverfahren und erläutere, welche Aufgabe die Variablen ende und getauscht haben. (3 Punkte)
Verfahren: Bubblesort (Sortieren durch Vertauschen benachbarter Elemente). (1 Punkt)
ende: Nach jedem Durchlauf steht das größte noch unsortierte Element am Ende des betrachteten Bereichs.endeverkleinert diesen Bereich um eins, damit bereits sortierte Elemente nicht erneut verglichen werden. (1 Punkt)getauscht: merkt, ob im aktuellen Durchlauf mindestens einmal getauscht wurde. Gab es keinen Tausch, ist das Array sortiert, und die Schleife endet vorzeitig. Im Beispiel spart das einen vierten Durchlauf. (1 Punkt)
b) Natalia Wróbel aus der Buchhaltung möchte die offenen Posten nach Betrag absteigend sehen. Jonas hat dafür ein anderes Verfahren gewählt, aber nicht alle Zeilen fertig geschrieben:
Prozedur sortiereOffenePosten(betraege: double[])
n := laenge(betraege)
zähle i von 0 bis n - 2
posMax := i
(1) .........................................
wenn (2) ............................... dann
(3) .................................
Ende wenn
Ende zähle
hilf := betraege[i]
(4) .........................................
(5) .........................................
Ende zähle
Ende sortiereOffenePosten
ba) Ergänze die Lücken (1) bis (5). (6 Punkte)
(1) zähle j von i + 1 bis n - 1
(2) betraege[j] > betraege[posMax]
(3) posMax := j
(4) betraege[i] := betraege[posMax]
(5) betraege[posMax] := hilf
Bewertung: (1) 2 Punkte (Start bei i + 1 und Grenze n - 1, je 1 Punkt), (2) 1 Punkt (Richtung > für absteigend), (3) 1 Punkt, (4) und (5) zusammen 2 Punkte. Ein zusätzliches wenn posMax <> i um den Tausch ist richtig, aber nicht nötig.
bb) Nenne das Verfahren, das Jonas verwendet. (1 Punkt)
Selectionsort (Sortieren durch Auswählen): Im unsortierten Bereich wird das größte Element gesucht und an die erste unsortierte Position getauscht.
bc) In einer ersten Fassung hatte Jonas den Tausch so geschrieben:
betraege[i] := betraege[posMax]
betraege[posMax] := betraege[i]
Erläutere, welches Ergebnis dieser Tausch hat. (2 Punkte)
Nach der ersten Zeile steht der größte Betrag in beiden Feldern; der ursprüngliche Wert von betraege[i] ist überschrieben. Die zweite Zeile schreibt denselben Wert zurück. Danach enthält das Array den größten Betrag doppelt, der überschriebene Betrag fehlt (1 Punkt). Für den Tausch braucht man eine Hilfsvariable, die den alten Wert von betraege[i] zwischenspeichert (Ringtausch) (1 Punkt).
c) Bastian Ludwig, Leiter von Werkstatt und Einkauf, erhält jeden Morgen eine Nachbestellliste auf sein Tablet. Sie enthält alle Artikel, deren Lagerbestand unter dem Mindestbestand liegt, und ist bisher nach Artikelnummer sortiert. Künftig sollen die Artikel mit der größten Fehlmenge (Mindestbestand minus Lagerbestand) oben stehen. Die Liste vom 26.10.2026:
| Index | Artikelnummer | Bezeichnung | Lagerbestand | Mindestbestand |
|---|---|---|---|---|
| 0 | BRE-BEL-02 | Bremsbelag-Satz | 4 | 15 |
| 1 | BRE-HYD-01 | Hydraulische Scheibenbremse (Paar) | 9 | 12 |
| 2 | KET-11-E | Kette 11-fach E-Bike | 6 | 8 |
| 3 | LIC-SET-01 | Lichtset Nabendynamo StVZO | 18 | 25 |
| 4 | RAD-CITY-01 | Stadtrad „Promenade“ 7-Gang | 3 | 5 |
| 5 | RAD-EB-02 | E-Bike „Kanal“ Mittelmotor 500 Wh | 1 | 3 |
ca) Erstelle einen Algorithmus für die Prozedur sortiereNachbestellung(artikel: Artikel[]), die das übergebene Array nach Fehlmenge absteigend sortiert. Verwende einen selbst geschriebenen Sortieralgorithmus und nenne das gewählte Verfahren. (10 Punkte)
Verfahren: Bubblesort
Prozedur sortiereNachbestellung(artikel: Artikel[])
n: integer := laenge(artikel)
zähle i von 0 bis n - 2
zähle j von 0 bis n - 2 - i
fehlLinks: integer := artikel[j].getMindestbestand() - artikel[j].getLagerbestand()
fehlRechts: integer := artikel[j + 1].getMindestbestand() - artikel[j + 1].getLagerbestand()
wenn fehlLinks < fehlRechts dann
hilf: Artikel := artikel[j]
artikel[j] := artikel[j + 1]
artikel[j + 1] := hilf
Ende wenn
Ende zähle
Ende zähle
Ende sortiereNachbestellung
Bewertung:
Verfahren genannt: 1 Punkt
äußere Schleife mit richtiger Anzahl Durchläufe: 2 Punkte
innere Schleife mit Grenze ohne Zugriff hinter das Array-Ende: 2 Punkte
Fehlmenge für beide Artikel richtig berechnet (über die Getter): 2 Punkte
Vergleich in der richtigen Richtung (absteigend): 1 Punkt
Tausch ganzer Objekte mit Hilfsvariable: 2 Punkte
Selectionsort oder Insertionsort sind ebenso richtig. Die Optimierung - i in der inneren Schleife ist nicht verlangt.
cb) Gib die Reihenfolge der Artikelnummern an, die Dein Algorithmus für die Liste vom 26.10.2026 liefert. (2 Punkte)
| Platz | Artikelnummer | Fehlmenge |
|---|---|---|
| 1 | BRE-BEL-02 | 11 |
| 2 | LIC-SET-01 | 7 |
| 3 | BRE-HYD-01 | 3 |
| 4 | KET-11-E | 2 |
| 5 | RAD-CITY-01 | 2 |
| 6 | RAD-EB-02 | 2 |
Der Bubblesort aus ca) tauscht nur bei echtem Kleiner (<). Die drei Artikel mit der Fehlmenge 2 behalten deshalb ihre bisherige Reihenfolge (nach Artikelnummer).
Bewertung: Reihenfolge nach Fehlmenge 1 Punkt, Reihenfolge der gleichen Fehlmengen passend zum eigenen Algorithmus 1 Punkt (bei Selectionsort kann sie abweichen).
d) Das Händlerportal ist in Java geschrieben. Ein Sortierkriterium ist dort ein Objekt vom Typ Comparator<Artikel>: Seine Methode compare(a, b) liefert einen negativen Wert, wenn a vor b gehört, 0 bei Gleichstand und einen positiven Wert, wenn a hinter b gehört. Eine Methode mit zwei Artikel-Parametern und int-Rückgabe kann per Methodenreferenz als Comparator<Artikel> übergeben werden; im Pseudocode übergibst Du einfach ihren Namen. Jonas hat für die Preisansicht (günstigster Artikel zuerst) diese Methode geschrieben:
int vergleichePreis(Artikel a, Artikel b) {
return (int) (a.getNettoPreis() - b.getNettoPreis());
}Im Test stehen das Rahmenschloss SCH-RAH-01 (41,18 €) und ein neues Faltschloss für 41,95 € in der Preisansicht mal so, mal so herum – je nachdem, in welcher Reihenfolge sie aus der Datenbank kommen.
da) Erkläre die Ursache an diesem Testfall und schreibe eine korrigierte Fassung von vergleichePreis. (6 Punkte)
Ursache (2 Punkte): Die Differenz 41,18 − 41,95 = −0,77 ist eine Kommazahl; die Umwandlung nach int schneidet die Nachkommastellen ab und liefert 0. Die beiden Schlösser gelten damit als gleich teuer, der Sortieralgorithmus lässt sie in der Reihenfolge stehen, in der sie ankommen. Das betrifft jeden Preisunterschied unter 1 €.
Korrigierte Fassung:
Funktion vergleichePreis(a: Artikel, b: Artikel): integer
wenn a.getNettoPreis() < b.getNettoPreis() dann
Rückgabe -1
Ende wenn
wenn a.getNettoPreis() > b.getNettoPreis() dann
Rückgabe 1
Ende wenn
Rückgabe 0
Ende vergleichePreis
Bewertung: Fall „a günstiger“ 2 Punkte, Fall „a teurer“ 1 Punkt, Fall „gleich“ 1 Punkt. Statt -1 und 1 sind beliebige negative bzw. positive Werte richtig. In Java ist auch return Double.compare(a.getNettoPreis(), b.getNettoPreis()); richtig.
e) Bevor das Portal die Sortierfunktion der Bibliothek nutzt, möchte Cem Sarıkaya an einem eigenen Algorithmus sehen, wie ein Comparator arbeitet.
ea) Erstelle die Prozedur sortiereMit(artikel: Artikel[], vergleich: Comparator<Artikel>), die das Array mit Insertionsort sortiert. Die Reihenfolge zweier Artikel darf nur über vergleich.compare(…) bestimmt werden. (8 Punkte)
Prozedur sortiereMit(artikel: Artikel[], vergleich: Comparator<Artikel>)
zähle i von 1 bis laenge(artikel) - 1
neu: Artikel := artikel[i]
j: integer := i - 1
solange j >= 0 und vergleich.compare(artikel[j], neu) > 0
artikel[j + 1] := artikel[j] // größeres Element rückt nach hinten
j := j - 1
Ende solange
artikel[j + 1] := neu
Ende zähle
Ende sortiereMit
Bewertung:
äußere Schleife ab dem zweiten Element bis zum letzten: 2 Punkte
einzusortierendes Element zwischenspeichern: 1 Punkt
innere Schleife mit Grenze
j >= 0vor dem Zugriff: 2 PunkteVergleich nur über
comparemit> 0(der linke Artikel gehört hinter den neuen): 2 PunkteVerschieben und Einsetzen an
j + 1: 1 Punkt
Mit > 0 rückt der neue Artikel nicht an gleichwertigen vorbei; das Verfahren bleibt stabil.
eb) Im fertigen Portal liegt das Sortiment in der Java-Liste List<Artikel> sortiment, und die Bibliothek übernimmt das Sortieren. Gib je eine Anweisung an, die die Liste aufsteigend bzw. absteigend nach Nettopreis sortiert. Verwende Comparator.comparingDouble und reversed(). Ein Export-Skript erledigt dasselbe in Python; gib dort die beiden Aufrufe mit sorted und key an. (4 Punkte)
sortiment.sort(Comparator.comparingDouble(Artikel::getNettoPreis)); // aufsteigend
sortiment.sort(Comparator.comparingDouble(Artikel::getNettoPreis).reversed()); // absteigendaufsteigend = sorted(sortiment, key=lambda a: a.getNettoPreis())
absteigend = sorted(sortiment, key=lambda a: a.getNettoPreis(), reverse=True)Je Anweisung 1 Punkt. Gleichwertig in Java: sortiment.sort(this::vergleichePreis) mit der korrigierten Methode aus da) bzw. sortiment.sort((a, b) -> vergleichePreis(b, a)) für absteigend. Python übergibt keine Vergleichsfunktion, sondern eine Schlüsselfunktion, die für jedes Element den Sortierwert liefert; eine Vergleichsfunktion wie in da) lässt sich mit functools.cmp_to_key umwandeln. Beide Bibliotheken sortieren stabil.
f) Katarzyna Nowak, Einkäuferin eines Fachhändlers, wünscht sich im Portal eine Ansicht, die nach Kategorie alphabetisch sortiert ist und innerhalb einer Kategorie die teuersten Artikel zuerst zeigt. Zum Vergleich zweier Zeichenketten gibt es die Funktion vergleicheText(s1: Text, s2: Text) : int (negativ, wenn s1 alphabetisch vor s2 steht, 0 bei Gleichheit, sonst positiv).
| Artikelnummer | Kategorie | Nettopreis (Listenpreis) |
|---|---|---|
| RAD-CITY-01 | Stadträder | 671,43 € |
| RAD-EB-02 | E-Bikes | 2.520,17 € |
| LIC-SET-01 | Beleuchtung | 75,63 € |
| BRE-HYD-01 | Bremsen | 133,61 € |
| BRE-BEL-02 | Bremsen | 18,40 € |
| SCH-BUE-01 | Schlösser | 62,18 € |
| SCH-RAH-01 | Schlösser | 41,18 € |
| KET-11-E | Antrieb | 32,90 € |
fa) Erstelle die Vergleichsfunktion vergleicheKategoriePreis(a: Artikel, b: Artikel) : int für diese Ansicht. Du darfst vergleichePreis aus d) verwenden. (5 Punkte)
Funktion vergleicheKategoriePreis(a: Artikel, b: Artikel): integer
ergebnis: integer := vergleicheText(a.getKategorie(), b.getKategorie())
wenn ergebnis <> 0 dann
Rückgabe ergebnis // unterschiedliche Kategorien
Ende wenn
Rückgabe vergleichePreis(b, a) // gleiche Kategorie: teurer zuerst
Ende vergleicheKategoriePreis
Bewertung: Vergleich der Kategorien mit vergleicheText 2 Punkte, zweites Kriterium nur bei gleicher Kategorie 1 Punkt, Preis in absteigender Richtung (Argumente vertauscht oder Vorzeichen umgekehrt) 2 Punkte. Eine Lösung ohne vergleichePreis mit eigenen </>-Vergleichen ist ebenso richtig.
fb) Gib die Reihenfolge der acht Artikel an, die sortiereMit(sortiment, vergleicheKategoriePreis) aus ea) liefert. (2 Punkte)
| Platz | Kategorie | Artikelnummer | Nettopreis |
|---|---|---|---|
| 1 | Antrieb | KET-11-E | 32,90 € |
| 2 | Beleuchtung | LIC-SET-01 | 75,63 € |
| 3 | Bremsen | BRE-HYD-01 | 133,61 € |
| 4 | Bremsen | BRE-BEL-02 | 18,40 € |
| 5 | E-Bikes | RAD-EB-02 | 2.520,17 € |
| 6 | Schlösser | SCH-BUE-01 | 62,18 € |
| 7 | Schlösser | SCH-RAH-01 | 41,18 € |
| 8 | Stadträder | RAD-CITY-01 | 671,43 € |
Bewertung: Kategorien in richtiger Reihenfolge 1 Punkt, innerhalb von Bremsen und Schlösser teurer zuerst 1 Punkt.
g) Cem Sarıkaya möchte vor dem Start des Portals zwei Fragen geklärt haben.
ga) Bastian Ludwig wünscht, dass Artikel mit gleicher Fehlmenge auf der Nachbestellliste weiterhin nach Artikelnummer geordnet sind. Erläutere den Begriff „stabiles Sortierverfahren“ und begründe, ob Dein Algorithmus aus ca) diesen Wunsch erfüllt. Gib an, was sich ändert, wenn die Bedingung fehlLinks <= fehlRechts lautet. (3 Punkte)
Ein Sortierverfahren ist stabil, wenn Elemente mit gleichem Sortierschlüssel nach dem Sortieren in derselben Reihenfolge stehen wie vorher. (1 Punkt)
Bubblesort mit
<tauscht nur Nachbarn mit echt unterschiedlicher Fehlmenge; gleiche Fehlmengen werden nie gegeneinander getauscht. Weil die Liste nach Artikelnummer sortiert ankommt, bleibt diese Ordnung bei Gleichstand erhalten – der Wunsch ist erfüllt. (1 Punkt; bei Selectionsort: nicht garantiert, weil der Tausch ein Element über ein gleichwertiges hinweg verschieben kann)Mit
<=werden auch gleiche Nachbarn getauscht: Das Ergebnis ist weiterhin nach Fehlmenge sortiert, aber nicht mehr stabil (KET-11-E, RAD-CITY-01 und RAD-EB-02 erscheinen in umgekehrter Reihenfolge), und es wird unnötig getauscht. (1 Punkt)
Unabhängig vom Verfahren erfüllt eine mehrstufige Vergleichsfunktion (Fehlmenge absteigend, bei Gleichstand Artikelnummer aufsteigend) den Wunsch sicher.
gb) Für den Jahresabschluss sollen alle 4.800 Bestellpositionen des Jahres sortiert werden. Berechne, wie viele Vergleiche Bubblesort im ungünstigsten Fall benötigt und wie lange das bei 1 µs je Vergleich dauert. Vergleiche das Ergebnis mit einem Verfahren, das rund n \cdot \log_2 n Vergleiche benötigt. (4 Punkte)
Geg.: n = 4.800 Bestellpositionen; t_V = 1 µs je Vergleich
Ges.: Anzahl Vergleiche V, Dauer t (Bubblesort und n · log2 n)
\text{I: } V = \frac{n \cdot (n-1)}{2} \qquad \text{II: } t = V \cdot t_V
I in II:
t = \frac{n \cdot (n-1)}{2} \cdot t_V = \frac{4800 \cdot 4799}{2} \cdot 1\,\mathrm{\mu s} = 11\,517\,600\,\mathrm{\mu s} \approx \underline{\underline{11{,}518\,\mathrm{s}}}
Bubblesort benötigt also 11.517.600 Vergleiche.
Schnelles Verfahren:
V_{schnell} = n \cdot \log_2 n = 4800 \cdot \log_2 4800 \approx 4800 \cdot 12{,}229 \approx 58\,698
t_{schnell} = V_{schnell} \cdot t_V \approx 58\,698 \cdot 1\,\mathrm{\mu s} \approx \underline{\underline{0{,}059\,\mathrm{s}}}
Das schnelle Verfahren braucht weniger als ein Hundertstel der Zeit (Faktor rund 196). Bubblesort hat eine quadratische Laufzeit (O(n^2)); für große Datenmengen nimmt man deshalb ORDER BY in der Datenbank oder die Sortierfunktion der Programmiersprache.
Bewertung: Anzahl Vergleiche 1 Punkt, Dauer Bubblesort 1 Punkt, Vergleichswerte des schnellen Verfahrens 1 Punkt, Schlussfolgerung 1 Punkt.
Aufgabe 3.2: Vorschlagsliste, Tagesplan und Raumranking für ein Barcamp (Profilkompetenz)
(ca. 42 min Bearbeitungszeit)
Am Ratz und Rübe Berufskolleg (RRB) in Bielefeld findet am Samstag, 13.03.2027, das Barcamp „Lernen.Digital.Leben 2027“ statt. Du bist Auszubildende*r im Orga-Team und entwickelst mit Mia Schröder die Planungssoftware weiter. Dimitrios Papadopoulos leitet die Organisation.
Jede eingereichte Session wird von zwei Personen des Orga-Teams mit 1 bis 10 Punkten begutachtet. Gehen die beiden Gutachten weit auseinander, bespricht das Orga-Team die Session lieber noch einmal, bevor sie auf die Vorschlagsliste kommt. Die Planungssoftware stellt die Einreichungen als Objekte der Klasse Einreichung bereit:
Einreichung
- nr: int
- titel: Text
- format: Text // "Vortrag", "Workshop", "Diskussion" oder "Tutorial"
- status: Text // "eingereicht", "angenommen", "abgelehnt" oder "zurueckgezogen"
- punkteSchnitt: real // Mittelwert der Gutachten, -1 wenn noch kein Gutachten vorliegt
- abweichung: real // Unterschied der beiden Gutachten in Punkten, -1 ohne Gutachten
+ getNr(): int
+ getTitel(): Text
+ getFormat(): Text
+ getStatus(): Text
+ getPunkteSchnitt(): real
+ getAbweichung(): real
Das Array einreichungen ist nach dem Einreichungsdatum sortiert. Stand 25.11.2026 (Auszug):
| Index | Nr. | Titel | Format | Status | Punkteschnitt | Abweichung |
|---|---|---|---|---|---|---|
| 0 | 5 | Datenschutz im Schulalltag – Mythen und Fakten | Diskussion | eingereicht | 7,5 | 1 |
| 1 | 7 | Krypto-Trading für Einsteiger | Vortrag | abgelehnt | 2,0 | 0 |
| 2 | 32 | Git für Einsteiger*innen | Workshop | eingereicht | 8,5 | 3 |
| 3 | 33 | Podcasts im Unterricht | Vortrag | eingereicht | 6,0 | 2 |
| 4 | 34 | Smart Home selbst bauen mit MQTT | Workshop | eingereicht | 8,5 | 1 |
| 5 | 35 | Ausbildung in Teilzeit | Diskussion | eingereicht | -1 | -1 |
| 6 | 36 | 3D-Druck im Werkstattunterricht | Workshop | eingereicht | 9,0 | 4 |
| 7 | 37 | Prompting für Auszubildende | Tutorial | eingereicht | 6,5 | 1 |
| 8 | 38 | Linux auf alten Laptops | Workshop | zurueckgezogen | 7,0 | 0 |
a) Für die Sitzungen des Orga-Teams soll eine Vorschlagsliste entstehen. Die Funktion vorschlagsliste(einreichungen: Einreichung[], mindestpunkte: real, maxAbweichung: real) : Einreichung[] gibt ein neues Array zurück. Es enthält nur Einreichungen, die noch den Status „eingereicht“ haben, mindestens mindestpunkte erreichen und deren Gutachten höchstens maxAbweichung Punkte auseinanderliegen. Das Array ist genau so lang, wie Einreichungen passen. Oben stehen die Sessions mit dem höchsten Punkteschnitt; bei gleichem Schnitt kommt die Session zuerst, bei der sich die Gutachten einiger sind. Neue Arrays legst Du mit neues Einreichung-Array der Länge n an; eine fertige Sortierfunktion der Programmiersprache verwendest Du hier nicht.
Beispiel: vorschlagsliste(einreichungen, 7.0, 3) liefert die Einreichungen 34, 32 und 5 in dieser Reihenfolge.
aa) Stelle den Algorithmus der Funktion als Struktogramm dar und nenne das Sortierverfahren, das Du verwendest. (12 Punkte)
Verfahren: Bubblesort
Dieselbe Lösung in Pseudocode:
Funktion vorschlagsliste(einreichungen: Einreichung[], mindestpunkte: double, maxAbweichung: double): Einreichung[]
// 1. passende Einreichungen zählen
anzahl: integer := 0
zähle i von 0 bis laenge(einreichungen) - 1
e: Einreichung := einreichungen[i]
wenn e.getStatus() = "eingereicht" und e.getPunkteSchnitt() >= mindestpunkte
und e.getAbweichung() <= maxAbweichung dann
anzahl := anzahl + 1
Ende wenn
Ende zähle
// 2. Array passender Länge anlegen und füllen
liste := neues Einreichung-Array der Länge anzahl
k: integer := 0
zähle i von 0 bis laenge(einreichungen) - 1
e: Einreichung := einreichungen[i]
wenn e.getStatus() = "eingereicht" und e.getPunkteSchnitt() >= mindestpunkte
und e.getAbweichung() <= maxAbweichung dann
liste[k] := e
k := k + 1
Ende wenn
Ende zähle
// 3. Bubblesort: Schnitt absteigend, bei Gleichstand Abweichung aufsteigend
zähle a von 0 bis anzahl - 2
zähle j von 0 bis anzahl - 2 - a
x: Einreichung := liste[j]
y: Einreichung := liste[j + 1]
wenn x.getPunkteSchnitt() < y.getPunkteSchnitt()
oder (x.getPunkteSchnitt() = y.getPunkteSchnitt() und x.getAbweichung() > y.getAbweichung()) dann
liste[j] := y
liste[j + 1] := x
Ende wenn
Ende zähle
Ende zähle
Rückgabe liste
Ende vorschlagsliste
Einreichungen ohne Gutachten (-1) fallen bei jeder sinnvollen Mindestpunktzahl heraus. Weil 32 und 34 denselben Schnitt haben, entscheidet die Abweichung: 34 (1 Punkt Unterschied) steht vor 32 (3 Punkte), obwohl 32 früher eingereicht wurde. 36 hat zwar den höchsten Schnitt, die Gutachten liegen aber 4 Punkte auseinander.
Bewertung:
- Verfahren genannt: 1 Punkt
- passende Einreichungen zählen: 2 Punkte
- Filterbedingung mit allen drei Teilen und UND: 2 Punkte
- Array mit passender Länge anlegen und mit eigenem Zähler füllen: 2 Punkte
- Sortierschleifen mit korrekten Grenzen: 2 Punkte
- zweistufiger Vergleich (Schnitt absteigend, bei Gleichstand Abweichung aufsteigend): 2 Punkte
- Tausch und Rückgabe: 1 Punkt
Andere Wege sind richtig, z. B. sortiertes Einfügen schon beim Füllen oder eine eigene Vergleichsfunktion für die beiden Kriterien.
ab) Gib an, welche Einreichungen in welcher Reihenfolge vorschlagsliste(einreichungen, 6.0, 2) liefert. (2 Punkte)
34, 5, 37, 33 (8,5 / 7,5 / 6,5 / 6,0). 32 und 36 fallen wegen der Abweichung heraus, 7 und 38 wegen des Status, 35 mangels Gutachten. 1 Punkt für die richtige Auswahl, 1 Punkt für die Reihenfolge.
b) Für eine Übersicht kopiert Mia die Einreichungen in eine Liste, die beim Entfernen schrumpft: liste.entferne(i) entfernt das Element an Position i, alle Elemente dahinter rücken um eins nach vorne (in Java liste.remove(i), in Python del liste[i]). Mit dieser Prozedur möchte sie alle Einreichungen entfernen, die nicht mehr den Status „eingereicht“ haben:
Prozedur nurOffene(liste: Liste von Einreichung)
n := laenge(liste)
zähle i von 0 bis n - 1
wenn liste[i].getStatus() <> "eingereicht" dann
liste.entferne(i)
Ende wenn
Ende zähle
Ende nurOffene
ba) Mia testet mit einer Liste aus den Einreichungen 38 (zurückgezogen), 7 (abgelehnt), 32 (eingereicht) und 35 (eingereicht). Ermittle mit einem Schreibtischtest, was passiert, und beschreibe die beiden Fehler. (3 Punkte)
n wird einmal zu Beginn auf 4 gesetzt.
| i | liste[i] |
Aktion | Liste danach |
|---|---|---|---|
| 0 | 38 (zurückgezogen) | entfernen | 7, 32, 35 |
| 1 | 32 (eingereicht) | – | 7, 32, 35 |
| 2 | 35 (eingereicht) | – | 7, 32, 35 |
| 3 | existiert nicht | Zugriff hinter das Listenende | Laufzeitfehler |
- Fehler 1: Nach dem Entfernen rückt 7 auf Position 0 nach,
iwird trotzdem auf 1 erhöht. Einreichung 7 wird nie geprüft und bleibt in der Liste. (1 Punkt) - Fehler 2: Die Obergrenze
n - 1wurde vor dem Entfernen berechnet. Weil die Liste kürzer geworden ist, greift die Schleife beii = 3auf ein Element zu, das es nicht mehr gibt (Python:IndexError). (1 Punkt)
Schreibtischtest: 1 Punkt.
bb) Korrigiere die Prozedur. (3 Punkte)
Prozedur nurOffene(liste: Liste von Einreichung)
i: integer := 0
solange i < laenge(liste) // Länge in jedem Durchlauf neu
wenn liste[i].getStatus() <> "eingereicht" dann
liste.entferne(i) // nächstes Element steht jetzt auf i
sonst
i := i + 1
Ende wenn
Ende solange
Ende nurOffene
Bewertung: Schleife mit aktueller Länge 1 Punkt, Index nur ohne Entfernen erhöhen 2 Punkte. Ebenso richtig: Durchlauf von hinten nach vorne (zähle i von laenge(liste) - 1 bis 0 Schrittweite -1) – dann verschieben sich nur bereits geprüfte Elemente. In Python geht es auch ohne Entfernen im Durchlauf: liste[:] = [e for e in liste if e.getStatus() == "eingereicht"].
c) Die Infomonitore zeigen den Tagesplan des Barcamps. Er liegt im Array plan: Eintrag[] mit 48 Plätzen; belegt sind die Positionen 0 bis anzahl - 1, aufsteigend sortiert nach Beginn. Die Klasse Eintrag bietet getBeginn(): int (Minuten seit Mitternacht, z. B. 11:00 Uhr = 660), getRaum(): Text und getTitel(): Text. Nach dem Barcamp-Prinzip werden am Morgen im Plenum spontan weitere Sessions ergänzt. Jede neue Session soll sofort an der richtigen Stelle im Plan stehen; Sessions mit gleichem Beginn erscheinen in der Reihenfolge, in der sie eingetragen wurden.
| Index | Beginn | Raum | Titel |
|---|---|---|---|
| 0 | 600 | A.001 | KI-Assistenten im Unterricht – was geht, was nicht? |
| 1 | 660 | C.110 | Reparieren statt wegwerfen: Laptops retten |
| 2 | 765 | B.201 | Barrierefreie Videos: Untertitel und Gebärdensprache |
| 3 | 825 | B.202 | Escape-Room mit Mikrocontrollern |
| 4 | 885 | B.202 | Barrierefreie Webseiten mit HTML und ARIA |
ca) Erstelle einen Algorithmus für die Funktion fuegeEin(plan: Eintrag[], anzahl: int, neu: Eintrag) : int, die den Eintrag neu an der richtigen Stelle einfügt und die neue Anzahl zurückgibt. Ist der Plan voll, soll nichts eingefügt und -1 zurückgegeben werden. (8 Punkte)
Funktion fuegeEin(plan: Eintrag[], anzahl: integer, neu: Eintrag): integer
wenn anzahl >= laenge(plan) dann
Rückgabe -1
Ende wenn
// Position suchen: hinter alle Einträge, die nicht später beginnen
pos: integer := 0
solange pos < anzahl und plan[pos].getBeginn() <= neu.getBeginn()
pos := pos + 1
Ende solange
// Einträge ab pos von hinten nach vorne um eins verschieben
k: integer := anzahl
solange k > pos
plan[k] := plan[k - 1]
k := k - 1
Ende solange
plan[pos] := neu
Rückgabe anzahl + 1
Ende fuegeEin
Beispiel: Die spontane Session „Mastodon für Schulen“ um 11:00 Uhr (660) in A.105 wird an Position 2 eingefügt – hinter die Reparatur-Session, die ebenfalls um 11:00 Uhr beginnt. Die Funktion gibt 6 zurück; die Einträge mit Beginn 765, 825 und 885 stehen nun auf den Positionen 3 bis 5.
Bewertung:
Prüfung auf vollen Plan mit Rückgabe -1: 1 Punkt
Positionssuche mit Grenze
pos < anzahlvor dem Zugriff: 2 Punkte<=für die Reihenfolge bei gleichem Beginn: 1 PunktVerschieben von hinten nach vorne: 2 Punkte
Einfügen an
posund Rückgabeanzahl + 1: 2 Punkte
cb) Erläutere, warum die Einträge von hinten nach vorne verschoben werden müssen. (2 Punkte)
Beim Verschieben nach hinten wird jeweils die nächste Position überschrieben. Beginnt man hinten, ist die Zielposition anzahl frei bzw. bereits kopiert, sodass kein Eintrag verloren geht (1 Punkt). Beginnt man vorne mit plan[pos + 1] := plan[pos], wird der Eintrag auf pos + 1 überschrieben, bevor er selbst verschoben wurde; im nächsten Schritt wird der bereits kopierte Eintrag weiterkopiert – am Ende steht derselbe Eintrag auf allen Positionen ab pos (1 Punkt).
cc) Nenne das Sortierverfahren, das entsteht, wenn alle Sessions des Tages nacheinander mit fuegeEin in einen leeren Plan eingetragen werden. (1 Punkt)
Insertionsort (Sortieren durch Einfügen).
d) Dimitrios möchte sehen, welche Räume nach dem Anmeldestand voraussichtlich am stärksten ausgelastet sind. Die Planungssoftware liefert die durchschnittliche Auslastung über alle Slots in Prozent im Array auslastung: real[]; der Index eines Raums ist um 1 kleiner als seine raum_id.
| Index | raum_id | Raum | auslastung[i] |
|---|---|---|---|
| 0 | 1 | A.001 Aula | 62,5 |
| 1 | 2 | A.104 | 93,8 |
| 2 | 3 | A.105 | 62,5 |
| 3 | 4 | B.012 Mensa | 31,7 |
| 4 | 5 | B.201 IT-Labor 1 | 87,5 |
| 5 | 6 | B.202 IT-Labor 2 | 76,8 |
| 6 | 7 | C.110 Elektrowerkstatt | 45,8 |
| 7 | 8 | C.020 Bibliothek | 30,0 |
Die Funktion auslastungsranking(auslastung: real[]) : int[] soll ein Array ranking mit den raum_ids zurückgeben, geordnet nach Auslastung absteigend. Das Array auslastung bleibt dabei unverändert: Die Funktion legt ranking mit den Werten 1 bis n an und sortiert nur diese Nummern; die Auslastung eines Eintrags liest sie über auslastung[ranking[j] - 1] nach. Zum Sortieren soll folgendes Verfahren verwendet werden: Für jede Position i von der ersten bis zur vorletzten wird im Bereich von Position i bis zum Ende der Raum mit der höchsten Auslastung gesucht und mit Position i getauscht.
da) Stelle den Algorithmus der Funktion in Pseudocode, als Struktogramm oder als Programmablaufplan dar. (9 Punkte)
Funktion auslastungsranking(auslastung: double[]): integer[]
n: integer := laenge(auslastung)
ranking := neues integer-Array der Länge n
zähle i von 0 bis n - 1
ranking[i] := i + 1 // raum_id
Ende zähle
zähle i von 0 bis n - 2
posMax: integer := i
zähle j von i + 1 bis n - 1
wenn auslastung[ranking[j] - 1] > auslastung[ranking[posMax] - 1] dann
posMax := j
Ende wenn
Ende zähle
hilf: integer := ranking[i] // nur die raum_ids tauschen
ranking[i] := ranking[posMax]
ranking[posMax] := hilf
Ende zähle
Rückgabe ranking
Ende auslastungsranking
Ergebnis für die Beispieldaten: ranking = [2, 5, 6, 1, 3, 7, 4, 8] (A.104 mit 93,8 % vorne, die Bibliothek mit 30,0 % hinten).
Bewertung:
Array
rankinganlegen und miti + 1füllen: 2 Punkteäußere Schleife bis zur vorletzten Position: 1 Punkt
Suche des Maximums ab Position
imit Merken der Position: 2 PunkteVergleich über die nachgeschlagene Auslastung (
auslastung[ranking[j] - 1]): 2 PunkteTausch der beiden Nummern über eine Hilfsvariable: 1 Punkt
Rückgabe: 1 Punkt
Wer die Auslastung über auslastung[j] statt über ranking[j] nachschlägt, vergleicht nach dem ersten Tausch die falschen Räume.
db) Dimitrios möchte, dass Räume mit gleicher Auslastung nach raum_id aufsteigend erscheinen. Gib den Inhalt von ranking nach dem zweiten Tausch (also nach i = 1) an und begründe damit, ob das vorgegebene Verfahren seinen Wunsch garantiert. Nenne eine Abhilfe. (3 Punkte)
Nach
i = 0(Tausch Position 0 mit Position 1): 2, 1, 3, 4, 5, 6, 7, 8. Nachi = 1(Tausch Position 1 mit Position 4): 2, 5, 3, 4, 1, 6, 7, 8. (1 Punkt)Raum 3 steht jetzt vor Raum 1, obwohl beide 62,5 % haben: Der Tausch hat Raum 1 über den gleichwertigen Raum 3 hinweg nach hinten geschoben. Dass am Ende doch 1 vor 3 steht, ist bei diesen Daten Zufall. Das Verfahren (Selectionsort) ist nicht stabil und garantiert den Wunsch nicht. (1 Punkt)
Abhilfe: bei gleicher Auslastung zusätzlich die Nummer vergleichen (
… oder (gleiche Auslastung und ranking[j] < ranking[posMax])) oder ein stabiles Verfahren wie Bubblesort mit<verwenden. (1 Punkt)
e) Emre Aksoy fragt, warum die Vorschlagsliste aus a) im Programm sortiert wird – die Daten stammen doch ohnehin aus der Datenbank barcamp. Erläutere zwei Vorteile einer Sortierung mit ORDER BY in der Datenbankabfrage und eine Situation, in der die Sortierung im Programm sinnvoll oder nötig ist. (3 Punkte)
Vorteile von ORDER BY (je 1 Punkt, zwei verlangt):
Die Datenbank nutzt schnelle Sortierverfahren und ggf. Indizes; der eigene Code ist kürzer und weniger fehleranfällig.
Filtern (
WHERE) und Sortieren geschehen zusammen, es werden nur die benötigten Datensätze in der richtigen Reihenfolge übertragen.Die Reihenfolge ist für alle Anwendungen, die die Abfrage nutzen, einheitlich (z. B. auch mit Zweitkriterium
ORDER BY punkte_schnitt DESC, abweichung).
Sortierung im Programm (1 Punkt, eine verlangt):
Die Daten kommen nicht (direkt) aus der Datenbank, z. B. über eine API, von einem Gerät oder aus einer Datei.
Das Kriterium wird erst im Programm berechnet oder von den Nutzenden gewählt (wechselnde Sortierung im Portal über eine Vergleichsfunktion), ohne die Daten neu abzufragen.
Die Liste ändert sich laufend im Speicher (Tagesplan mit spontanen Sessions), sodass sortiertes Einfügen günstiger ist als eine neue Abfrage.
Links und weitere Informationen
Hinweis zur Nachnutzung als Open Educational Resource (OER)
Dieser Artikel und seine Texte, Bilder, Grafiken, Code und sonstiger Inhalt sind - sofern nicht anders angegeben - lizenziert unter CC BY 4.0. Nennung gemäß TULLU-Regel bitte wie folgt: “Übungsaufgaben zu Sortieralgorithmen und Vergleichsfunktionen” von oer-informatik.de (H. Stein), Lizenz: CC BY 4.0. Der Artikel wurde unter https://oer-informatik.de/sortieralgorithmen-uebungsaufgaben veröffentlicht, die Quelltexte sind in weiterverarbeitbarer Form verfügbar im Repository unter https://gitlab.com/oer-informatik/algorithmik/algorithmen. Erstellt mit KI-Assistenz; von mir umfassend redaktionell überarbeitet, geprüft und freigegeben. Stand: 29.10.2026.
[Kommentare zum Artikel lesen, schreiben] / [Artikel teilen] / [gitlab-Issue zum Artikel schreiben]
