Quicksort
- Quicksort-Algorithmus
- Quick-Sort-Beispiel
- Implementierung des Quick-Sort-Algorithmus
- Quick-Sort-Algorithmus Komplexität
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
aufbeg - 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 Siei
und vertauschen SieA[i]
mitA[j]
. -
Tauschen Sie
A[i]
mitA[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.
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 wird3
an seine sortierte Position gesetzt. Die beiden gebildeten Subarrays werden dann rekursiv sortiert. -
Für Subarray
(1,2)
wird2
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)
wird4
in sortierte Position gebracht und Subarray(6,5)
gebildet, das dann rekursiv sortiert wird. -
Für Subarray
(6,5)
wird5
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 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