Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen der Seite angezeigt.
| Beide Seiten, vorherige Überarbeitung Vorherige Überarbeitung Nächste Überarbeitung | Vorherige Überarbeitung | ||
| gf_informatik:suchen_und_sortieren:sortieren [2025-03-11 07:54] – [C7 (Herausforderung): Quicksort] hof | gf_informatik:suchen_und_sortieren:sortieren [2026-05-02 14:12] (aktuell) – [C7 (Herausforderung): Quicksort] hof | ||
|---|---|---|---|
| Zeile 41: | Zeile 41: | ||
| * Wie gehts du vor? | * Wie gehts du vor? | ||
| * Wieviele Vergleiche sind nötig? | * Wieviele Vergleiche sind nötig? | ||
| - | |||
| - | |||
| ### Sortieralgorithmen | ### Sortieralgorithmen | ||
| Sortieren ist eines der Grundprobleme der Informatik, und es existieren [[http:// | Sortieren ist eines der Grundprobleme der Informatik, und es existieren [[http:// | ||
| * Laufzeit: wieviele Operationen sind nötig, um eine Liste der Länge `n` zu sortieren? | * Laufzeit: wieviele Operationen sind nötig, um eine Liste der Länge `n` zu sortieren? | ||
| - | * Vergleiche | + | * Vergleich |
| * Austausch von zwei Elementen | * Austausch von zwei Elementen | ||
| * Entfernung oder Einfügen eines Elements | * Entfernung oder Einfügen eines Elements | ||
| Zeile 53: | Zeile 51: | ||
| * In-Place: Wird abgesehen von der zu sortierenden Liste nur noch eine konstante Speicherkapazität verwendet, oder wird beispielsweise eine neue Liste aufgebaut, die den Speicherbedarf verdoppelt? | * In-Place: Wird abgesehen von der zu sortierenden Liste nur noch eine konstante Speicherkapazität verwendet, oder wird beispielsweise eine neue Liste aufgebaut, die den Speicherbedarf verdoppelt? | ||
| * Wenn du beim Sortieren nur Elemente vertauschst, | * Wenn du beim Sortieren nur Elemente vertauschst, | ||
| + | |||
| #### Aufgabe C2: Sortierung Prüfen | #### Aufgabe C2: Sortierung Prüfen | ||
| Zeile 67: | Zeile 66: | ||
| - | <nodisp 1> | + | <bottom-exercise id=" |
| - | + | < | |
| - | ++++Lösung| | + | def is_sorted(l): |
| - | <code python> | + | """ |
| + | </ | ||
| + | <template data-type=" | ||
| def is_sorted(l): | def is_sorted(l): | ||
| for index in range(len(l) - 1): | for index in range(len(l) - 1): | ||
| Zeile 81: | Zeile 82: | ||
| print(is_sorted([' | print(is_sorted([' | ||
| print(is_sorted([' | print(is_sorted([' | ||
| - | </code> | + | </template> |
| - | ++++ | + | < |
| - | </nodisp> | + | assert is_sorted([' |
| + | assert not is_sorted([' | ||
| + | </ | ||
| + | </bottom-exercise> | ||
| Zeile 100: | Zeile 104: | ||
| Hier dasselbe für [[gf_informatik: | Hier dasselbe für [[gf_informatik: | ||
| - | |||
| #### Aufgabe C4: Selection Sort anwenden | #### Aufgabe C4: Selection Sort anwenden | ||
| Du hast folgende beiden Listen: | Du hast folgende beiden Listen: | ||
| + | |||
| <code python> | <code python> | ||
| obstsorten = [" | obstsorten = [" | ||
| Zeile 110: | Zeile 114: | ||
| - Schreibe eine Funktion '' | - Schreibe eine Funktion '' | ||
| - | - Schreibe danach eine Funktion '' | + | - Schreibe danach eine Funktion '' |
| - Kopiere die beiden Listen in deinen Code. | - Kopiere die beiden Listen in deinen Code. | ||
| - Erweitere deinen Code, sodass du eine Obstsorte festlegen kannst und am Ende eine der folgenden beiden Nachrichten ausgegeben wird. | - Erweitere deinen Code, sodass du eine Obstsorte festlegen kannst und am Ende eine der folgenden beiden Nachrichten ausgegeben wird. | ||
| Zeile 117: | Zeile 121: | ||
| - | + | <bottom-exercise id=" | |
| - | <nodisp 2> | + | <template data-type=" |
| - | ++++Lösung| | + | obstsorten = ["Kirsche", "Apfel", "Banane", " |
| - | <code python> | + | |
| - | obstsorten = ["Apfel", "Banane", "Kirsche", " | + | |
| farben = [" | farben = [" | ||
| + | </ | ||
| + | < | ||
| def find_min(l): | def find_min(l): | ||
| min_index = 0 | min_index = 0 | ||
| Zeile 154: | Zeile 157: | ||
| right = middle - 1 | right = middle - 1 | ||
| return None | return None | ||
| + | |||
| + | obstsorten = [" | ||
| + | farben = [" | ||
| mein_obst = " | mein_obst = " | ||
| Zeile 159: | Zeile 165: | ||
| mein_index = binary_search(obstsorten_sortiert, | mein_index = binary_search(obstsorten_sortiert, | ||
| if mein_index is None: | if mein_index is None: | ||
| - | print(" | + | print(f"Die Obstsorte {mein_obst} wurde nicht gefunden." |
| else: | else: | ||
| - | print(" | + | print(f"Die Obstsorte {mein_obst} hat die Farbe {farben[mein_index]}.") |
| - | </code> | + | </template> |
| - | ++++ | + | </bottom-exercise> |
| - | </nodisp> | + | |
| #### C5 (Zusatzaufgabe): | #### C5 (Zusatzaufgabe): | ||
| Der Algorithmus wird [[gf_informatik: | Der Algorithmus wird [[gf_informatik: | ||
| - | #### C6 (Herausforderung): | ||
| - | _Selection Sort_ ist **in-place** | + | #### C6 (Herausforderung): Laufzeit-Analyse |
| - | Aber wie berechnen wir die Laufzeit des Algorithmus? | + | Wie berechnen wir die Laufzeit des Selection-Sort-Algorithmus? |
| - | * An jeder Position | + | * Um das Minimum zu finden, |
| * Für die Position `0` sind das `n-1` Vergleiche | * Für die Position `0` sind das `n-1` Vergleiche | ||
| * Für die Position `1` sind es `n-2` | * Für die Position `1` sind es `n-2` | ||
| * ... | * ... | ||
| * Für die Position `n-2` ist es ein Vergleich | * Für die Position `n-2` ist es ein Vergleich | ||
| - | * Für die Position `n-1` sind es null Vergleiche | + | * Für die Position `n-1` sind es null Vergleiche |
| * Im Durchschnitt sind es also $\frac{n-1}{2}$ Vergleiche pro Position. | * Im Durchschnitt sind es also $\frac{n-1}{2}$ Vergleiche pro Position. | ||
| - | * Insgesamt führen | + | * Der Schritt wird $n$ Mal ausgeführt, |
| Es wird jedes Element mit jedem anderen verglichen. Intuitiv scheint es möglich, mit weniger Vergleichen auszukommen. Wenn wir wissen, dass `x > y` und `y > z` ist, so müssten wir eigentlich `x` nicht mehr mit `z` vergleichen. Aber wieviele Vergleiche sind mindestens notwendig? Können wir einen **Divide & Conquer** Ansatz wie bei der Binärsuche verwenden? | Es wird jedes Element mit jedem anderen verglichen. Intuitiv scheint es möglich, mit weniger Vergleichen auszukommen. Wenn wir wissen, dass `x > y` und `y > z` ist, so müssten wir eigentlich `x` nicht mehr mit `z` vergleichen. Aber wieviele Vergleiche sind mindestens notwendig? Können wir einen **Divide & Conquer** Ansatz wie bei der Binärsuche verwenden? | ||
| - | |||
| #### C7 (Herausforderung): | #### C7 (Herausforderung): | ||
| Zeile 217: | Zeile 221: | ||
| ++++ | ++++ | ||
| - | <nodisp 1> | + | <bottom-exercise id=" |
| - | ++++Lösung| | + | < |
| - | <code python quicksort.py> | + | def teile(l, links, rechts): |
| + | """ | ||
| + | Divide-Step von Quicksort: Teilt die angegebene Liste in zwei Teile und gibt | ||
| + | den Index des Pivot-Elements zurück. | ||
| + | Alle Elemente vor dem Pivot-Element sind <= dem Pivot, alle Elemente nachher sind | ||
| + | grösser als der Pivot. | ||
| + | """ | ||
| + | |||
| + | def quick_sort(l, | ||
| + | """ | ||
| + | </ | ||
| + | < | ||
| + | assert quick_sort([3, | ||
| + | assert quick_sort([35, | ||
| + | </ | ||
| + | < | ||
| def teile(l, links, rechts): | def teile(l, links, rechts): | ||
| """ | """ | ||
| Zeile 253: | Zeile 272: | ||
| def quick_sort(l, | def quick_sort(l, | ||
| - | links = links or 0 | + | links = 0 if links is None else links |
| - | rechts = rechts or len(l) - 1 | + | rechts = len(l) - 1 if rechts is None else rechts |
| # Falls die Liste weniger als 2 Elemente hat, ist sie bereits sortiert. | # Falls die Liste weniger als 2 Elemente hat, ist sie bereits sortiert. | ||
| if links < rechts: | if links < rechts: | ||
| Zeile 269: | Zeile 288: | ||
| l = [35, 71, 93, 88, 1, 83, 83, 56, 10, 96] | l = [35, 71, 93, 88, 1, 83, 83, 56, 10, 96] | ||
| print(quick_sort(l)) | print(quick_sort(l)) | ||
| - | </code> | + | </template> |
| - | ++++ | + | </bottom-exercise> |
| - | </nodisp> | + | |