Heutiges Programm
Letztes Mal: Insertion Sort
Sortiere [5, 2, 8, 4, 1]:
Schleifeninvariante
Vor Iteration i sind Elemente in li[:i] sortiert.
Bei Iteration i, das i-te Element an der korrekten Position in die sortierte Teilliste li[:i] einfügen.
Wiederholen bis das gesamte Array sortiert ist (i = n).
Letztes Mal: Insertion Sort
# Input: Array A = (A[1], ..., A[n]), n >= 0
# Output: Sortiertes Array A
def insertion_sort(A):
for i in range(1, len(A)):
j = i
while j > 0 and A[j-1] > A[j]:
A[j], A[j-1] = A[j-1], A[j]
j = j - 1Anzahl Vergleiche im schlechtesten Fall?
Anzahl Vertauschungen im schlechtesten Fall?
Frage: Wie können wir die Anzahl Vergleiche für den schlechtesten Fall verbessern?
Binärer Insertion Sort
Idee: Verwende binäre Suche statt linearer Suche, um die Einfügeposition zu finden.
# Input: Array A = (A[1], ..., A[n]), n >= 0
# Output: Sortiertes Array A
def binary_insertion_sort(A):
for i in range(1, len(A)):
x = A[i]
p = BinarySearchIndex(A, 0, i-1, x)
for j in range(i-1, p-1, -1):
A[j+1] = A[j]
A[p] = xAnzahl Vergleiche im schlechtesten Fall?
Anzahl Kopiervorgänge im schlechtesten Fall?
Übung 1
Geben Sie die Anzahl Aufrufe der Funktion f abhängig von n in der Θ-Notation für den untenstehenden Beispiel an. Kürzen Sie ihr Ergebnis soweit wie möglich. Geben Sie eine kurze Begründung.
# pre: n is an integer >= 0
def g(n):
count = 0
while n // (2 ** count) >= 1:
f()
count += 1Übung 2
Geben Sie die Anzahl Aufrufe der Funktion f abhängig von n in der Θ-Notation an. Kürzen Sie ihr Ergebnis soweit wie möglich.
# pre: n is an integer >= 0
def g(n):
if n >= 1:
f()
g(n // 2)Übung 3
Geben Sie die Anzahl Aufrufe der Funktion f abhängig von n in der Θ-Notation an. Kürzen Sie ihr Ergebnis soweit wie möglich.
# pre: n is an integer >= 0
def g(n):
if n >= 1:
for i in range(n):
f()
g(n // 2)Übung 4
Geben Sie die Anzahl Aufrufe der Funktion f abhängig von n in der Θ-Notation an. Kürzen Sie ihr Ergebnis soweit wie möglich.
# pre: n is an integer >= 0
def g(n):
if n >= 1:
for i in range(n):
f()
g(n // 2)
g(n // 2)Rekursive Snippets: Verifikation
Überprüfe die Analysen empirisch.
Merge
Zwei sortierte Arrays werden zu einem sortierten Array zusammengeführt.
Eingabe: zwei sortierte Arrays
Vergleiche jeweils die kleinsten Elemente und nimm das kleinere:
1 < 2 → nimm 1 (a1) | 4 > 2 → nimm 2 (a2) | 4 > 3 → nimm 3 (a2)
4 < 10 → nimm 4 (a1) | 7 < 10 → nimm 7 (a1) | 9 < 10 → nimm 9 (a1)
16 > 10 → nimm 10 (a2) | 16 > 11 → nimm 11 (a2) | 16 > 12 → nimm 12 (a2)
Rest: nimm 16 (a1)
Ergebnis:
Algorithmus merge
Algorithmus merge_sort
Natürlicher 2-Wege Mergesort
Idee: Nutze bereits existierende sortierte Teilfolgen (Runs) statt immer in der Mitte zu teilen.
Runs identifizieren (aufsteigende Teilfolgen):
Pass 1: Benachbarte Run-Paare mergen
Pass 2: Weiter mergen
Pass 3: Fertig!
Algorithmus NaturalMergesort(A)
Input: Array A der Länge n > 0, Output: Array A sortiert
Gruppenübung: Timsort
https://expert.ethz.ch/enrolled/SS26/mavt2/codeExamples
Timsort, eine Kombination aus Insertion Sort und Merge Sort, ist der Standard-Sortieralgorithmus in Python. Mehr dazu in der Aufgabenbeschreibung auf Code Expert.
Timsort: Überblick
Timsort kombiniert die Stärken von Insertion Sort (schnell für kleine/fast-sortierte Daten) und Merge Sort (garantiert O(n log n)):
- Teile das Array in kleine Blöcke (Runs)
- Sortiere jeden Run mit Insertion Sort
- Merge die Runs mit einem optimierten Merge-Verfahren
Übung 6: Search and Sort
- Eierwerfen
- Vergleich von Sortieralgorithmen
- Verbesserter Insertion Sort
- Invarianten der Suchalgorithmen
Abgabedatum: Montag 06.04.2026, 20:00 CET
KEINE HARDCODIERUNG