Sortieren durch Zerlegen / Quicksort

Ein Sortierspiel

Anton, Britta, Carlo, ... wollen sich der Größe nach in einer Reihe aufstellen. Zuerst werden alle genau vermessen.

Sortierspiel

Das Spiel läuft jetzt so ab:

Eine Person (z.B. die erste in der Reihe) wird als Vergleichsperson ausgewählt. Im vorliegenden Beispiel ist das Anton.

Sortierspiel

Alle anderen ordnen sich links bzw. rechts von der Vergleichsperson ein, je nachdem, ob sie kleiner oder größergleich als die Vergleichsperson sind.

Sortierspiel

Anton bleibt jetzt auf seiner Position. Er nimmt nicht mehr an weiteren Spielrunden teil. Dasselbe Spiel wird jetzt im linken und im rechten Bereich durchgeführt: Eine Person (z.B. die erste in der Reihe) wird wiederum als Vergleichsperson ausgewählt.

Sortierspiel

Und so weiter ...

Aufgabe 1

Spielt das Sortierspiel selbst durch. Wann ist das Spiel beendet? Welche Extremfälle können während des Spiels auftreten? Funktioniert das Sortierspiel dann auch noch?

Die Grundidee

Gegeben ist eine Liste mit vergleichbaren Elementen. Ein Element der Liste (z.B. das erste Element) wird ausgewählt. Die Restliste wird dann gemäß dieses Elements in zwei Teillisten aufgeteilt: die Liste der Elemente der Restliste, die kleiner als das ausgewählte Element sind sowie die Liste der Elemente der Restliste, die nicht kleiner (d.h. größer oder gleich) als das ausgewählte Element sind. Dieser Vorgang wird mit den Teillisten völlig analog fortgesetzt.

  25   17   32   56   25   19    8   66   29    6   20   29
  ^

  17   19    8    6   20 | 25 | 32   56   25   66   29   29
  ^                      |    | ^
                         |    | 
   8    6 | 17 | 19   20 |    | 25   29   29 | 32 | 56   66
   ^      |    | ^       |    | ^            |    |  ^
          |    |         |    |              |    |
   6 |  8||    ||19 | 20 |    ||25 | 29   29 |    ||56 | 66
     |   ||    |    |    |    ||   | ^       |    ||   |
     |   ||    |    |    |    ||   ||29 | 29 |    ||   |    

Die folgende Abbildung soll die Grundidee des Sortierverfahrens Sortieren durch Zerlegen noch einmal verdeutlichen:

Quicksort

Aufgabe 2

Führe das Sortierverfahren Sortieren durch Zerlegen am folgenden Beispiel durch. Protokolliere die einzelnen Schritte wie oben gezeigt.

  35   28   41    7   14   50   33   21   21   60   18   12
  ^

Ablaufmodellierung mit mehreren Listen

Das oben erläuterte Sortierverfahren soll jetzt mit einem Algorithmus beschrieben werden.

Informell lässt sich dieser Sortierablauf so beschreiben:

ALGORITHMUS quicksort
Übergabe: Liste L
wenn die Liste L mehr als ein Element hat:
    # zerlegen
    wähle als Pivotelement p das erste Element der Liste aus
    erzeuge Teillisten K und G aus der Restliste (L ohne p) mit:
    - alle Elemente aus K sind kleiner als das Pivotelement p
    - alle Elemente aus G sind größergleich als das Pivotelement p
    # Quicksort auf die verkleinerten Listen anwenden
    KSortiert = quicksort(K)
    GSortiert = quicksort(G)
    # zusammensetzen
    LSortiert = KSortiert + [p] + GSortiert
sonst:
    LSortiert = L
Rückgabe: LSortiert

Aufgabe 3

Implementiere den Algorithmus quicksort.

Ablaufmodellierung mit einer Liste

Quicksort lässt sich auch mit Vertauschungen von Elementen in der Ausgangsliste realisieren:

ALGORITHMUS quicksort
Übergabe: Liste L, Indexbereich
wenn die Liste L nicht leer ist:
    # zerlegen
    wähle als Pivotelement p das erste Element der Liste aus
    tausche Elemente innerhalb L so, dass eine Zerlegung entsteht mit: 
    - L = K + G
      alle Elemente aus K sind kleinergleich als das Pivotelement p
      alle Elemente aus G sind größergleich als das Pivotelement p
      K und G enthalten mindestens ein Element
    # Quicksort auf die verkleinerten Listen anwenden
    L = quicksort(L, Indexbereich von K)
    L = quicksort(L, Indexbereich von G)
Rückgabe: L

Die Implementierung ist hier etwas schwieriger:

def quicksort(L, anfang, ende):
    if len(L) > 1:
        #print('Quicksort', L[anfang:(ende+1)])
        pivot = L[anfang]
        links = anfang
        rechts = ende
        while links <= rechts:
            while L[links] < pivot:
                links = links+1
            while L[rechts] > pivot:
                rechts = rechts-1
            if links <= rechts:
                if links < rechts:
                    h = L[links]
                    L[links] = L[rechts]
                    L[rechts] = h
                links = links+1
                rechts = rechts-1
                if rechts < anfang:
                    rechts = anfang
        #print('         ', L[anfang:rechts+1], L[links:(ende+1)])
        if anfang < rechts:            
            L = quicksort(L, anfang, rechts)
        if links < ende:
            L = quicksort(L, links, ende)
    return L

# Test
L = [25, 17, 32, 56, 25, 19, 8, 66, 29, 6, 20, 29]
print(L)
L = quicksort(L, 0, len(L)-1)
print(L)

Aufgabe 4

Teste diese Implementierung. Teste sie auch mit den Ausgabeanweisungen, die in der Funktionsdefinition oben noch auskommentiert sind. Erkläre die ausgegebenen Werte.

X

Fehler melden

X

Suche