Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • master
  • restructuring
2 results

Target

Select target project
  • 94830396EC94280B/datenstrukturen-und-algorithm-ss2020-skript
  • 6048DFF64EAA81BC/datenstrukturen-und-algorithm-ss2020-skript
2 results
Select Git revision
  • master
  • restructuring
2 results
Show changes
Commits on Source (8)
...@@ -49,6 +49,7 @@ Wobei \texttt{merge} folgendermaßen definiert wird: ...@@ -49,6 +49,7 @@ Wobei \texttt{merge} folgendermaßen definiert wird:
} }
\KwRet $\mathcal{A}$ \KwRet $\mathcal{A}$
\end{algorithm} \end{algorithm}
%TODO: REWRITE TO LISTS
\subsubsection{Laufzeit} \subsubsection{Laufzeit}
Die Laufzeit der Algorithmen ist nicht vom konkreten Input, sondern nur von der Länge des Inputs abhängig. Worst, best Die Laufzeit der Algorithmen ist nicht vom konkreten Input, sondern nur von der Länge des Inputs abhängig. Worst, best
...@@ -84,11 +85,11 @@ Wir müssen also nurnoch den asymptotischen Aufwand für die rekursiven Aufrufe ...@@ -84,11 +85,11 @@ Wir müssen also nurnoch den asymptotischen Aufwand für die rekursiven Aufrufe
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 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 $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 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. $T_\text{m}(n)$ zudem durch die Konstante $m = \max(\{T_\text{m}(i) \mid i \in \{0, \dots, n_0\}\})$ abschätzen.
Das erlaubt es uns, obige Summe aufzuspalten: 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-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) + \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)}. \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)}.
\] \]
...@@ -106,6 +107,6 @@ Dieser Term dominiert also alle anderen Terme, und damit $T_\text{ms} \in \mathc ...@@ -106,6 +107,6 @@ Dieser Term dominiert also alle anderen Terme, und damit $T_\text{ms} \in \mathc
In der hier vorgestellten Variante muss bei jedem Aufruf von \texttt{merge} ein neues Array angelegt werden. Damit braucht 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. $\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). Es gibt allerdings auch Weiterentwicklungen, die mit $\mathcal{O}(1)$ Speicher auskommen (z.B. TimSort oder blocksort).
...@@ -27,7 +27,7 @@ Reihenfolge). In der Sammelphase werden alle Kategorien entsprechend ihrer Ordnu ...@@ -27,7 +27,7 @@ Reihenfolge). In der Sammelphase werden alle Kategorien entsprechend ihrer Ordnu
$x \leftarrow \texttt{get}(\mathcal{Q})$ \; $x \leftarrow \texttt{get}(\mathcal{Q})$ \;
$\texttt{put}(\mathcal{Q}_{x_i}, x)$ \; $\texttt{put}(\mathcal{Q}_{x_i}, x)$ \;
} }
\For{ $j \rightarrow 0$ \KwTo $b-1$}{ \For{ $j \leftarrow 0$ \KwTo $b-1$}{
\While{$\mathcal{Q}_j$ \emph{is not empty}}{ \While{$\mathcal{Q}_j$ \emph{is not empty}}{
$\texttt{put}(\mathcal{Q}, \texttt{get}(\mathcal{Q}_j))$ \; $\texttt{put}(\mathcal{Q}, \texttt{get}(\mathcal{Q}_j))$ \;
} }
......
...@@ -200,7 +200,7 @@ Teilbaum, der Information im Node und einem rechten Teilbaum: ...@@ -200,7 +200,7 @@ Teilbaum, der Information im Node und einem rechten Teilbaum:
\text{BST}\; D &= ε\ |\; \text{BST}\; D\quad D\quad \text{BST}\; D \\ \text{BST}\; D &= ε\ |\; \text{BST}\; D\quad D\quad \text{BST}\; D \\
\mathcal{B}\quad &= ε\ |\;\quad l\qquad \ \ \ x\; \ \qquad r \mathcal{B}\quad &= ε\ |\;\quad l\qquad \ \ \ x\; \ \qquad r
\end{align*} \end{align*}
In dieser Notation beschreiben wir nun kombat die gängisten Operationen auf binären Suchbäumen in rekursiver Form: In dieser Notation beschreiben wir nun kompakt die gängigsten Operationen auf binären Suchbäumen in rekursiver Form:
Die Höhe ist $1$ + die Höhe des größeren Teilbaums: Die Höhe ist $1$ + die Höhe des größeren Teilbaums:
\begin{align*} \begin{align*}
...@@ -292,7 +292,7 @@ erreicht, wenn wir die Elemente gemäß ihrer Ordnung einfügen. ...@@ -292,7 +292,7 @@ erreicht, wenn wir die Elemente gemäß ihrer Ordnung einfügen.
Da die Laufzeit aller Algorithmen auf Binären Suchbäumen direkt von der Höhe abhängt, stellt sich die Frage: Da die Laufzeit aller Algorithmen auf Binären Suchbäumen direkt von der Höhe abhängt, stellt sich die Frage:
Was ist die zu erwartende Höhe eines Binärbaums, wenn man (eindeutige) Elemente in einer zufälligen Reihenfolge einfügt? Was ist die zu erwartende Höhe eines Binärbaums, wenn man (eindeutige) Elemente in einer zufälligen Reihenfolge einfügt?
\begin{proposition} \begin{theorem}
Werde $π \in S_n$, eine Permutation von $n$ Elementen (d.h. die Elemente $\{1,\cdots,n\}$ in einer zufälligen Reihenfolge Werde $π \in S_n$, eine Permutation von $n$ Elementen (d.h. die Elemente $\{1,\cdots,n\}$ in einer zufälligen Reihenfolge
ohne Wiederholungen), in einen initial leeren Binärer Suchbaum eingefügt. Sei $H_n$ die Zufallsvariable, ohne Wiederholungen), in einen initial leeren Binärer Suchbaum eingefügt. Sei $H_n$ die Zufallsvariable,
die die Höhe dieses zufällig befüllten Baumes beschreibt. die die Höhe dieses zufällig befüllten Baumes beschreibt.
...@@ -301,7 +301,7 @@ Was ist die zu erwartende Höhe eines Binärbaums, wenn man (eindeutige) Element ...@@ -301,7 +301,7 @@ Was ist die zu erwartende Höhe eines Binärbaums, wenn man (eindeutige) Element
\mathbb{E}[H_n] \in Θ(\log n). \mathbb{E}[H_n] \in Θ(\log n).
\] \]
\label{prop:BST_average_case_wachstum} \label{prop:BST_average_case_wachstum}
\end{proposition} \end{theorem}
\begin{proof} \begin{proof}
Die untere Grenze ist klar, da wie eingangs beschrieben die Höhe eines Baumes immer in $Ω(\log n)$ liegt. Die untere Grenze ist klar, da wie eingangs beschrieben die Höhe eines Baumes immer in $Ω(\log n)$ liegt.
...@@ -309,7 +309,7 @@ Was ist die zu erwartende Höhe eines Binärbaums, wenn man (eindeutige) Element ...@@ -309,7 +309,7 @@ Was ist die zu erwartende Höhe eines Binärbaums, wenn man (eindeutige) Element
Wird ein Element $i$ gezogen, befinden sich am Ende $i-1$ Elemente im linken Teilbaum und $n-i$ Wird ein Element $i$ gezogen, befinden sich am Ende $i-1$ Elemente im linken Teilbaum und $n-i$
Elemente im rechten Teilbaum. Elemente im rechten Teilbaum.
Die Höhe eines nichtlehren Baumes ist 1 + die Höhe des größten Teilbauem. Die Höhe eines nichtleeren Baumes ist 1 + die Höhe des größten Teilbaums.
Unter der Annahme, dass alle Elemente gleichwahrscheinlich gezogen werden, ist der Erwartungswert von $H_n$ einfach nur der Unter der Annahme, dass alle Elemente gleichwahrscheinlich gezogen werden, ist der Erwartungswert von $H_n$ einfach nur der
Durchschnitt aller möglichen Fälle: Durchschnitt aller möglichen Fälle:
\begin{equation*} \begin{equation*}
...@@ -318,15 +318,15 @@ Was ist die zu erwartende Höhe eines Binärbaums, wenn man (eindeutige) Element ...@@ -318,15 +318,15 @@ Was ist die zu erwartende Höhe eines Binärbaums, wenn man (eindeutige) Element
\end{equation*} \end{equation*}
Wir betrachten nun $Y_n = 2^{H_n}$: Wenn wir zeigen können, dass $\mathbb{E}[Y_n] \in \mathcal{O}(n^a)$, so folgt Wir betrachten nun $Y_n = 2^{H_n}$: Wenn wir zeigen können, dass $\mathbb{E}[Y_n] \in \mathcal{O}(n^a)$, so folgt
daraus das $\mathbb{E}[H_n] \in \mathcal{O}(a \log n) = \mathcal{O}(\log n)$. daraus, dass $\mathbb{E}[H_n] \in \mathcal{O}(a \log n) = \mathcal{O}(\log n)$.
In dieser exponentiellen Darstellung wird exponentielle Höhe nun durch \\$Y_n = 2 \max(Y_{i-1},Y_{n-1})$ beschrieben, In dieser exponentiellen Darstellung wird exponentielle Höhe nun durch \\$Y_n = 2 \max(Y_{i-1},Y_{n-1})$ beschrieben,
analog verhält sich der Erwartungswert von $Y_n$: analog verhält sich der Erwartungswert von $Y_n$:
\begin{equation*} \begin{equation*}
\mathbb{E}[Y_n] = \frac{2}{n} \sum_{i=1}^n \mathbb{E}[\max(Y_{i-1}, Y_{n-i})]. \mathbb{E}[Y_n] = \frac{2}{n} \sum_{i=1}^n \mathbb{E}[\max(Y_{i-1}, Y_{n-i})],
\label{eq:EW_Yn_1} \label{eq:EW_Yn_1}
\end{equation*} \end{equation*}
Wobei wir durch die Abschätzung $\mathbb{E}[\max(X,Y)]\mathbb{E}[X] + \mathbb{E}[Y]$ (gültig für nichtnegative wobei wir durch die Abschätzung $\mathbb{E}[\max(X,Y)]\mathbb{E}[X] + \mathbb{E}[Y]$ (gültig für nichtnegative
Zufallsvariablen $X$ und $Y$) und der Symmetrie der Summenterme weiter zu Zufallsvariablen $X$ und $Y$) und der Symmetrie der Summenterme weiter zu
\[ \[
\mathbb{E}[Y_n]\frac{2}{n} \sum_{i=1}^n (\mathbb{E}[Y_{i-1}] + \mathbb{E}[Y_{n-i}]) = \frac{4}{n} \mathbb{E}[Y_n]\frac{2}{n} \sum_{i=1}^n (\mathbb{E}[Y_{i-1}] + \mathbb{E}[Y_{n-i}]) = \frac{4}{n}
......
...@@ -49,7 +49,7 @@ Ist das Wurzelelement ein Blatt, so ist die Haldenbedingung immer erfüllt. ...@@ -49,7 +49,7 @@ Ist das Wurzelelement ein Blatt, so ist die Haldenbedingung immer erfüllt.
Um sonst die Haldenbedingung zu erzwingen, muss das Wurzelelement also mit dem Maximum seiner beiden Kinder getauscht werden. Um sonst die Haldenbedingung zu erzwingen, muss das Wurzelelement also mit dem Maximum seiner beiden Kinder getauscht werden.
Dabei wird die Haldenbedingung aber möglicherweise bei betauschten Kindknoten verletzt. Also rufen wir den Algorithmus dort noch einmal auf. Dabei wird die Haldenbedingung aber möglicherweise bei betauschten Kindknoten verletzt. Also rufen wir den Algorithmus dort noch einmal auf.
In Pseudocode aus der Array-Perspektive sieht das folgendermaßen aus (Der Pseudocode in Arrayperspektive ist eine In Pseudocode aus der Array-Perspektive sieht das folgendermaßen aus (Der Pseudocode in Baumperspektive ist eine
Übungsaufgabe): Übungsaufgabe):
\begin{algorithm}[H] \begin{algorithm}[H]
...@@ -144,7 +144,7 @@ sortiert das Array. ...@@ -144,7 +144,7 @@ sortiert das Array.
\paragraph{Laufzeit:} \paragraph{Laufzeit:}
Es reicht hier obige Abschätzung, dass $\texttt{heapify\_array}$ einen asymptotischen Aufwand von $\mathcal{O}(n \log Es reicht hier obige Abschätzung, dass $\texttt{heapify\_array}$ einen asymptotischen Aufwand von $\mathcal{O}(n \log
n)$ hat. Die Laufzeit wird von den $\frac{n}{2}$ aufrufen von $\texttt{heapify}$, welches $\mathcal{O}(\log n)$ Aufwand n)$ hat. Die Laufzeit wird von den $\frac{n}{2}$ Aufrufen von $\texttt{heapify}$, welches $\mathcal{O}(\log n)$ Aufwand
hat, eh dominiert. Also liegt die Laufzeit in $\mathcal{O}(n \log n)$. Damit ist $\texttt{heapsort}$ also worst-case hat, eh dominiert. Also liegt die Laufzeit in $\mathcal{O}(n \log n)$. Damit ist $\texttt{heapsort}$ also worst-case
optimal. optimal.
......
...@@ -47,7 +47,10 @@ maximal halb so hoch hängt wie eins auf der untersten Ebene. ...@@ -47,7 +47,10 @@ maximal halb so hoch hängt wie eins auf der untersten Ebene.
Dadurch folgt: Dadurch folgt:
\begin{lemma} \begin{lemma}
In einem nichtlehren Red-Black-Tree der Größe $n$ liegt die Höhe $h$ in $Θ(\log n)$. In einem nichtlehren Red-Black-Tree der Größe $n$ gilt:
\[
h ∈ Θ(n \log n).
\]
\label{lemma:RBT_height} \label{lemma:RBT_height}
\end{lemma} \end{lemma}
Die Details des Beweises sind eine Übungsaufgabe. Die Details des Beweises sind eine Übungsaufgabe.
...@@ -97,7 +100,7 @@ Dabei macht \texttt{balance} nichts, solange nicht einer der vier Fälle aus Abb ...@@ -97,7 +100,7 @@ Dabei macht \texttt{balance} nichts, solange nicht einer der vier Fälle aus Abb
\begin{align} \begin{align}
\begin{rcases} \begin{rcases}
\texttt{balance}(B\; a\; x\; (R\; b\; y\; (R\; c\; z\; d))) \\ \texttt{balance}(B\; a\; x\; (R\; b\; y\; (R\; c\; z\; d))) \\
\texttt{balance}(B\; (R\; a\; x\; (R\; b\; y\; c\;) z\; d)) \\ \texttt{balance}(B\; (R\; a\; x\; (R\; b\; y\; c\;)) z\; d) \\
\texttt{balance}(B\; (R\; (R\; a\; x\; b)\; y\; c)\; z\; d) \\ \texttt{balance}(B\; (R\; (R\; a\; x\; b)\; y\; c)\; z\; d) \\
\texttt{balance}(B\; a\; x\; (R\; (R\; b\; y\; c)\; z\; d)) \\ \texttt{balance}(B\; a\; x\; (R\; (R\; b\; y\; c)\; z\; d)) \\
\end{rcases} &= (R\; (B\; a\; x\; b)\; y\; (B\; c\; x\; d)) \\ \end{rcases} &= (R\; (B\; a\; x\; b)\; y\; (B\; c\; x\; d)) \\
...@@ -155,11 +158,12 @@ Dieses Ergebnis lässt sich noch verfeinern, da tatsächlich amortisiert $\mathc ...@@ -155,11 +158,12 @@ Dieses Ergebnis lässt sich noch verfeinern, da tatsächlich amortisiert $\mathc
kann: kann:
\begin{lemma} \begin{lemma}
Bei mehrfacher, sukzessiver Anwendung von \emph{\texttt{insert}} passieren lediglich $\mathcal{O}(1)$ Schreibaufrufe, also Bei widerholten Einfügen in einen Red-Black-Tree gibt es lediglich amortisiert $\mathcal{O}(1)$ Umstrukturierungsoperationen
Anwendungen der Regeln (3.1), (3.3) und (3.5). (Also Operationen wie in Abbildung \ref{fig:rbt_balance} beschrieben).
\label{lemma:rbt_amortisiert} \label{lemma:rbt_amortisiert}
\end{lemma} \end{lemma}
\begin{proof} \begin{proof}
TODO: Rework.
Wir beobachten zuerst, dass sich bei einer Anwendung der Regel (3.5) die Kapazität des entsprechenden Teilbaums Wir beobachten zuerst, dass sich bei einer Anwendung der Regel (3.5) die Kapazität des entsprechenden Teilbaums
verdoppelt: In jeder der vier Ausgangsfälle in Abbildung \ref{fig:rbt_balance} beträgt die Kapazität maximal verdoppelt: In jeder der vier Ausgangsfälle in Abbildung \ref{fig:rbt_balance} beträgt die Kapazität maximal
$4^{h'}$, wobei $h'$ hier die Anzahl der zu durchwandernden schwarzen Knoten auf den von der Wurzel dieses Teilbaums zu $4^{h'}$, wobei $h'$ hier die Anzahl der zu durchwandernden schwarzen Knoten auf den von der Wurzel dieses Teilbaums zu
......
...@@ -16,15 +16,17 @@ ...@@ -16,15 +16,17 @@
\usepackage{nccmath,mathtools} \usepackage{nccmath,mathtools}
\usepackage{unicode-math} \usepackage{unicode-math}
\usepackage{amsthm}
\newtheorem{theorem}{Theorem}[section]
\newtheorem{corollary}[theorem]{Corollary}
\newtheorem{proposition}[theorem]{Proposition}
\newtheorem{lemma}[theorem]{Lemma}
\newtheorem{conjecture}[theorem]{Conjecture}
\theoremstyle{definition} \theoremstyle{definition}
\newtheorem{definition}{Definition} \newtheorem{definition}[theorem]{Definition}
\newtheorem{example}{Beispiel} \newtheorem{remark}[theorem]{Remark}
\theoremstyle{plain} \newtheorem{example}[theorem]{Example}
\newtheorem{theorem}{Satz}
\newtheorem{proposition}{Proposition}
\newtheorem{lemma}{Lemma}
\usepackage{commath}
%custom math macros %custom math macros
\usepackage{mathtools} \usepackage{mathtools}
......
# default target at the top
Datenstrukturen_und_Algorithmen.pdf:
%.pdf: %.tex
latexmk -deps -deps-out=$*.d -xelatex --shell-escape -halt-on-error $<
-include *.d
.PHONY: clean
clean:
latexmk -pdflua -C $(NAME)
rm -f *.d
Kompilieren via `make` oder `latexmk -lualatex --shell-escpape Datenstrukturen_und_Algorithmen.tex`
Skript für die Vorlesung Datenstrukturen und Algorithmen, gehalten im Sommersemester 2020-2025 von von Florian Unger (TU Graz).
Das Skript basiert auf ein altes Vorlesungsskript von Oswin Aichholzer zur gleichnamigen Vorlesung (gehalten irgendwann um 1999 herum), wurde aber technisch vollkommen modernisiert und auch inhaltlich grundlegend überarbeitet. Die grundlegende Struktur wurde aber vererbt.
Fehlermeldungen bitte an florian.unger@tugraz.at oder via merge requests.
Langfristig wird eine CC-Lizenz angestrebt, wobei vorher noch urheberrechtliche Fragen geklärt werden müssen.