diff --git a/200_Sortieralgorithmen.tex b/200_Sortieralgorithmen.tex
index c804770fd15a1e6e2eb0f3cc2993e174217f39a6..9cf25b71c3e427cfdbabf64f12e38b36b03b5a33 100644
--- a/200_Sortieralgorithmen.tex
+++ b/200_Sortieralgorithmen.tex
@@ -4,8 +4,8 @@ In diesem Kapitel werden wir uns mit Sortieralgorithmen beschäftigen. Den Anfan
 widmen, nur um sie kurz darauf (mit erweiterten Voraussetzungen an die zu sortierenden Objekte) mit \texttt{radixsort} wieder
 zu brechen.
 
-\input{201_quicksort}
-\include{202_mergesort}
+\input{201_mergesort}
+\include{202_quicksort}
 \include{203_Untere_Schranke_Sortieralgorithmen}
 \include{204_Radixsort}
 \include{205_Eigenschaften_von_Sortieralgorithmen}
diff --git a/201_mergesort.tex b/201_mergesort.tex
new file mode 100644
index 0000000000000000000000000000000000000000..fd575f3efcd5da6bc2dd4cf5dbd40762e5cfd5ce
--- /dev/null
+++ b/201_mergesort.tex
@@ -0,0 +1,111 @@
+\section{Mergesort}
+Diese Sortierverfahren ist ein Paragon der sogenannten \emph{divide et impera}-Strategie.
+
+Ausgehend von einem linearen Feld $\mathcal{A}$ der Größe $n$ unterteilen wir das Problem rekursiv immer weiter in kleinere Probleme,
+welche superlinear schneller gelöst werden können. Der Basisfall, ein Array mit einem einzigen Element, ist dann immer
+sortiert. Im letzen Schritt vereinen wir alle sortierten Teilarrays zu einem großen sortierten Array. Siehe Abbildung
+\ref{fig:mergesort_diagram} für ein Beispiel.
+
+\begin{figure}[htb]
+  \centering
+  \includegraphics[width=0.8\textwidth]{bilder/mergesort_diagram}
+  \caption{Ein Beispiellauf des \texttt{mergesort}-Algorithmus auf den Input $\mathcal{A} = (38,27,43,3,9,82,10)$}
+  \label{fig:mergesort_diagram}
+\end{figure}
+Im folgenden Pseudocode verwenden wir die Funktion $\texttt{Array}(n)$, welches uns einfach nur ein leeres (also z.B.
+mit $0$ gefülltes) Array der Länge $n$ gibt, sowie die Funktion $\texttt{len}(\mathcal{A})$, welche die Länge des arrays $\mathcal{A}$
+zurückgibt.
+
+\begin{algorithm}[H]
+  \SetNlSty{texttt}{[}{]}
+  \caption{\texttt{mergesort}($\mathcal{A}$)}
+  \KwIn{An  array $\mathcal{A}$ of size $n$}
+  \KwOut{The sorted array $\mathcal{A}$}
+  \eIf{$n = 1$}{
+    \Return $\mathcal{A}$ \;
+  }{
+    $k \leftarrow \floor*{\frac{n}{2}}$ \;
+    \KwRet $\texttt{merge}(\texttt{mergesort}(\mathcal{A}[0,\dots, k]), \texttt{mergesort}(\mathcal{A}[k+1, \dots,  n]))$
+  }
+\end{algorithm}
+
+Wobei \texttt{merge} folgendermaßen definiert wird:
+
+\begin{algorithm}[H]
+  \SetNlSty{texttt}{[}{]}
+  \caption{\texttt{merge}($\mathcal{A}_1, \mathcal{A}_2$)}
+  \KwIn{Two sorted arrays $\mathcal{A}_1$ and $\mathcal{A}_2$}
+  \KwOut{The sorted union array $\mathcal{A}$ of the input}
+  $\mathcal{A} \leftarrow \texttt{Array}(\texttt{len}(\mathcal{A}_1) + \texttt{len}(\mathcal{A}_2))$ \;
+  $i_1, i_2 \leftarrow 0$ \;
+  \For{$i \leftarrow 0$ \KwTo $\texttt{len}(\mathcal{A})$}{
+    \eIf{$\mathcal{A}_1[i_1] \leq \mathcal{A}_2[i_2]$}{
+      $\mathcal{A}[i] \leftarrow \mathcal{A}_1[i_1]$ \;
+      $i_1 \leftarrow i_1 + 1$ \;
+    }{
+      $\mathcal{A}[i] \leftarrow \mathcal{A}_2[i_2]$ \;
+      $i_2 \leftarrow i_2 + 1$ \;
+    }
+  }
+  \KwRet $\mathcal{A}$
+\end{algorithm}
+
+\subsubsection{Laufzeit}
+Die Laufzeit der Algorithmen ist nicht vom konkreten Input, sondern nur von der Länge des Inputs abhängig. Worst, best
+und average case sind also gleich. Für \texttt{merge} ist die Länge des Inputs $n = \texttt{len}(\mathcal{A}_1) +
+\texttt{len}(\mathcal{A}_2)$ und es gilt: $T_{\text{m}} = T_{\texttt{merge}} = f \in \mathcal{O}(n)$, da Zeile~3 alles dominiert. 
+
+Damit ist die Laufzeitfunktion für \texttt{mergesort} für $T_\text{ms}(1) \in \mathcal{O}(1)$ und für $n > 1$
+\[
+  T_{\text{ms}}(n) = 2 T_{\text{ms}}(\frac{n}{2}) + T_{\text{m}}(n) + d,
+\]
+wobei $d \in \mathcal{O}(1)$.
+Mit dem Hauptsatz der Laufzeitfunktionen haben wir damit Fall 2, die asymptotisch exakte Laufzeit beträgt ($\log_2{2} = 1$) also
+\[
+  T^{\text{ms}} \in Θ(n \log{n}).
+\]
+
+Um die Methodik der rekursiven Laufzeitberechnungen zu demonstrieren, berechnen wir die eine Seite der Abschätzung
+elementar. Um den Beweis übersichtlicher zu halten, nehmen wir an, dass $n=2^k$ für ein $k \in \mathbb{N}$. Für Werte
+von $n$, welche keine Zweierpotenz sind, können wir aufgrund der Monotonie von $T_\text{ms}$ dann abschätzen.
+
+\begin{align*}
+  T_{\text{ms}} 
+  &= 2T_\text{ms}\left(\frac{n}{2}\right) + T_\text{m}(n) + d \\
+  &= 4T_\text{ms}\left(\frac{n}{4}\right) + 2 T_\text{m}\left(\frac{n}{2}\right) + 2d + T_\text{m}(n) + d \\
+  &= 8T_\text{ms}\left(\frac{n}{8}\right) + 4 T_\text{m}\left(\frac{n}{4}\right) + 4d + 2 T_\text{m}\left(\frac{n}{2}\right) + 2d + T_\text{m}(n) + d \\
+  &\vdots \\
+  &= \underbrace{n T_\text{ms}(1)}_{\in \mathcal{O}(n)} 
+    + \sum_{l=0}^{\log_2 \left(\frac{n}{2}\right)} 2^l T_\text{m}\left(\frac{n}{2^l} \right) 
+    + \underbrace{\sum_{l=0}^{\log_2 \left(\frac{n}{2}\right)} 2^l d}_{\in \mathcal{O}(n)}
+\end{align*}
+
+Wir müssen also nurnoch den asymptotischen Aufwand für die rekursiven Aufrufe von $T_\text{m}$ finden.
+Wir wissen, da $T_\text{m} \in \mathcal{O}(n)$, dass es ein $n_0 \in \mathbb{N}$ und $c \in \mathbb{R}$ gibt, sodass
+$T_\text{m}(n) \leq c n$ für \emph{alle} $n > n_0$. Insbesondere also für die nächstgrößere Zweierpotenz, sodass wir
+o.B.d.A. annehmen können: $n_0 = 2^k_0$ für ein $k_0 \in \mathbb{N}$. Für alle $n \leq n_0$ können wir den Aufwand von
+$T_\text{m}(n)$ zudem durch die Konstante $m = \max(\{T_\text{m}(i) | i \in \{0, \dots, n_0\}\})$ abschätzen.
+
+Das erlaubt es uns, obige Summe aufzuspalten:
+\[
+  \sum_{l=0}^{k-1} 2^l T_\text{m}\left( \frac{n}{2^l} \right) = 
+  \sum_{l=0}^{k-k_0} 2^l T_\text{m}\left( \frac{n}{2^l} \right) + 
+  \underbrace{\sum_{l=k-k_0+1}^{k-1} 2^l T_\text{m}\left( \frac{n}{2^l} \right)}_{\leq 2^k m \in \mathcal{O}(n)}.
+\]
+Es bleibt noch der erste Teil. Aber hier greift endlich die Abschätzung $T_\text{m}(n)~\leq~cn$, und damit
+\[
+  \sum_{l=0}^{k-k_0} 2^l T_\text{m}\left( \frac{n}{2^l} \right) 
+  = c \sum_{l=0}^{k-k_0} 2^l \frac{n}{2^l} 
+  = c \sum_{l=0}^{k-k_0} n
+  \in \mathcal{O}(n \log_2 n).
+\]
+Dieser Term dominiert also alle anderen Terme, und damit $T_\text{ms} \in \mathcal{O}(n \log n)$.
+
+
+\subsubsection{Speicherverbrauch}
+In der hier vorgestellten Variante muss bei jedem Aufruf von \texttt{merge} ein neues Array angelegt werden. Damit braucht
+$\texttt{mergesort}$ asymptotisch $\mathcal{O}(n)$ zusätzlichen Speicher.
+
+Es gibt allerdings auch weiterentwicklungen, die mit $\mathcal{O}(1)$ Speicher auskommen (z.B. TimSort oder blocksort).
+
+
diff --git a/202_quicksort.tex b/202_quicksort.tex
new file mode 100644
index 0000000000000000000000000000000000000000..f961c8bc22c1bdfffb3c6846bad210a1fd451ac6
--- /dev/null
+++ b/202_quicksort.tex
@@ -0,0 +1,290 @@
+\section{Quicksort}
+Quicksort ist einer der meist verwendeten Sortieralgorithmen. Die Idee ist wieder das divide-et-impera-Prinzip,
+der Kern des Algorithmus ist die Zerlegung des Arrays, die sogenannte Partition.
+
+\subsection{Partition}
+Für eine Partition eines Arrays $\mathcal{A}$ wählen wir zuerst ein Pivotelement $p$. Nun sortieren wir das Array so,
+dass links von $p$ nur Elemente stehen, die kleiner als $p$ sind, rechts nur Elemente, die größer sind.
+Vorerst nehmen wir als Pivotelement einfach das letzte Arrayelement.
+
+\noindent Die Funktion $\texttt{swap}(a,b)$ im folgenden Pseudocode tauscht hierbei die Werte von $a$ und~$b$.
+
+\begin{algorithm}[H]
+  \SetNlSty{texttt}{[}{]}
+  \caption{\texttt{partition}($\mathcal{A}$)}
+  \KwIn{An unsorted array $\mathcal{A}$ of lenght $n$} 
+  \KwOut{The partition of $\mathcal{A}$ wrt. the pivot $p$ and its index $k$}
+  $p \leftarrow \mathcal{A}[n-1]$ \;
+  $i \leftarrow -1$ \;
+  \For{$j \leftarrow 0$ \KwTo $n-2$}{
+    \If{$\mathcal{A}[j] \leq p$}{
+      $\texttt{swap}(\mathcal{A}[i+1], \mathcal{A}[j])$ \;
+      $i \leftarrow i + 1$ \;
+    }
+  }
+  $\texttt{swap}(\mathcal{A}[i+1], \mathcal{A}[n-1])$ \;
+  $i \leftarrow i + 1$ \;
+  \KwRet $(\mathcal{A}, i)$
+\end{algorithm}
+
+\subsubsection{Korrektheitsüberlegungen:}
+Was passiert hier? Das Pivotelement $p$ ist das letzte Element von $\mathcal{A}$, siehe Zeile [1].
+Wie oben erwähnt, partionieren wir das Array in
+Elemente, welche kleiner oder gleich $p$ sind, sowie die Elemente, welche größer als $p$ sind.
+Das Pivotelement $p$ dient erstmal nur zum Vergleichen ([4]), bleibt aber
+ansonsten außen vor, bis es in Zeile [7] an seine endgültige Position getauscht wird. 
+
+Die endgültige Position von $p$ wird von dem Index $i$ bestimmt. Dabei erfüllt $i$ zu jedem Zeitpunkt die Bedingung,
+dass alles, was sich links von $i$ befindet ($i$ eingeschlossen), stets kleiner oder gleich $p$ ist (Zeile [4] und [5])! Unter
+den Elementen, die bereits mit $p$ verglichen wurden (siehe Laufindex $j$) nimmt $i$ dabei den maximalen Wert ein (Nach
+Ausführung von Zeile [6], bzw Zeile [8]). Zu beachten ist außerdem, dass durch das rechtzeitige Addieren von $i+1$ nie ein
+Arrayzugriff an undefinierter Stelle geschieht([5]), selbst wenn $i$ mit $-1$ initialisiert wurde([2]).
+
+Als letztes muss nur noch die Rolle des Laufindex $j$ geklärt werden. Definiert in Zeile [3] startet $j$ beim ersten Element
+und geht bis zum vorletzten (also exklusiv $p$). Da pro Schleifendurchgang $i$ um maximal eins inkrementiert werden
+kann, ist $j$ also stets größergleich $i$. Dabei zeigt $j$ an, welche Elemente des Arrays bereits mit $p$ verglichen
+wurden. 
+Findet $j$ mit Zeile $[4]$ ein Element, welches kleiner ist als $p$, wird dieses in den von $i$ markierten Bereich
+vertauscht([5]). Dabei wird eine Sortierung innerhalb einer Partition zwar vielleicht zerstört, aber das ist für die
+Korrektheit des Algorithmus nicht relevant. 
+
+Man kann also feststellen: Das Array ist stets in vier (möglicherweise leere) Teilbereiche unterteilt. Der
+Speicherort von $p$ (Anfangs $n-1$), die noch nicht verglichenen Elemente $j < \text{ index } \leq n-2$, die kleiner als
+$p$ eingestuften Elemente $0 \leq \text{ index } \leq i$ und die als größer als $p$ eingestuften Elemente $i < \text{ index }
+\leq j$.
+
+Da ein Schleifendurchlauf die Schleifeninvarianten (also der Programmzustand exakt vor dem Inkrementieren von $j$)
+\begin{itemize}
+  \item Elemente mit Index $x$, wobei $x \leq i$, sind kleiner oder gleich $p$, 
+  \item Elemente mit Index $x$, wobei $i < x$ und $x \leq j$, sind größer $p$,
+  \item Elemente mit Index $x$, wobei $j < x$, sind noch nicht überprüft,
+\end{itemize}
+erhält, aber die Anzahl der nicht überprüften Elemente pro Schleifendurchlauf um eins schrumpft, terminiert der
+Algorithmus. Mit Zeile [7] wird am Ende noch $p$ an seinen richtigen Platz verschoben, damit eine korrekte Partition
+zurückgegeben werden kann.
+
+%TODO: Bild von partition analog zu Cormen, Figure 7.1
+
+\subsubsection{Laufzeit:}
+Die Schleife in Zeile [3] bis [6] hat an sich eine Laufzeit in $\mathcal{O}(1)$, wird aber $\mathcal{O}(n)$ mal
+aufgerufen. Dadurch ergibt sich, dass die Laufzeit von $T_{\text{p}} = T_\texttt{partition}(\mathcal{A})$ in $\Theta(n)$
+liegt, wobei $n = \texttt{len}(\mathcal{A})$. Es gibt keinen asmyptotischen Unterschied zwischen best/worst-case.
+
+
+\subsection{Quicksort}
+Auf der Basis von $\texttt{partition}$ kann der Sortieralgorithmus $\texttt{quicksort}$ konstruiert werden.
+
+\begin{algorithm}[H]
+  \SetNlSty{texttt}{[}{]}
+  \caption{\texttt{quicksort}($\mathcal{A}$)}
+  \KwIn{An unsorted array $\mathcal{A}$ of length $n$} 
+  \KwOut{The same array $\mathcal{A}$, but sorted}
+  \eIf{$n > 1$}{
+    $(\mathcal{A}, k) \leftarrow \texttt{partition}(\mathcal{A})$ \;
+    \KwRet $\texttt{concat}(\texttt{quicksort}(\mathcal{A}[0, \dots, k-1]), [A[k]], \texttt{quicksort}(\mathcal{A}[k+1,
+      \dots, n-1])$ \;
+  }{
+    \KwRet $\mathcal{A}$
+  }
+\end{algorithm}
+
+Die Funktion $\texttt{concat}$ ist hierbei eine $\mathcal{O}(1)$-Operation, da sie vom Compiler wegoptimiert werden
+kann. Aber auch als $\mathcal{O}(n)$-Operation wäre sie asymptotisch irrelevant, da $\texttt{partition}$ bereits
+$\mathcal{O}(n)$ Zeit braucht. Sollten wir Arrays auf Grenzen wie $[0,-1]$ aufrufen, so ist damit das leere Array
+gemeint.
+
+\subsubsection{Korrektheitsüberlegungen:}
+Die Korrektheit von $\texttt{quicksort}$ ist schneller einsehbar als die von $\texttt{partition}$. Ist die
+Paritionseigenschaft bezüglich des Pivotelements in Position $k$ erfüllt, so haben wir links und rechts davon echt
+kleinere Unterarrays, welche durch Rekursion sortiert werden (der Basisfall von einem Element ist trivial sortiert). Der
+Algorithmus $\texttt{quicksort}$ terminiert als spätestens nach $n$ rekursiven Aufrufen und arbeitet dabei korrekt.
+
+\subsubsection{Laufzeit:}
+Die allgemeine Rekusionsgleichung für $T_{\text{qs}} = T_{\texttt{quicksort}}$ lautet
+\[
+  T_{\text{qs}}(n) = T_{\text{qs}}(m) + T_{\text{qs}}(n-m) + T_p(n) + f(n), \text{ wobei } f \in \mathcal{O}(1).
+\]
+Dabei verschwindet $f$ völlig unter $T_p \in \mathcal{O}(n)$.
+Anders als bei $\texttt{partition}$ gibt es hier aber Unterschiede im best/worst case.
+
+\paragraph{Best case}
+Im besten Fall treffen wir mit dem Pivotelement $p$ genau den Median von $\mathcal{A}$. Dann haben wir durch $m =
+\frac{n}{2}$ pro Rekursionsschritt eine balancierte Aufteilung des Rekursionsbaums. Dann haben wir nach dem Hauptsatz
+der Laufzeitfunktionen also $a=2, b=2$, $f \in \mathcal{O}(n)$ und damit eine best-case-Laufzeit von
+$\mathcal{O}(n \log(n))$. Wir rechnen aber noch einmal per Hand nach: Einerseits um zu sehen wie das geschieht,
+andererseits, da der worst-case nicht mit dem Satz berechnet werden kann. 
+Sei der Einfachheit halber $n = 2^{k'}$ für ein $k' \in \mathbb{N}$.
+\begin{align*}
+  T_{\texttt{qs}}^{\text{best}}(n) 
+&= T_{\text{qs}}^{\text{best}} \left(\frac{n}{2} \right) + T_{\text{qs}}^{\text{best}} \left(\frac{n}{2} \right) + T_{\text{p}}(n) \\
+  &= 2T_{\text{qs}}^{\text{best}} \left(\frac{n}{2} \right) + T_{\text{p}}(n) \\
+  &= 4T_{\text{qs}}^{\text{best}}\left(\frac{n}{4} \right) + 2T_{\text{p}} \left(\frac{n}{2} \right) +  T_{\text{p}}(n) \\
+  &= 8T_{\text{qs}}^{\text{best}}\left(\frac{n}{8} \right) + 4T_{\text{p}} \left(\frac{n}{4} \right) + 2T_{\text{p}}\left(\frac{n}{2} \right) +  T_{\text{p}}(n) \\
+  &= \ldots \\
+  &= nT_{\text{qs}}^{\text{best}}(1)  + \sum_{k=0}^{\log_2(n)} 2^k T_{\text{p}}\left(\frac{n}{2^k}\right) \\
+\end{align*}
+Wir sehen nun in einer Nebenrechnung, dass $n \mapsto 2^k T_{\text{p}}(\frac{n}{2^k}) \in \Theta(n)$ für alle
+$k \in \mathbb{N}$. 
+Sei also $k$ fixiert. Dann gilt $c_1 \floor*{\frac{n}{2^k}} \leq T_{\text{p}}(\floor*{\frac{n}{2^k}}) \leq c_2
+\ceil*{\frac{n}{2^k}}$ für alle $n \geq n_0 2^k$, wobei $n_0$ durch $T_{\text{p}} \in \Theta(n)$ gegeben ist. Wir
+multiplizieren die Ungleichung mit $2^k$, erhalten damit $2^k c_1 \floor*{\frac{n}{2^k}} \leq 2^k
+T_{\text{p}}(\floor*{\frac{n}{2^k}}) \leq 2^k c_2 \ceil*{\frac{n}{2^k}}$, was wieder für alle $n \geq n_0 2^k$ gültig ist.
+Da $2^k \floor*{\frac{n}{2^k}} \leq n$ und $2^k \ceil*{\frac{n}{2^k}} \geq n$ gilt, können wir die Ungleichung zu 
+$c_1 n \leq 2^k T_{\text{p}}(\floor*{\frac{n}{2^k}}) \leq c_2 n$ vereinfachen. Damit gilt mit $c_1, c_2$ und $n_0' = 2^k
+n_0$:
+\[
+  n \mapsto 2^k T_{\text{p}}\left(\floor*{\frac{n}{2^k}}\right) \in \Theta(n).
+\]
+
+Damit haben wir
+\begin{align*}
+  T_{\text{qs}}^{\text{best}}(n) 
+  &= nT_{\text{qs}}^{\text{best}}(1)  + \sum_{k=0}^{\log_2(n)} 2^k T_{\text{p}}\left(\frac{n}{2^k}\right) \\
+  &\in \mathcal{O}(n) + \log_2(n) \mathcal{O}(n) \\
+  &= \mathcal{O}(n \log(n)). \\
+\end{align*}
+
+\paragraph{Worst case}
+Im schlechtesten Fall teilen wir das Array sehr ungünstig: Das Pivotelement ist immer das Maximum oder das Minimum,
+unser Array wird also aufgeteilt in ein $n-1$ großes Array, $m=1$ in jedem Rekursionsschritt.
+Damit haben wir keinen echten Bruchteil pro Rekursionsschritt und das Master-Theorem lässt sich nicht anwenden. Also
+rechnen wir per Hand:
+\begin{align*}
+  T_{\text{qs}}(n) & = T_{\text{qs}}(1) + T_{\text{qs}}(n-1) + T_\text{p}(n) \\
+  &= 2T_{\text{qs}}(1) + T_{\text{qs}}(n-2) + T_\text{p}(n-1) + T_\text{p}(n) \\
+  &= 3T_{\text{qs}}(1) + T_{\text{qs}}(n-3) + T_\text{p}(n-2) + T_\text{p}(n-1) + T_\text{p}(n) \\
+  &\qquad \qquad \vdots \\
+  &= \underbrace{n T_{\text{qs}}(1)}_{\text{$\in Θ(n)$}}  
+  +\underbrace{\sum_{i=1}^n T_\text{p}(i)}_{\text{$\in Θ(n^2)?$}} \\
+\end{align*}
+Dabei gibt uns die Eulersche Summenformel $\sum_{i=1}^n i = \frac{n^2 - n}{2} \in \mathcal{O}(n^2)$ einen Hinweis, in welcher
+Aufwandsklasse der Summenterm liegen könnte. Wir fomalisieren jetzt also die Idee, dass wir $T_{\text{p}}(n)$ durch $c_2 n$ von
+oben und $c_1 n$ von unten abschätzen können, sobald die $n$ groß genug werden.
+
+Betrachten wir also $\sum_{i=1}^k T_\text{p}(i)$. Mit $T_\text{p} \in Θ(n)$ wissen wir, dass $n_0,c_1,c_2$ existieren, sodass
+$c_1 n' \leq T_\text{p}(n') \leq c_2 n'$ für alle $n' > n_0$. Dieses $n_0$ ist aber fix, d.h. für ein groß genuges $k$ (und
+$k$ soll später gegen unendlich gehen) betrachten wir also $\sum_{i=n_0}^k T_p(i)$. Hier gilt:
+\[
+  \underbrace{c_1 \sum_{i=n_0}^k i}_{\text{$\in Ω(k^2)$}} 
+  \leq \sum_{i=n_0}^k T_p(i) \leq
+  \underbrace{c_2 \sum_{i=n_0}^k i}_{\text{$\in \mathcal{O}(k^2)$}}
+\]
+wie uns die Eulersche Summenformel verrät.
+Mit einer beidseitigen Abschätzung haben wir hier also obige Vermutung bewiesen.
+
+
+
+Wir würden nun gerne noch eine average-case Analyse durchführen. Bei einer Gleichverteilung des Inputs ergibt sich
+nämlich auch eine average-case Aufwand von $T_{\text{qs}}^{\text{avg}} \in \mathcal{O}(n \log n)$. Allerdings benötigt eine
+average-case Analyse Annahmen über die Verteilung des Inputs.
+
+Wir analysieren daher eine stark verwandte Variante, den randomisierten Quicksort.
+
+\subsection{Randomisierter Quicksort}
+Grundidee des randomisierten Quicksort Algorithmus ist es, nicht mehr ein fixes Pivotelement in der Partition zu wählen
+(wie bei uns das erste Element), sondern ein zufälliges. Dadurch kann man eine gute
+\emph{durchschnittliche} Performance erreichen. 
+
+Das Wort \emph{durchschnittlich} bekommt hier aber eine andere andere Bedeutung
+als in der average-case-Analyse! In der average-case-Analyse betrachtet man die durchschnittliche Laufzeit über alle
+möglichen Inputs (gewichtet mit der Wahrscheinlichkeit des entsprechenden Inputs), hier hingegen betrachtet man die
+durchschnittliche Laufzeit \emph{über die verschiedenen zufälligen Läufe des nichtdeterministischen Algorithmus}
+(gewichtet nach Wahrscheinlichkeit des entsprechenden Durchlaufs).
+
+Definieren wir zuerst die randomisierte Partition:
+
+\begin{algorithm}[H]
+  \SetNlSty{texttt}{[}{]}
+  \caption{\texttt{randomized\_partition}($\mathcal{A}$)}
+  \KwIn{An unsorted array $\mathcal{A}$ of length $n$} 
+  \KwOut{The partition of $\mathcal{A}$ wrt. the randomized pivot $p$ and its post-partitioning-index $k$}
+  $i \leftarrow \texttt{random\_uniform}(n-1)$ \;
+  $\texttt{swap}(\mathcal{A}[0], \mathcal{A}[i])$ \;
+  $p \leftarrow \mathcal{A}[n-1]$ \;
+  $i \leftarrow -1$ \;
+  \For{$j \leftarrow 0$ \KwTo $n-2$}{
+    \If{$\mathcal{A}[j] \leq p$}{
+      $\texttt{swap}(\mathcal{A}[i+1], \mathcal{A}[j])$ \;
+      $i \leftarrow i + 1$ \;
+    }
+  }
+  $\texttt{swap}(\mathcal{A}[i+1], \mathcal{A}[n-1])$ \;
+  $i \leftarrow i + 1$ \;
+  \KwRet $(\mathcal{A}, i)$
+\end{algorithm}
+
+Neu ist also nur das Vertauschen des ersten Elements von $\mathcal{A}$ mit dem durch $\texttt{random\_uniform}$
+zufällig (gleichverteilt) erwählten anderen Elements des Arrays, der Rest ist wie bei $\texttt{partition}$.
+Dabei hat $\texttt{random\_partition}$ die gleichbleibende Laufzeit $T_{\text{rp}} \in Θ(n)$ mit $n =
+\texttt{len}(\mathcal{A})$.
+
+Der Algorithmus $\texttt{randomized\_quicksort}$ hat dabei genau den gleichen Pseudocode wie $\texttt{quicksort}$, nur
+dass $\texttt{randomized\_partition}$ statt $\texttt{partition}$ in Zeile $[2]$ gerufen wird. Die Laufzeit von
+$\texttt{randomized\_quicksort}$ mit Input der Länge $n$ bezeichnen wir mit $T_{\text{rqs}}(n)$. Wir werden nun zeigen,
+dass $T_{\text{rqs}} \in \mathcal{O}(n \log n)$ liegt.
+
+
+\subsubsection{Herleitung der average case Laufzeit von \texttt{randomized\_quicksort}:} Für die erwartete Laufzeit gilt
+\begin{displaymath}
+  T_{\text{rqs}}(n) = \sum_{k=1}^{n-1} P(k) \left( T_{\text{rqs}}(k) + T_{\text{rqs}}(n-k) + T_{\text{rp}}(n) \right),
+\end{displaymath}
+wobei $P(k)$ die Wahrscheinlichkeit ist, dass $\texttt{randomized\_partition}(\mathcal{A})$ den Index $k$ liefert.
+Wir nehmen mit $k \in \{1,\dots, n-1\}$ eine Gleichverteilung $P(k) = \frac{1}{n-1}$ an.
+% TODO: Mehr Details
+\begin{align*}
+  T_{\text{rqs}} & = \sum_{k=1}^{n-1} \left( \frac{1}{n-1} \left( T_{\text{rqs}}(k) + T_{\text{rqs}}(n-k) + T_{\text{rp}}(n) \right) \right) \\
+  & = \frac{1}{n-1} \sum_{k=1}^{n-1} \left( T_{\text{rqs}}(k) + T_{\text{rqs}}(n-k) \right) + \frac{n-1}{n-1} T_{\text{rp}}(n) \\
+  & = \frac{2}{n-1} \sum_{k=1}^{n-1} T_{\text{rqs}}(k) + T_{\text{rp}}(n).
+\end{align*}
+Wir zeigen nun vermöge einer vollständiger Induktion, dass mit $c = \max\{T_{\text{rqs}}(1) + T_{\text{rp}}(2), 8 c_{\text{rp}}\}$ gilt: 
+\[
+  T_{\text{rqs}}(n) \leq c \cdot n \log_2 n \text{ für alle } n > 2.
+\]
+
+Hierbei ist $c_{\text{rp}}$ die Konstante mit welcher $T_\text{rp}(n) \leq c_{\text{rp}} n$ gilt. Streng genommen
+gilt das erst ab irgendeinem $n_0$, aber den Aspekt vernachlässigen wir hier, um die Beweisstruktur etwas
+übersichtlicher zu gestalten. Es ist bei \texttt{randomized\_partition} aber auch leicht ersichtlich, dass $n_0 = 2$
+gewählt werden kann. 
+
+Induktionsanfang $n=2$: 
+\begin{align*}
+  T_{\text{rqs}}(n) 
+  &\leq 2 T_{\text{rqs}}(1) + T_{\text{rp}}(n) \\
+  &\leq c n \log_2 2 
+\end{align*}
+Für $c = \max(T_{\text{rqs}}(1) + T_{\text{rp}}(2), 8 c_{\text{rp}}) \geq T_{\text{rqs}}(1) + T_{\text{rp}}(2)$ ist die
+Abschätzung definitiv erfüllt.
+
+Induktionsschritt $n-1 \mapsto n$: Zu zeigen ist, dass mit mit der Aussage wahr für alle $n \in \{2, \dots, n-1\}$ gilt:
+$T_{\text{rqs}}(n) \leq c n \log_2 n$. Wir rechnen:
+\begin{align*}
+  T_{\text{rqs}}(n) &= \frac{2}{n-1} \sum_{k=1}^{n-1} T_{\text{rqs}}(k) + T_{\text{rp}}(n) \\
+  &\overset{{\scriptscriptstyle \text{IV}}}{\leq} \frac{2}{n-1} \sum_{k=1}^{n-1} c \cdot k \log_2 k + T_{\text{rp}}(n) \\
+  &= \frac{2c}{n-1} \sum_{k=1}^{n-1} k \log_2 k + T_{\text{rp}}(n) \\
+  &\overset{\scriptscriptstyle (*)}{\leq} \frac{2c}{n-1} \left( (\log_2 n) \left( \frac{n(n-1)}{2} \right) - \frac{\frac{n}{2}(\frac{n}{2}-1)}{2} \right) + T_{\text{rp}}(n) \\
+  &= c \cdot n \log_2 n - c \left( \frac{n}{4} - \frac{1}{2} \right) + \underbrace{T_{\text{rp}}(n)}_{\leq c_{\text{rp}} \cdot n} \\
+  &\leq c \cdot n \log_2 n - \left( \frac{2c \frac{n}{2} (\frac{n}{2} - 1)}{(n-1)2} \right) + c_{\text{rp}} \cdot n \\
+  &\leq c \cdot n \log_2 n - c \cdot \left( \frac{n}{4} \frac{(n-2)}{(n-1)} \right) + c_{\text{rp}} \cdot n \\
+  &\leq c \cdot n \log_2 n.
+\end{align*}
+Damit der letzte Schritt geht, muss 
+\begin{align*}
+  c &\leq \frac{c_{\text{rp}}}{\frac{n}{4} \frac{n-2}{n-1}} \\
+  &= 4 c_{\text{rp}} \underbrace{\frac{(n-1)}{(n-2)}}_{\text{$\leq 2$ für $n > 2$}} \\
+  &\leq 8c_{\text{rp}}
+\end{align*}
+sein. Durch unsere Wahl von $c = \max\{T_{\text{rqs}}(1) + T_{\text{rp}}(2), 8 c_{\text{rp}}\}$ ist das der Fall.
+
+Jetzt gilt es nurnoch, die in Schritt $(*)$ getroffene Abschätzung der Summe $\sum_{k=1}^{n-1} k \log_2 k$ zu beweisen:
+\begin{align*}
+  \sum_{k=1}^{n-1} k \log_2 k & = \sum_{k=1}^{\ceil*{\frac{n}{2}}-1} k \underbrace{\log_2 k}_{\leq \log_2 \frac{n}{2}} +
+  \sum_{k=\ceil*{\frac{n}{2}}}^{n-1} k \underbrace{\log_2 k}_{\leq \log_2 n} \\
+  &\leq \sum_{k=1}^{\ceil*{\frac{n}{2}}-1} k (\log_2 n - 1) + \sum_{k=\ceil*{\frac{n}{2}}}^{n-1} k \log_2 n \\
+  &= \log_2 n \sum_{k=1}^{\ceil*{\frac{n}{2}}-1} k - \sum_{k=1}^{\ceil*{\frac{n}{2}}-1} k + \log_2 n \sum_{k = \ceil*{\frac{n}{2}}}^{n-1} k \\
+  &= \log_2 n \underbrace{\sum_{k=1}^{n-1} k}_{= \frac{n(n-1)}{2}} - \underbrace{\sum_{k=1}^{\ceil*{\frac{n}{2}}-1} k}_{\geq \frac{\frac{n}{2}(\frac{n}{2}-1)}{2}} \\
+  &\leq (\log_2 n) \left( \frac{n(n-1)}{2} \right) - \frac{\frac{n}{2}(\frac{n}{2}-1)}{2}
+\end{align*}
+
+
+Unsere vollständige Induktion ist damit bewiesen, und wir haben gezeigt, dass die durchschnittliche Laufzeit von $\texttt{randomized\_quicksort}$ in
+$\mathcal{O}(n \log n)$ liegt.