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