Quicksort

Harshit Jindal 12 Oktober 2023
  1. Quicksort-Algorithmus
  2. Quick-Sort-Beispiel
  3. Implementierung des Quick-Sort-Algorithmus
  4. Quick-Sort-Algorithmus Komplexität
Quicksort

Die Quicksort ist ein hocheffizienter Sortieralgorithmus, der auf dem Prinzip des Divide-and-Conquer-Algorithmus basiert. Quick Sort arbeitet, indem es das Array in zwei Teile um ein ausgewähltes Pivot-Element herum partitioniert. Es verschiebt kleinere Elemente auf die linke Seite des Pivots und größere Elemente auf die rechte Seite. Danach werden die linken und rechten Teilbereiche rekursiv sortiert, um das gesamte Array zu sortieren. Es wird Quick sort genannt, weil es etwa 2 oder 3 mal schneller ist als herkömmliche Sortieralgorithmen. Quick Sort wird häufig für die Informationssuche und numerische Berechnungen innerhalb von Datenstrukturen verwendet.

Quicksort-Algorithmus

Nehmen wir an, dass wir ein unsortiertes Array A[] mit n Elementen haben. Nehmen Sie zwei Variablen, beg & end, und speichern Sie den Index des Anfangs- und des Endelements.

Partition()

  • Wählen Sie das letzte Element (kann je nach Implementierung ein beliebiges sein) als Pivot-Element.
  • Initialisieren Sie den Wert des Zeigers i auf beg - 1, damit wir Elemente, die kleiner als das Pivot-Element sind, an den Anfang des Arrays verschieben können.
  • Durchlaufen Sie das Array iterativ und führen Sie für jedes Element die folgenden Schritte aus.
  • Wenn das Element A[i] < pivot ist, inkrementieren Sie i und vertauschen Sie A[i] mit A[j].
  • Tauschen Sie A[i] mit A[end], um das Pivot-Element an seine richtige Position zu setzen.
  • Gibt den Index des Pivot-Elements zurück.

QuickSort()

  • Wählen Sie den Pivot-Index pi.
  • Partitionieren Sie das Array um den Pivot-Index.
  • Rekursives Sortieren der Elemente auf der linken Seite arr[beg,...,pi] des Pivot-Elements.
  • Rekursives Sortieren der Elemente auf der rechten Seite arr[pi+1,...,end] des Pivot-Elements.

Schnellsortieralgorithmus

Ergebnis des Quick-Sort-Algorithmus

Quick-Sort-Beispiel

Angenommen, wir haben das Array: (6,5,1,4,2,3). Wir werden es mit dem Quick-Sort-Algorithmus sortieren.

  • Zuerst wird 3 als Pivot-Element ausgewählt, das Array wird in zwei Teilbereiche (1,2) - kleinere Elemente, und (6,5,4) - größere Elemente - partitioniert. Und dann wird 3 an seine sortierte Position gesetzt. Die beiden gebildeten Subarrays werden dann rekursiv sortiert.
  • Für Subarray (1,2) wird 2 als Pivot-Element ausgewählt und an die richtige Position gesetzt & es wird Subarray (1) gebildet, das bereits sortiert ist.
  • Für Subarray (6,5,4) wird 4 in sortierte Position gebracht und Subarray (6,5) gebildet, das dann rekursiv sortiert wird.
  • Für Subarray (6,5) wird 5 als Pivot ausgewählt und an die richtige Position gesetzt, was (6) als neues Subarray ergibt. Der Einzelelement-Unterarray (6) ist bereits sortiert.
  • Schließlich erhalten wir das sortierte Array als (1, 2, 3, 4, 5, 6).

Implementierung des Quick-Sort-Algorithmus

#include <bits/stdc++.h>
using namespace std;

int partition(int arr[], int beg, int end) {
  // Select the last element as pivot element
  int pivot = arr[end];
  int i = (beg - 1);
  // Move smaller elements to left side and larger on right side
  for (int j = beg; j < end; j++) {
    if (arr[j] <= pivot) {
      i++;
      swap(arr[i], arr[j]);
    }
  }
  swap(arr[i + 1],
       arr[end]);  // Move pivot element to its right position in array
  return (i + 1);
}

void quickSort(int arr[], int beg, int end) {
  if (beg < end) {
    int pi = partition(arr, beg, end);
    quickSort(arr, beg,
              pi - 1);  // Recursive Sort element on left side of partition
    quickSort(arr, pi + 1,
              end);  // Recursive Sort element on right side of partition
  }
}
int main() {
  int n = 6;
  int arr[6] = {5, 3, 4, 2, 1, 6};
  cout << "Input array: ";
  for (int i = 0; i < n; i++) {
    cout << arr[i] << " ";
  }
  cout << "\n";
  quickSort(arr, 0, n - 1);  // Sort elements in ascending order
  cout << "Output array: ";
  for (int i = 0; i < n; i++) {
    cout << arr[i] << " ";
  }
  cout << "\n";
}

Quick-Sort-Algorithmus Komplexität

Zeitkomplexität

  • Durchschnittlicher Fall

Die von Quick Sort benötigte Zeit ist durch die folgende Rekursionsbeziehung gegeben:

 T(n) = T(k) + T(n-k-1) + θ(n)

k steht hier für die Anzahl der Elemente, die kleiner/größer als das Pivot-Element sind.

Das Ergebnis dieser Rekursionsrelation ist T(n) = nLogn.Der Durchschnittsfall tritt auf, wenn wir zufällige, ungleichmäßige Partitionen erhalten. Die Zeitkomplexität liegt in der Größenordnung von [Big Theta]: O(nLogn).

  • Schlimmster Fall
T(n) = T(n-1) + θ(n)

Der Worst-Case tritt auf, wenn das Pivot-Element immer entweder das größte oder das kleinste Element des Arrays ist. In diesem Fall fallen alle Elemente in ein Subarray und es müssen maximal n Aufrufe gemacht werden. Die Zeitkomplexität im schlimmsten Fall ist [Big O]: O(n2).

  • Bester Fall
 T(n) = 2T(n/2) + θ(n)

Der beste Fall tritt ein, wenn das ausgewählte Pivotelement immer das mittlere Element ist oder wenn beide Partitionen gleichmäßig ausgeglichen sind, d.h. der Größenunterschied ist 1 oder weniger. Die Zeitkomplexität im besten Fall ist [Big Omega]: O(nLogn).

Raumkomplexität

Die durchschnittliche Platzkomplexität für den Schnellsortieralgorithmus ist O(Logn). Das ist der Platz, den der Rekursionsstapel benötigt. Aber im schlimmsten Fall, wenn das Sortieren eines Arrays n Rekursionen erfordert, ist die Platzkomplexität O(n).

Harshit Jindal avatar Harshit Jindal avatar

Harshit Jindal has done his Bachelors in Computer Science Engineering(2021) from DTU. He has always been a problem solver and now turned that into his profession. Currently working at M365 Cloud Security team(Torus) on Cloud Security Services and Datacenter Buildout Automation.

LinkedIn

Verwandter Artikel - Sort Algorithm