TU Wien:Algorithmen und Datenstrukturen VU (Szeider)/Zusammenfassung Test 1
Es gibt auch eine Zusammenfassung für den Stoff vom 2. Test.
Stable Matching[Bearbeiten | Quelltext bearbeiten]
Gale-Shapley-Algorithmus
Kennzeichne jede Familie/jedes Kind als frei
while ein Kind ist frei und kann noch eine Familie auswählen
Wähle solch ein Kind s aus
f ist erste Familie in der Präferenzliste von s,
die s noch nicht ausgewählt hat
if f ist frei
Kennzeichne s und f als einander zugeordnet
elseif f bevorzugt s gegenüber ihrem aktuellen Partner s'
Kennzeichne s und f als einander zugeordnet und s' als frei
else
f weist s zurück
Algorithmenanalyse[Bearbeiten | Quelltext bearbeiten]
Von der LVA-Leitung wurde ein Aufgabenblatt zum Üben der Algorithmenanalyse hochgeladen: Aufgabenblatt Algorithmenanalyse.pdf. Lösungen: Aufgabenblatt Algorithmenanalyse mit Lösungen.pdf.
- Instanz
- Eine Eingabe wird auch als Instanz des Problems, das durch den Algorithmus gelöst wird, bezeichnet.
- worst-case
- average-case
- best-case
Asymptotisches Wachstum[Bearbeiten | Quelltext bearbeiten]
" ist eine obere Schranke von ."
" ist eine untere Schranke von ."
" ist eine scharfe Schranke von ."
- Additivität
- (analog für Θ und Ω)
- Transitivität
- (analog für Θ und Ω)
Laufzeiten einiger gebräuchlicher Funktionen[Bearbeiten | Quelltext bearbeiten]
| Laufzeit | Notation | Beispiele |
|---|---|---|
| konstant | ||
| logarithmisch | binäre Suche | |
| linear | Maximumsuche, merge two sorted lists to one sorted | |
| n log n | Mergesort | |
| quadratisch | ||
| kubisch | ||
| polynomiell | ||
| exponentiell |
- Polynomialzeit
- Es existiert eine Konstante , sodass die Laufzeit in liegt.
Sortieren als praktisches Beispiel[Bearbeiten | Quelltext bearbeiten]
Selectionsort[Bearbeiten | Quelltext bearbeiten]
Suche kleinstes unsortiertes Element und tausche es mit dem ersten Unsortierten.
Wikipedia, worst, best & average-case: , instabil
Selectionsort(A):
for i ← 0 bis n − 2
smallest ← i
for j ← i + 1 bis n − 1
if A[j] < A[smallest]
smallest ← j
Vertausche A[i] mit A[smallest]
Insertionsort[Bearbeiten | Quelltext bearbeiten]
Füge unsortiertes Element an der richtigen Stelle ein.
Wikipedia, worst-case: , best-case: , average-case: , stabil
Insertionsort(A):
for i ← 1 bis n − 1
key ← A[i], j ← i − 1
while j ≥ 0 und A[j] > key
A[j + 1] ← A[j]
j ← j − 1
A[j + 1] ← key
Graphen[Bearbeiten | Quelltext bearbeiten]
G = (V,E)
n=|V|, m=|E|
| Adjazenzmatrix | Adjazenzliste | |
|---|---|---|
| Platzbedarf | ||
| Laufzeit adjazent | ||
| Aufzählen aller Kanten |
- Pfade und Zusammenhang
- Kürzeste Pfade und Distanz
- Kreis
- Baum
- Wurzelbaum
Breitensuche (BFS)[Bearbeiten | Quelltext bearbeiten]
Speichere Nachbarknoten in einer Queue, falls sie noch nicht entdeckt wurden. Wiederhole dies für alle Knoten in der Queue bis sie leer ist / der gesuchte Knoten gefunden wurde.
Wikipedia, worst case:
BFS(Graph, Start):
Discovered[v] ← false für alle Knoten v ∈ V
Discovered[s] ← true
Q ← {Start}
while Q ist nicht leer
Entferne ersten Knoten u aus Q
Führe Operation auf u aus
foreach Kante (u,v) inzident zu u
if !Discovered[v]
Discovered[v] ← true
Füge v zu Q hinzu
Tiefensuche (DFS)[Bearbeiten | Quelltext bearbeiten]
Rekursiver Aufruf für jeden Nachbarknoten, der noch nicht besucht wurde.
Wikipedia, worst case:
DFS(Graph, Start):
Discovered[v] ← false für alle Knoten v ∈ V
DFS1(Graph, Start)
DFS1(Graph, u):
Discovered[u] ← true
Führe Operation auf u aus
foreach Kante (u,v) inzident zu u
if !Discovered[v]
DFS1(G, v)
Zusammenhangskomponente[Bearbeiten | Quelltext bearbeiten]
Ein maximaler zusammenhängender Teilgraph. Ein nicht zusammenhängender Graph zerfällt in seine Zusammenhangskomponenten.
Zusammenhang in gerichteten Graphen[Bearbeiten | Quelltext bearbeiten]
- starker Zusammenhang
- jedes Paar von Knoten ist gegenseitig erreichbar
- schwacher Zusammenhang
- jedes Paar von Knoten ist unter Misachtung der Kantenrichtung von einander erreichbar
DAGs und topologische Sortierung[Bearbeiten | Quelltext bearbeiten]
- Gerichteter azyklischer Graph (Directed Acyclic Graph, DAG)
- Topologische Sortierung
Dijkstra-Algorithmus[Bearbeiten | Quelltext bearbeiten]
Dijkstra(G,s):
Discovered[v] ← false für alle Knoten v ∈ V
d[s] ← 0
d[v] ← ∞ für alle anderen Knoten v ∈ V \ {s}
L ← V
while L ist nicht leer
wähle u ∈ L mit kleinstem Wert d[u]
lösche u aus L
Discovered[u] ← true
foreach Kante e = (u,v) ∈ E
if !Discovered[v]
d[v] ← min(d[v],d[u]+le)Heap[Bearbeiten | Quelltext bearbeiten]
Ein Heap (Min-Heap) ist ein binärer Wurzelbaum, dessen Knoten mit ≤ total geordnet sind, sodass gilt:
- Ist u ein Kind von v, dann gilt v ≤ u (Heap-Eigenschaft für Min-Heap).
- Alle Ebenen von Knoten bis auf die letzte sind vollständig aufgefüllt.
- Die letzte Ebene des Baumes ist linksbündig aufgefült.
Ebenenweise Speicherung in Array (index 0 freigelassen):
- Nachfolgerknoten:
- Elternknoten
- Erstellen aus Array
- Einfügen
Element wird an Position eingefügt.
if i > 1
j ← ⌊i/2⌋
if H[i] < H[j]
Vertausche die Array-Einträge H[i] und H[j]
Heapify-up(H,j)
- Löschen
Element an Stelle wird auf gelöschte Stelle verschoben.
n ← length(H)-1
if 2 · i > n
return
elseif 2 · i < n
left ← 2 · i, right ← 2 · i + 1
j ← Index des kleineren Wertes von H[left] und H[right]
else
j ← 2 · i
if H[j] < H[i]
Vertausche die Arrayeinträge H[i] und H[j]
Heapify-down(H,j)
Greedy-Algorithmen[Bearbeiten | Quelltext bearbeiten]
Erstelle inkrementell eine Lösung, bei der nicht vorausschauend ein lokales Kriterium zur Wahl der jeweils nächsten hinzuzufügenden Lösungskomponente verwendet wird.
Interval Scheduling[Bearbeiten | Quelltext bearbeiten]
Ziel: Finde eine Teilmenge maximalen Gewichts von paarweise kompatiblen Jobs.
Sortierungsmöglichkeiten:
- früheste Startzeit
- früheste Beendigungszeit
- kleinstes Intervall
- wenigste Konflikte
Dabei hat sich erwiesen, dass eine Sortierung nach frühester Beendigungszeit am ehesten zu einem globalen Optimum führt.
Minimaler Spannbaum[Bearbeiten | Quelltext bearbeiten]
(Minimum Spanning Tree, MST)
Prim(G, c):
foreach (v ∈ V )
A[v] ← ∞
Initialisiere eine leere Priority Queue Q
foreach (v ∈ V )
Füge v in Q ein
S ← ∅
while Q ist nicht leer
u ← entnehme minimales Element aus Q
S ← S ∪ {u}
foreach Kante e = (u, v) inzident zu u
if v ∉ S und ce < A[v]
Verringere die Priorität A[v] auf ce
Prim ist besser für dichte Graphen und Kruskal ist besser für dünne Graphen.
Zwischenstopps auswählen[Bearbeiten | Quelltext bearbeiten]
Divide-and-Conquer[Bearbeiten | Quelltext bearbeiten]
Teile ein Problem in Teilprobleme auf. Löse jedes Teilproblem unabhängig und kombiniere die Lösung für die Teilprobleme zu einer Lösung für das ursprüngliche Problem.
Mergesort[Bearbeiten | Quelltext bearbeiten]
, stabil
- Teile Array in zwei Hälften.
- Sortiere jede Hälfte rekursiv.
- Verschmelze zwei Hälften zu einem sortierten Ganzen.
Merge(A,l,m,r):
i ← l, j ← m + 1, k ← l
while i ≤ m und j ≤ r
if A[i] ≤ A[j]
B[k] ← A[i], i ← i + 1
else
B[k] ← A[j], j ← j + 1
k ← k + 1
if i > m
for h ← j bis r
B[k] ← A[h], k ← k + 1
else
for h ← i bis m
B[k] ← A[h], k ← k + 1
for h ← l bis r
A[h] ← B[h]
Quicksort[Bearbeiten | Quelltext bearbeiten]
best & average: , instabil
Wähle ein Pivotelement , teile die Liste in zwei Teillisten, die linke enthält Elemente , die rechte Elemente . Sortiere die Teillisten rekursiv.
Inversionen zählen[Bearbeiten | Quelltext bearbeiten]
Brute-Force-Ansatz: Überprüfe alle Paare i und j. Falls i > j -> Inversion.
Laufzeit O(n^2)
Divide-and-Conquer: 1) Teile Liste in zwei Teile. -> O(1)
2) Zähle rekursiv die Anzahl der Inversionen in jeder Hälfte. (links und rechts) -> 2T(n/2)
3) Combine: Inversionen von linke Hälfte + Inversionen von rechte Hälfte + Inversionen linke-rechte Hälfte.
z.B. [3, 1, 4, 10, 5, 2]
1) Teile: [3, 1, 4] [10, 5, 2]
2) Inversionen auf linke Hälfte: {(3-1)} => 1 Inversionen
Inversionen auf rechte Hälfte: {(10-5, 10-2, 5-2)} => 3 Inversionen
3) Linke-rechte Hälfte: {(3-2), (4-2)}
Gesamt: 1 + 3 + 2 = 6
Laufzeit: O(n * log(n))
Dichtestes Punktpaar[Bearbeiten | Quelltext bearbeiten]
Suchbäume[Bearbeiten | Quelltext bearbeiten]
- Einfügen eines neuen Elements
- Suche eines Elements
- Entfernen eines Elements
- Durchlaufen aller Elemente in geordneter Reihenfolge
- Finden des kleinsten / größten Elements
- Finden eines nächstkleineren / nächstgrößeren Elements
- Durchmusterungen (Traversals)
- Inorder: linker Unterbaum, Wurzel, rechter Unterbaum
- Preorder: Wurzel, linker Unterbaum, rechter Unterbaum
- Postorder: linker Unterbaum, rechter Unterbaum, Wurzel
Wurzelbäume[Bearbeiten | Quelltext bearbeiten]
- Tiefe (Niveau) eines Knotens
- Anzahl der Kanten auf dem Pfad von der Wurzel zum Knoten
- Blatt
- Ein Knoten, wenn er keine Kinder besitzt, ansonsten innerer Knoten.
Binäre Suchbäume[Bearbeiten | Quelltext bearbeiten]
- binäre Suchbaumeigenschaft
- Für jeden Knoten gilt: alle Knoten im linken Teilbaum haben einen kleineren Schlüssel, alle Knoten im rechten Teilbaum einen größeren Schlüssel.
Balancierte Bäume[Bearbeiten | Quelltext bearbeiten]
- höhenbalanciert (AVL)
- gewichtsbalanciert
- (a,b)-Baum (2 ≤ a ≤ b)
AVL-Bäume[Bearbeiten | Quelltext bearbeiten]
- Höhe linker Unterbaum
- Höhe rechter Unterbaum
- balanciert
- Rebalancierung
| Rotation nach rechts | |
| Doppelrotation links-rechts | |
| Rotation nach links | |
| Doppelrotation rechts-links |
B-Bäume und B*-Bäume[Bearbeiten | Quelltext bearbeiten]
- B-Baum der Ordnung
- Blätter haben gleiche Tiefe und sind leere Knoten.
- Jeder Knoten hat bis zu Kinder.
- Jeder innere Knoten außer der Wurzel hat mindestens Kinder. Die Wurzel hat mindestens 2 Kinder.
- Jeder Knoten mit Schlüssel hat Kinder.
- Für jeden Knoten mit Schlüsseln und Kindern gilt: :
- Alle Schlüssel in sind kleiner gleich
- ist kleiner gleich allen Schlüsseln in
- ( bezeichnet den Teilbaum mit Wurzel )
B-Bäume wachsen immer an der Wurzel.
Hashing[Bearbeiten | Quelltext bearbeiten]
- Hashfunktion
- Divisions-Rest-Methode (m idealerweise prim)
- Multiplikationsmethode , (A ist irrational)
- Kollisionsbehandlung
- Verkettung der Überläufer: Jedes Element der Hashtabelle ist eine verkettete Liste
- offene Hashverfahren (Flag )
- lineares Sondieren
- quadratisches Sondieren
- Double Hashing
- Verbesserung nach Brent
Wahrscheinlichkeit für einen bestimmten Platz in der Hastabelle
Datenstrukturen in Java[Bearbeiten | Quelltext bearbeiten]
- Collection: verwaltet Objekte, wird nicht direkt implementiert
- Set: Collection ohne duplizierte Elemente
- SortedSet:
- List: Collection, die über den Index geordnet ist. Dupliziere Elemente sind gestattet.
- Queue: Verwaltung von Warteschlangen
- Dequeue: (double ended queue) Einfügen und Löschen von Elementen nur am Anfang und am Ende der Queue möglich
- Set: Collection ohne duplizierte Elemente
- Map: Verwaltung von Schlüsseln
- SortedMap: Elemente werden in aufsteigender Reihenfolge verwaltet.
TimSort: Kombi aus Merge und Insertionsort