Name Erfinder Typ Idee/Vorgehen Implementation Laufzeit/Lösungsgüte
A-Sort
Algorithmus ARRAY von vorne nach hinten durcharbeiten
- neue Zahl immer zuhinterst hinstellen
- soweit nach vorne rücken, bis richtiger Platz
erreicht (= um # Inversionen vorschieben)

Summe aller Abstände jeweils vom rechten Rand =
# Inversionen der Ausgangsfolge


Abstrakter Datentyp
Theorie Der ADT ist eine Hülle, die vom Server bereitgestellt wird mit genau definierten Schnittstellen.

Der Benutzer erweitert den ADT um die Inhalte, die er braucht, liefert ev. weitere Prozeduren (Vergleich etc.).
Er kümmert sich aber nicht um die eigentlichen Vorgänge mit seinen Daten sondern nur um die Ergebnisse.

Der Client hat nur auf die exportierten Prozeduren und Objekte Zugriff


Additionsrätsel
Algorithmus ARRAY mit n Ziffern,
6 9 2 5 0 2 1 3 --> 69 + 2 + 5 + 0 + 21 + 3 = 100
Wie zusammennehmen/plus setzen, so dass Summe = 100?

PROCEDURE Add(i, sum, aktsum)
BEGIN
IF (i=n) OR (sum+aktsum>100) THEN
RETURN sum+aktsum=100;
ELSE RETURN Add(i+1, sum+aktsum, A[i])
OR Add(i+1, sum, aktsum*10+A[i]);
END;


Variante dynamisch:

O(n^3)


Aktienaufgabe, sooft wie man will einsteigen
Algorithmus immer mit Nachfolgetag vergleichen
falls A[i+1] höher als A[i] dann kaufen/behalten, sonst verkaufen

O(n)
Algorithmenanalyse, Oh, Theta, Omega
Theorie O: Es gibt eine obere Grenze, einen möglichst
kleine Fkt g(n), für die gilt:
f(n)<= c1*g(n) + c2
oder
f(n)<= c*g(n) für alle n >=n0


Omega: Es gibt eine möglichst grosse untere Grenze
mit Funktion h(n):
h(n) e O(f(n))

Theta: Der Algorithmus hat die gleiche Fkt als obere
und untere Schranke

Theta = O & Omega


Amortisierte Kostenanalyse (Bankkontenparadigma)
Theorie Z.B: Multidq in Q:
Bei jedem enQ wird zusätzlich zu effektiven Kosten (=1 pro enQ) noch ein 2. Franken einbezahlt. Damit wird das deQ und multidQ gratis

bal i : Kontostand nach i-ter Operation, balance
bal 0:=0
bal ist gleich der # der Elemente in Q

zB. Zähler 010001010001001:
Bei jedem Bit „1“ muss 1 Franken bereit liegen, weil ein Wechsel an dieser Stelle einen
weiteren Wechsel an der vorderen Stelle nach
sich zieht. Bei jedem Weiterzählen werden also
2 Franken bezahlt (einer für Konto)

a: amortisierte Kosten
t: tatsächliche Kosten

a i = t i + (bal i - bal i-1)
(Stand Konto vorher nachher)
Für alle Operationen aufgerechnet:
sum(a i) = sum(t i) + sum (bal i - bal i-1)
= sum(t i) + (bal Schluss - bal iAnfang)
--> sum(a i) >= sum(t i )


AVL-Bäume Adelson-Velskij, Landis Datenstruktur Für jeden Knoten gilt:
Differenz Höhe linker TB und rechter TB <=1
(-1: links höher, +1: rechts höher)
--> Jeder Knoten führt noch einen Parameter Balance mit

Bei Einfügen, Entfernen sind ev. Rotationen nötig
(Einfach bzw. Doppelrotationen)

# Rotationen: Einfügen: <=1
Entfernen: <= log(n) schlääääächt!

Anzahl Blätter möglichst klein, # Blätter=Fib (H+2)

Höhe ~1.44 * log (n)

Suche O(log n); Ins O(n); Del O(log n)
B-Bäume Bayer, Mc Creight Datenstruktur Viel Zeit wird verbraucht für Festplattenzugriff, wenn benachbarte Knoten an verschiedenen Orten gespeichert sind. --> viele Knoten zu einem Knoten zusammenfassen.

Effizienzmass: # Plattenzugriffe statt # Schlüsselvgl

B-Baum der Ordnung 3:
- alle Blätter haben gleiches Niveau
- jeder Knoten ausser Wurzel hat mind. m/2 Kinder,
m/2-1 keys

- Wurzel: >=2 Kinder
# Blätter bei Höhe H (= # keys +1)
mind höchstens
2.(m/2)^h m^h

--> n<= (m/2) -Logartihmus von ((n+1)/2)

Speicherplatznutzung >=50%, Im Mittel 69%


Was ist Differenz zu 2-3 Baum?

alles O(logm (n))
Backtracking n Damen
Algorithmus Allgemeiner Backtracking Algorithmus

ok:=FALSE;

PROCEDURE FindeLsg(i: Index, VAR ok: BOOL, VAR L: Lösung);
BEGIN
WHILE ~ok DO
IF Teillösung bisher ist gültig THEN
erweitere um einen Schritt
IF Lsg noch nicht vollständig
FindeLsg(i+1, ok, L);
IF ~ok THEN Backtracking
nimm den letzten Schritt zurück
END;
ELSE ok:=TRUE;
END;
Wähle nächstes Element zum Ausprobieren
END:


Bellmannsche Optimalitätsbedingung
Theorie Wenn Gesamtlösung optimal ist, muss auch jede Teillösung optimal sein.

Aus diesem Grund lassen sich die Probleme mit der dynamischen Programmierung lösen, weil dort immer für kleine Teilbereiche eine optimale Lösung gesucht wird.


Bin-Packing-Problem
Algorithmus online Algorithmus, Behälter (Bins), alle gleich gross, es kommen immer ein Gegenstand nach dem andern, der verpackt werden muss.

Wenn er noch Platz hat, kommt er in den gleichen, wenn nicht, kommt er in den nächsten, in dem er Platz hat

Lösungsgüte = 2

Es gibt höchstens 1 Bin, der weniger als halbvoll ist (sonst hätte ich ja den Ggstand im 2. halbvollen zum
1. halbvollen reingetan)


Binäre Suche
Algorithmus In geordnetem ARRAY:
Es wird ein bestimmtes Element zB
Mittelelement m ausgewählt, mit key
verglichen.

Falls key>m, in rechter, sonst in linker Hälfte
weitersuchen.

Bei IF Abfrage nicht zuerst x=m fragen!

O(log n)
Bipartites perfektes Matching
Algorithmus Männer, Frauen, Kante bedeutet: will heiraten

online Algorithmus:

Alle Männer schon gegeben, Frauen kommen einzeln dazu

Wähle die erste Kante zu einem noch freien Mann

ergibt eventuell kein perfektes (maximum) Matching,

aber immerhin ein maximal Matching, d.h. es ist keine Verbesserung des Resultats durch hinzufügen von Kanten möglich


Blumenschaufenster
Algorithmus Es hat n Vasen, die fest positioniert sind, dazu kommen n Blumen, m<=n. Zu jeder Kombination Vase und Blume gibt es einen Wert. Welches ist die optimale Anordnung?

Dynamisch:
Senkrecht Blumen, waagrecht Vasen
Immer 1. Blume einer Reihe: Diagonal von oben übertragen und W[i,j] zum Wert dazuaddieren.
Für den Rest der Zeile: Max( Feld links (Blume nicht in diese Vase), Feld diagonal links oben + W[i,j] (Blume kommt in diese Vase))


Bohnen im Topf
Theorie Beliebige Anzahl weisse und schwarze Bohnen im Topf. Immer 2 ziehen: Falls 2 gleiche: beide raus, 1 schwarze rein, Falls 2 verschiedene: schwarze raus, weisse zurück.

terminiert? ja: nach jedem Ziehen hat sich die Anzahl Bohnen um 1 verringert

Schlusszustand:
je nach Anfangszahl weisse: Falls Gerade: Ende mit 1 Schwarzen, sonst mit 1 Weissen.
(Invariante: immer entweder -2 oder +-0 weisse --> gerade/ungerade bleibt immer erhalten)


Bubble-Sort
Algorithmus Immer zwei benachbarte tauschen, falls sie in der falschen Reihenfolge sind.

Im Worst Case muss das hinterste ganz nach vorne --> n mal die Vertauschungen durchlaufen


PROCEDURE Bubblesort (VAR A: ARRAY OF INT);
VAR changed:BOOLEAN;
i, temp:INTEGER;
BEGIN
REPEAT
changed:=TRUE;
FOR i:= 1 TO (N-1) DO
IF A[i] > A[i+1] THEN
temp:=A[i]; A[i]:=A[i+1];
A[i+1]:=temp;
changed:=FALSE;
END;
END;
UNTIL changed:
END Bubblesort;

O(n^2)
Computertomographie
Algorithmus quadratische Matrix, immer pro Reihe und pro Spalte ist die Anzahl schwarzer Felder vermerkt, Wie findet man eine korrekte Matrix?

Zeile und Spalte werden mit DIV bzw MOD berechnet, damit kontinuierlich vorwärts gezählt werden kann.

Dann wird das ganze rekursiv laufen, 1. Variante: leer lassen --> zum nächsten Feld
2. Variante: setzen, ist nur mögliche falls in dieser Zeile und Spalte noch # schwarze > 0, nach setzen in entsprechender Zeile, Spalte je 1 abzählen

Schlussbedingung: IF pos=n*m THEN



Das Spiel Go
Algorithmus Anzahl Blöcke einer Farbe finden -
-> für jedenStein der Farbe kontrollieren,
ob er an einen eigenen anstösst
(in 4 Richtungen ausschwärmen,
wenn ja, Stein löschen,
wenn nein: INC (# Blöcke)


Gibt es einen Block der Farbe, der mit einem gegnerischen Stein eingeschlossen werden könnte?

Für jeden Stein # Luftlöcher ermitteln. Falls Stein nur einen freien Platz hat, kennzeichnen und zurückmelden, dass nur 1 Luftloch


Dijkstra Programmiersprache Dijkstra Theorie Nur 4 Operationen:

- Nulloperation , skip

- Zuweisung (mehrfach möglich, simultan (x,y := 1, x+1)

- Bewachte Anweisung, offen falls Boolsche Wache =
TRUE
if a<b --> x:=b fi

- Alternative: Falls mindestens eine Boolsche Wache offen,
dann wähle eine offene aus. Wenn keine mehr offen: Fehlerhalt
if a<b --> x:=b | a>=b --> x:=a fi

Repetition: Solange mindestens eine Bool Wache offen,
wähle eine offene aus und führe sie aus
do a<b --> a,b := b,a
| b<c --> b,c := c,b
od {a <= b <= c } (Kommentar)

nicht deterministisch, mehrere Abläufe möglich, ist ideal um einen Ort zu finden, an dem mehrere Variablen gleich sind (a nicht kleiner als b, b nicht kleiner als c, c nicht kleiner als a --> a=b=c)


Durchschnittsberechnung (Zero-Knowledge)
Algorithmus 3 Einkommen, A, B und C, es soll Durchschnitt berechnet werden, ohne dass man ein Einkommen preisgeben muss:

Jeder teilt sein Einkommen in 3 beliebige Teile, zB A1, A2 und A3.

So erhält jeder 3 Teile zB A2, B2 und C2. Aus diesen 3 Teilen bildet er nun die Summe und meldet die zurück.

Aus diesen 3 Summanden kann nun der Durchschnitt gebildet werden.


EBNF Notation
Theorie Mögliche Verbindungen:
- Konkatenation: A B (aneinanderhängen)
- Alternative: A | B
- Option: [ A ] (entweder 1 x oder 0 x das „A“ = entweder A oder nichts)
- Repetition: { A } (entweder 0x oder 1x oder 2x oder.... das A = „ „ oder „ A „ oder „AA“ oder „AAA“ oder...)

Extended Backus Naur Form

EBNF beschreibt sich selber:

Syntax = { Production }.
Production = Name „ = „ Expression „ . „.
Expression = Term { „ | „ Term }.
Term = Factor { Factor }
Factor = Name | String | „ { „ Expression „ } „ | „ [ „ Expression „ ] „ | „ ( „ Expression „ ) „.


Editierdistanz
Algorithmus Wie nahe sind 2 Worte beeinander?

Es wird immer das ein Zeichen vom oberen und 1 vom unteren Wort betrachtet.
Fall 1: oben und unten gleich --> keine Abweichung
Fall 2: oben und unten verschieden --> Abweichung +1
Fall 3: oben leer --> Abweichung +1
Fall 4: unten leer --> Abweichung +1

Dynamisch lösen:

1 Wort senkrecht, anderes waagrecht
Diagonal: +1 falls verschieden, + 0 falls gleich
nach rechts: + 1
nach unten: + 1

immer Minimum wird ausgewählt


rechts unten bestes Resultat


Effizientes Mergesort mit versch. Bändern
Theorie Bänder verschiedener Länge, L4, L15, L5, L2

Wie ist der beste Ablauf, um möglichst wenig Operationen zu haben?

zB. L4 + L15 --> 19 Operationen
L2 + L5 --> 7 Operationen
Resultate verschmelzen: 26 Operationen
TOTAL: 52 Operationen

Ideal: L2 + L4, Ergebnis mit L5, Ergebnis mit L15
= 6+11+26 Operationen = 43 Operationen

Ideal, wenn die Läufe möglichst gleich lang sind
(bei Merge L2 und L15 viele vergebliche Op.)


Exponentielle Suche
Algorithmus Binäre Suche nur bei endlicher Datenmenge möglich

bei unendlicher Menge, sortiert:

Beginn bei A[1], vergleichen, falls key > A[1]:
um 2, 4, 8, 16, .... Schritte nach rechts gehen

O(log k); k: effektive Position des Schlüssels

O (log k)
Färben von Graphkanten online
Algorithmus Bei jeder Kante, die neu dazukommt, wird bei Farbe 1 begonnen und solange hochgezählt, wie die Farbe schon bei einem der beiden Endknoten benutzt wird.

--> Lösungsgüte <=2

Grund: x:= höchste im Graph vorkommende
Knotengradzahl

vor Einfügen der Kante haben beide Knoten
höchstens x-1 Kanten, die höchste Farbe, die
ich für die neue Kante also wähle ist (2*x)-1,
da aber der Graph einen Knoten mit Grad x
hat, brauche ich auf jeden Fall mindestens x
Farben


fehlerresistenter Zahleneinleser
Algorithmus Es sollen Ganzzahlen eingelesen werden,
bei jeder Ziffer wird der aktuelle Wert berechnet,
bei einer falschen Eingabe soll kein Trap entstehen

--> Eingabe als CHAR
ORD(ch) - ORD(„0“) berechnen
Falls das zwischen 0 und 9 ist:
alte Zahl *10 + neue Ziffer

Für komplexere Eingabemöglichkeiten:

gerichteten Graphen aufzeichnen


O (n)
Ferien von 5 Freunden planen
Algorithmus Wollen gemeinsam Ferien machen, gibt es einen Tag, an dem es allen geht?

Datenstruktur?
- ARRAY N+1,356 OF INTEGER,
pro Freund eine Zeile + 1 Auswertung

1 Tag: Auswertung berechnen,
Finde, ob A[0,i]=5

14 Tage mit möglichst vielen:
ARRAY 5 OF INTEGER, Init mit 356
darin immer wenn in Auswertung ansteigt,
eintragen.
wenn fällt: Für alle Werte grösser als Ausertung
neu schauen, ob schon 14 Tage seit Anstieg,
wenn ja vgl mit Maxbisher, ev. ändern


Finde 2 Zahlen mit Summe = 100
Algorithmus ARRAY mit Ganzzahlen, pos und neg, aufsteigend geordnet.

1.Var: von links nach rechts:
nimm Zahl, such im Rest vom ARRAY mit
binärer Suche ob Gegenstück vorhanden
O( n log n)

2. Var: 2 Indexvar, eine am Anfang, eine am Schluss,
betrachte Summe
IF sum < 100 THEN INC (links);
ELSIF sum> 100 THEN DEC (rechts);
ELSE RETURN found;
END;


Finde Nullstelle, Dijkstra
Algorithmus Einheitsintervall mit garantierter Nullstelle,
Funktion streng monoton steigend,
effizienter Algorithmus gesucht,
Treffergenauigkeit: Abweichung <0.001

x:=0; step:=0.5;
do (step>0.001) & (f(x)>0) --> x:=x-step; step:=step/2
(step>0.001) & (f(x)<0) --> x:=x+step; step:=step/2
od;


Geschichtete Bäume
Datenstruktur auch: stratified tree

4 Grundtypen sind zugelassen (statt nur 1 Knoten), ev. für Wurzel noch spezielle Regeln

Einfügen: aus Blatt inneren Knoten machen,
Kontrolle ob immer noch einer der
Grundtypen,
sonst: Push up, die Schichten werden
nach oben verlagert, falls bis Wurzel
weitergeht:
Baum wächst in der Höhe um 1

Suche: O(log n)

Einfügen: Suchen: O(log n)
Strukturänderung O(1)
Schichänderung O(log n)

Entfernen dito



Graphenrepräsentation
Datenstruktur Adjazenzmatrix:
gut geeignet für viele Kanten, braucht n^2
Speicherplatz, Eintrag ist Verbindungslänge
bzw. TRUE falls Verbindung besteht.

Adjazenzliste:
Liste mit allen Knoten drin, angehängt an jedem die Liste mit den Knoten, mit denen
er verbunden ist.


Graphentraversierung (breadth, depth)
Algorithmus Breitensuche:
Beginn bei Knoten v, alle Knoten, die von v
aus direkt erreicht werden können, werden in
eine Queue eingetragen. Dann wird der
vorderste Knoten der Queue abgearbeitet und
wieder alle Knoten, die von dort erreichbar
sind, angehängt.

Vorteil: Kreisförmiges Suchen, es wird mit
Sicherheit die kürzeste Verbindung zu einem
anderen Knoten zuerst gefunden

Tiefensuche:
Vom Startknoten aus werden die direkt
erreichbaren Knoten auf einen Stack
geschrieben. Nun wird das gleiche immer mit
dem obersten Knoten auf dem Stack
wiederholt, bis gefunden oder bis Sackgasse,
dann nächster Knoten --> Backtracking


Handelsreisenden Stationen, Dijkstra

4 Handelsreisende, gleiche Routen,
machen an verschiedenen Orten Station,
schreiben sich immer Tageskilometer auf.
Haben sie einmal an gleichem Ort übernachtet?

Bedingung: A[i]=B[j]=C[k]=D[l|

i,j,k,l:=0,0,0,0
do A[i]<B[j] --> i:=i +1
B[j] < C[k] --> j:=j + 1
C[k] < D[l] --> k:=k+1
D[k] < A[i] --> l:=l + 1
od


Hashing mit Ueberlauf
Datenstruktur Die Kollisionen werden als lineare Liste an das ARRAY angehängt. Falls der key nicht am richtigen Ort im ARRAY steht, wird die Liste traversiert

Nachteil: - 2 verschiedene Datenstrukturen
- Zeitverlust beim Traversieren, falls
viele Kollisionen auftreten



Hashing, offen; double hashing
Datenstruktur Bei Kollisionen werden die Daten in noch freie Plätze eingewiesen. Konstante Sprungweite ungeschickt.
--> 2 Hashfkt.
h(x): 1. Adresse wird erzeugt
g(x): Sprungweite wird festgelegt

Wenn Key nicht an 1. Adresse gefunden wird, springe nach unten bis du hast. Falls du auf leeres Feld triffst --> nicht in Liste enthalten

Vorteil: - nützt den Speicherplatz gut aus
Nachteil: - kompliziert

Problem delete: Bei Löschen muss ein Dummy „deleted“ eingefügt, damit nicht Suche fälschlicherweise abgebrochen wird.

Aber: irgendwann meiste Zellen voll oder deleted
--> lange Suche

delete nicht gut gelöst

Loadfactor = # Einträge / # Zellen

sinnvoll zwischen 0.4 und 0.8


Hashing, perfekt
Datenstruktur Alle Einträge müssen schon bekannt sein,
die Hashfunktion wird so gewählt, dass keine Kollisionen auftreten

zB: Compiler, reservierte Wörter

ev. mit Fallunterscheidung
IF x=0 THEN h(x):=8;
ELSE h(x):=x DIV 3;
END;


Hashing, uniform
Datenstruktur Alle Ausgangswerte im ARRAY S werden gleichoft gesucht, S sehr gross

S wird einfach komprimiert, d.h.es werden jeweils mehrere Daten in gleiche Adresse in A geschrieben

Die Ordnung bleibt erhalten

ist aber gar nicht der Normalfall


Heap
Datenstruktur Elemente eigentlich in einem ARRAY gespeichert.
In einem max-Heap ist jedes Element i grösser als die Elemente 2*i bis 2*(i+1)-1; in Baumdarstellung grösser als seine 2 Kinder --> Max ist immer an Wurzel.

Heap erstellen:
ab Mitte (len DIV 2) bis nach vorne immer Elem.
versickern lassen

Siftdown:
Das Element tauscht mit dem grösseren seiner
Kinder die Position. Das wird sooft wiederholt,
bis das Element keine Kinder mehr hat.

Neue El in Heap einfügen:
an hinterste neue Position stellen, falls < als Vorgänger
nach oben wandern lassen.

Erstellen: O(n)
Heapsort
Algorithmus Ungeordnetes ARRAY

zuerst Heap herstellen (Vordere Hälfte Siftdown)

dann:
- Maximum aus Wurzel mit höchstem Index (n) tauschen
- Wurzel versickern lassen
- wiederholen für ARRAY 1..n-1


O(n log n)
Horner-Schema
Algorithmus Möglichkeit für Polynom-Herstellung

(((((an)*x+an-1)*x + an-2)*x + an-3)*x + ......)*x+ a0


Huffman-Bäume Huffman Datenstruktur optimaler (kürzester) Präfixfreier Code für Schlüssel mit gegebenen Häufigkeiten:

--> immer die 2 mit den kleinsten Häufigkeiten zusammenfassen, ein Ast 0, ein Ast 1

A B C D
0.5 0.1 0.1 0.3

0.2

0.5

1

A=0, B=100, C=101, D=11

Wird in Heap verwaltet:
Min1 holen, Min 2 holen, (Min1 + Min2) einfügen


Induktives Beweisen
Theorie Eine zB. durch Teleskopieren gefundene Formel wird mit Induktion bewiesen.

Aus Teleskopieren:
T(2)=1,
T(n)=2*T(n/2)+2 ist von der Grössenordnung 3/2*n -2

Ind. Verankerung: n=2:
3/2*2-2 = 1, ok.

Ind. Schritt: n-->2*n
T(2n) =2*T(n)+2= 2*(3/2*n-2)+2
=3n+2=3/2*2n+2, ok.


Interpolationssuche
Algorithmus In geordnetem ARRAY:
Aufgrund Annahme der ungefähren Gleichverteilung kann mit Hilfe der # Elemente und des Wertebereichs die ungefähre wahrscheinlichste Position ermittelt werden.

(A[n] - A[0]) / (n-0) = (key - A[0]) / (pos - 0)

Worst Case: O(n)

im Mittel (bei Gleichverteilung): O(log(log(n))

zwischen O(log(log n)) und O(n)
Intervalleinschluss
Algorithmus Problem: Finde Intervalle, die ganz in einem
anderen Intervall enthalten sind.

naiv: Jedes mit jedem Vergleichen O(n^2)

Induktion:

Bedingung: Intervall n ist immer das Int. mit
rechtestem linkem Endpunkt.

bisher weitester rechter Endpunkt xrechts
muss gespeichert werden.

Falls xrechts > rechter Rand von Int n
--> eingeschlossen
Gibt es Int., die Int. n einschliesst?
--> Müssten gleichen linken Rand haben
--> Zusatzbedingung: nimm bei mehreren mit gleichem
linken Ende immer zuerst das Längste

Vergleiche: O(n)
Intervalle nach linkem Rand ordnen: O(n log n)


K - Zentrum
Algorithmus gegeben eine Menge von Punkten in 2 Dim., gegeben eine Anzahl k Clusters/Gruppen

Wie kann ich die Clusters so wählen, dass die Radien der Cluster möglichst klein sind?

- wähle einen beliebigen Punkt als Zentrum 1.
- nimm als nächstes den Punkt, der am weitesten vom Zentrum 1 entfernt ist als neues Zentrum.
- suche nun den Punkt, dessen Distanz zum nächsten Zentrum maximal ist (alle anderen Punkte haben innerhalb einer kleineren Distanz irgend ein Zentrum) und wähle den als neues Zentrum

wiederhole sooft, bis k Zentren gefunden, nun müssen die Punkte noch den k Clustern zugeordnet werden

Lösungsgüte = 2


Kürzeste Wege im Graphen Ford, Bellman Algorithmus Breitensuche in Graph
Anfangsbedingungen: Startknoten hat 0 als Distanz, alle anderen haben MAX(INT).

Nun werden alle Knoten angeschaut, die vom Startknoten aus zu erreichen sind. (=Rand)
Falls der Wert bei diesem Knoten grösser ist, als bei einem anderen Nachbarknoten + Weglänge zwischen diesen beiden, so wird der Wert geändert (relabel)


Kürzeste Wege im Graphen Dijkstra Algorithmus Aufteilung in Kern, Rand und unbekannt.
Anfang: Kern: Startknoten
Rand: alle Knoten, die vom Startknoten direkt
erreicht werden können.

Nun wird der Randknoten(=r) mit der kleinsten Distanz zum Start dazugenommen. Jede Linie die von r weggeht wird bearbeitet.

Fall 1: zu Knoten im Kern: nichts tun.
Fall 2: zu Randknoten: Weg via r mit bisherigem Eintrag
vergleichen, ev. verbessern
Fall 3: zu unbekanntem Knoten: wird neu in Rand aufgenommen
mit der Distanz via r

Aufwand: jedesmal Minimum aus Rand suchen O (n)
jedesmal Pfeilen folgen c*n

O(n^2)

Idee: Rand als Heap verwalten, falls nicht zuviele Kanten ist das besser (O (m* log(n)))


Kunstwerk im Kunstwerk
Algorithmus Implementation für :
Kunstwerk ist Quadrat mit Seitenlänge S,
kann entweder mit einer von 4 Farben ausgemalt
werden oder mit 4 x 4 neuen Kunstwerken rekursiv
gefüllt werden.

EBNF:
Kunstwerk = rot | blau | gelb | grün | 4x4 Kunstwerk.

PROCEDURE Kunstwerk*(x,y,Seitenlänge:INT);
BEGIN
IF Read=“r“ THEN....
ELSIF Read=“Kunst“ THEN
FOR i:=0 TO 3 DO
FOR j:=0 TO 3 DO
Kunstwerk (x+i*Seit, y+j*Seit, Seit/4);
END;
END;
END;


Lineare Liste für Wörterbuch
Datenstruktur Erfolglose Suche:
unsortiert:
Search : n Operationen
sortiert:
Search : n/2 Operationen

Worst Case:
unsortiert:
Search O(n)
Insert: O(1)
Delete: O(n)

sortiert:
Search O(n)
Insert O(n)
Delete O(n)


Lineare Suche
Algorithmus In ARRAY oder linearer Liste (geordnet oder ungeordnet)

Die Elemente werden von links nach rechts kontrolliert.

Im Mittel: n/2 Kontrollen

Worst Case: n Kontrollen

O(n)
Liniensegment - Schnittproblem
Algorithmus horizontale und vertikale Liniensegmente im R^2 verteilt.

von jeder Linie Anfang(x,y) und Ende(x,y) bekannt.

naiv: jede Linie mit jeder vergleichen --> Laufzeit O n^2

Variante:

Sweep- Line, Scanner von links her, Menge der y-Werte der aktuellen horizontalen Linien mitführen, bei Beginn bzw Ende einer horizontalen Linie Menge wieder aktualisieren.

Immer von einer vertikalen Linie zur nächsten springen, kontrollieren, hat es in Menge einen y Wert, der zwischen Anfang und Ende der vertikalen Linie liegt? Wenn ja: Schnittpunkt noch registrieren

statt Menge mitführen auch möglich: y Werte der horizontalen Linien in einem Baum ablegen, eventuell Blätter untereinandern noch verknüpfen,
Dann einfach nach yEndwerten der senkrechten Linie suchen.


O (n log (n))
Lokale Suche
Algorithmus Beginn mit einer willkürlichen Lösung

Vergleiche mit unmittelbaren Nachbarn,
falls einer der Nachbarn besser ist, wechsle¨

falls innerhalb einer bestimmten Anzahl Schritte kein Wechsel passiert ist, brich ab.

Je nach Lösungslandschaft kann es sein, dass man nur ein lokales, nicht sehr gutes Maximum findet.


Longest common subsequence
Algorithmus 2 Zeichenfolgen, welches ist längstmögliche Zeichenfolge, die in beiden vorkommt (Buchstaben dürfen ausgelassen werden)

X= A B C D E D A G N D G E E
Y= T A B W D W G N A A E G E

Lcs= A B D G N G E

Dynamisch:
Gitter, 1 Wort senkrecht, das andere Waagrecht
0 initialisieren

3 Möglichkeiten:
1. Diagonal nach rechts unten: beide
Buchstaben genommen, Wert von links
oben +1 eintragen
2. Von oben: im senkrechten Wort 1 Buchst
ausgelassen
3. Von links: im waagrechten Wort 1 Buchst.
ausgelassen,

Immer Maximum wird eingetragen, im Feld rechts unten steht die maximale Länge der LCS


Masse für Vorsortiertheit
Theorie zB # Runs
Ein Run innerhalb einer Folge ist eine Teilfolge,
in der die Werte nur ansteigen

zB # Inversionen
Wieviele Elemente in Folge hinter Element x
sind kleiner als Element x

~Anzahl Vertauschungen, um zur richtigen
Reihenfolge zu kommen


Matrixmultiplikation Strassen Algorithmus Ueblicherweise Matrixmulitplikation
m x n * n x p - Matrizen braucht m*n*p Multipl/Add.

---> O (n^3)

Dank Zerlegung in 7 Blockmatrizen nun nur noch O (n^2.81....)

O (n^3) bzw. O (n^2.81.....)
Max Punktzahl in Prüfung
Algorithmus N Aufgaben, jede Aufgabe gibt Punkte W[i], braucht Zeit Z[i], wie findet man optimale Lösung (angefangene Aufg geben keine Pkt)

immer bester Quotient W[i]/Z[i] nehmen ergibt
nicht unbedingt beste Lösung

Dynamisch lösen

ARRAY, senkrecht Aufgaben, wagrecht Zeit,
Aufg nicht lösen: Zahl von Reihe oben
übertragen
Aufg lösen: Zahl in oberer Reihe, Z[i]
Positionen weiter links + W[i]
nimm immer Max

beste Lösung: Zahl am weitesten unten links

Lösungsmenge finden: von unten aufrollen,
falls gleiche Zahl obendran: --> nicht
genommen


Max und Min gleichzeitig finden
Algorithmus naiv: zuerst Max suchen --> n-1 Vgl
dann Min suchen --> n-2 Vgl

Divide and conquer: Halbieren,
Annahme: in jeder Hälfte Max, Min bekannt,
dann nur noch max1 und max2 vgl etc.
bei nur 2 Elementen: 1 Vergleich

--> 3/2n + 2

O(n)
Maximum finden
Algorithmus ARRAY oder Liste, ungeordnet

Von links her scannen,
immer bisheriges Maximum mit aktuellem Wert vergleichen,
ev. übernehmen

Alternative: Min-Heap bilden (O(n))

für i-kleinstes: i * Min rausnehmen,
versickern lassen, i*log n


oder mit Median-of-median in O(n)

O(n)
Maximum Subarray
Algorithmus naiv: von jedem aus bis zu jedem alles aufsummieren
--> O (n^3)

Altern: Summe immer übernehmen und nur noch
letztes Element dazuzählen
O (n^2)

Altern: Preprocessing
Vorher Array berechnen, wieviel Differenz von
jedem zum ersten Element (als absolute Zahlen
und nicht mehr als Schritt im Vergleich zum
Vorgänger)
Dann immer Differenz Einstiegstag -
Ausstiegstag berechnen
O(n^2)

Ultimo:Scanlinie von links immer bisheriges max und
randmax bis zur Scanlinie mitführen.
IF randmax + A[aktuell]< 0 THEN randmax:=0;
(gar nicht einsteigen)
ELSE randmax:=randmax+A[aktuell].
Falls randmax > max, als neues max
übernehmen.
O(n)

O (n)
Median suchen Blum Algorithmus naiv: grösstes raus, 2.grösstes raus, ...
bis zum Mittleren, O(n^2)

Wie Median finden, zB als gutes Pivot für BinSearch?

- ARRAY in 5er Blöcke aufteilen,
- jeden Block sortieren
- mittlere Elemente wieder in ARRAY
- Verfahren rekursiv anwenden

--> Median der Mediane ist gutes Pivot

Analyse: T(n)<= f*n + e*n + T(n/5) + T(7/10n + 6)

n0=91, O(n)

O(n)
Mergesort
Algorithmus - ARRAY wird in 2 Hälften geteilt,
- jede Hälfte wird in sich geordnet
- die beiden Teile werden verschmolzen
- rekursiv aufgerufen

PROCEDURE Mergesort....
... m:=(l+r) DIV 2; Mergesort(A, l,m);
Mergesort(A, m+1,r);
Merge(A, l, m, r);

PROCEDURE Merge
VAR B: ARRAY OF INTEGER
.... WHILE (i<=m) & (j<=r) DO
IF A[i]<A[j] THEN B[k]:=A[i]; INC i;
ELSE.....
IF i>m THEN (*1. Teil schon fertig*)
FOR s:=1 TO r-j DO
B[k+s]:=A[s+j]; END;....

Es können auch mehr Stränge miteinander gemerget werden (zB 5 mit je 60 Läufen von je 5 Zeichen), immer 1 Lauf von allen 5 Bändern auf ein Zielband --> auf Zielband 60 Läufe mit je 25 Zeichen, dann wieder auf 5 Bänder verteilen, je 12 Läufe à 25 Zeichen etc.


Minimum Spanning Tree Kruskal Algorithmus Sortiere alle Kanten nach der Länge,
nimm immer die kürzeste,
wähl sie aus, sofern sich kein Zyklus ergibt

Mit Union- Find Struktur verwalten, ob es ein Zyklus ist.

O (m * log(n))
Minimum Spanning Tree Dijkstra Algorithmus gleicher Ansatz wie kürzester Weg mit Kern, Rand, unbekannt.
Start: Nimm beliebigen Knoten als Kern

Wähle kürzeste Kante, die über den Schnitt Kern - Rand geht.
Nimm den Endknoten im Rand zum Kern dazu, definiere den neuen Schnitt, nimm Nachbarknoten zum Rand dazu


O (n^2)
Missionare und Kanibalen
Algorithmus Zustandsraum zusammenstellen

ungültige Positionen rausstreichen

mögliche Züge aufzeichnen

im Zustandsraum Weg von A nach B suchen


Natürliche Suchbäume
Datenstruktur Jeder Baum 2 Zeiger, geordnet nach key,

Einfügen: entlang Baum nach unten, dann in Blatt key einfügen

Abbilden auf Strahl: Immer abwechselnd Blatt, innerer Knoten

Problem: Degeneration zu Liste i m Worst Case
Suche O(n) statt O(log n)

Mittel über alle Permutationen: O(log n)
Mittel über alle möglichen Baumstrukturen: O(sqrt(n))

Variante: Blattsuchbaum,Schlüssel nur in Blättern, braucht etwas mehr Platz

Variante: Sentinel unten einfügen, Key für Suche in Sentinel schreiben



Nearest Neigbour in 2 Dim
Algorithmus nächster Nachbar in 1 Dim:
Sortieren, berechne immer Differenz
zw. 2 Elementen, Find Min

in 2 Dim: 1.Var:
Induktion, immer 1 Punkt dazu-
nehmen, mit allen n-1 bisherigen Pkt vergleichen , O (n^2)

2. Var:
Divide and conquer, zuerst nach y-Koordinate sortieren (für nachher bei
Mittelstreifenkontrolle
mittlere x - Koordinate finden,
senkrechte Linie durch diesen Median
legen, Annahme: in jeder Hälfte
nächste Nachbarn gefunden
min 1 und min2 vergleichen. Entlang
Mittelstreifen noch mit kleinerem
Minimum kontrollieren, ob noch
Punkte in diesem Band näher sind , neues Min.

y Koord sortieren: O (n log n), Dann log n Schritte jedes Mal: Median x finden: O (n log n), Punkte entlang steifen suchen: O (n log n),


Objektorientierung
Theorie Zusätzliche Variablenart: Prozedurvariablen

damit lassen sich im ADT vorsehen, was mit einem bestimmten Objekt zu tun ist, ohne es schon im voraus zu wissen.

Jedes Objekt hat die Prozeduren, mit denen es bearbeitet wird, gerade schon in seinen eigenen Variablen drin fixiert.


Optimale Suchbäume
Datenstruktur Suchbäume, bei denen die Zugriffhäufigkeiten auf die Knoten bekannt sind.

optimal: Ž(#Zugriffe * Weglänge) = minimal

Weglänge zu Wurzel = 1

Der optimale Suchbaum ergibt sich nicht immer, wenn die Knoten in Reihenfolge der Häufigkeit eingefügt werden.

key 1 key 2 key 3
Zw.raum Zw.raum Zw.raum Zw.r.

4 3 5 3 2 1 6

wij: wie oft wird auf den Bereich von 0 bis 2 zugegriffen?
--> 0+4+3+5+3+2 Mal = 17, Gitter ausfüllen

Pij: Intervall aufteilen, Minimum suchen für P 0,2 :
(P 0,1 + P 1,2) oder (P 0,0 + P0,2) + w 0,2

Gitter Root, worin festgehalten wird, wo aufgeteilt wurde --> Wurzel des Teilbaums


Optimales Produkt mehrerer Matrizen
Algorithmus n Matrizen, wie soll am besten geklammert werden?

Lösungsgitter, Diagonalen immer 0, nur oberer Teil wird benötigt

Wenn nur 2 Matrizen: # Multiplikationen = n*q * r, eintragen in Matrix

Weitere Felder: immer diagonaleweise füllen, bei jeder die neu dazukommt entscheiden, wo klammern, Minimum eintragen

--> rechts oben wird das bestmögliche Resultat erscheinen


Palindromtest
Algorithmus a man a plan a canal: panama

WHILE i<=n DIV 2 & A[i]=A[n-i] DO INC(i); END


Polynomauswertung
Algorithmus Polynom n-ten Grades berechnen:
Pn(x) = an*x^n+an-1*x^(n-1)+ .... + a0

mit Induktion 1:
Annahme Pn-1(x) schon berechnet
Pn(x) = Pn-1(x) + an*x^n; (= an*x*x*x*.....*x)
P0(x) = a0
jeder Schritt n Multiplikationen --> O(n^2)


mit Induktion 2:
Annahme Pn-1 (x) und x^(n-1) schon berechn.
Pn(x) = Pn-1(x) + an * x * x^(n-1)
jeder Schritt 2 Multiplikationen --> O(n)


Anderer Induktionsansatz von hinten:
Qn-1(x) = an*x^n + an-1 * x^n-1 + ..... + a1*x
= x*(an*x^n-1+an-1*x^n-2+....+a1)
hinterer Teil Rn-1(x) hat wieder gleiche Form
wie Pn(x)

Pn(x) = x* Rn-1(x) + a0

jeder Schritt 1 Add, 1 Mult --> O(n)


Priority-Queue
Datenstruktur Die Elemente enthalten einen Key, der die Priorität angibt. Sie werden nicht hinten in die Q eingehängt, sondern an dem Platz, wo sie nach key hingehören.

Für die Priority-Q als ADT wird beim init noch eine Vergleichsprozedur vom Client benötigt

SERVER: siehe Q in Liste, ausser
TYPE comp: PROCEDURE (a,b: Elem): BOOLEAN;
Qdesc=RECORD
compare:comp;
END;
PROCEDURE init*(vgl:comp):Q;
BEGIN
NEW(Q);
Q^.compare:=vgl; ......

PROCEDURE push* (VAR q: Q; e:Elem);
VAR before, cur: Elem;
BEGIN
cur:= Q^.first; before:=Q^.first;
WHILE Q^.compare(cur, e) DO
cur:=cur^.next;
END;
e^.next:=cur;
before^.next:=e; END push;

enq: O(n), deq: O(1); init: O(1)
pseudopolynomielle Laufzeit
Theorie Ein Algorithmus, der eine Laufzeit hat, die nicht nur von der Anzahl der Elemente abhängt, sondern auch noch von einem Wert, der von der Eingabe abhängt

z.B: Rucksackproblem: O(n * G)
G ist die Gewichtslimite in diskrete Teile
unterteilt


Queue in ARRAY
Datenstruktur FiFo

2 Zeiger, vorne, hinten
enqueue: hängt bei hinten an, INC (hinten)
dequeue: nimmt bei vorne weg, INC (vorne)
ismt?: vorne>hinten?

ohne Rückkoppelung: bei Erreichen bestimmter Länge wieder alles nach vorne schieben
mit Rückkoppelung: beim Füllen hinten angelangt einfach wieder vorne weitermachen, bis hinten+1=vorne --> full
Zusatzfkt: multidq(key): Alles weg bis key kommt oder Q leer ist

push: O(1), pop O(1), ismt: O(1), suchen: O(n)
Queue in Liste
Datenstruktur FiFo

Zwei POINTER, first, last
push: bei last einhängen
pop: bei first einhängen
ismt? first=NIL?
init: NEW (Q^.first); NEW (Q^.last);
TYPE Elem=POINTER TO Elemdesc
Elemdesc=RECORD
next: Elem;
END;
Q=POINTER TO Qdesc;
Qdesc=RECORD
first:Elem;
last: Elem;
END;
push: O(1), pop O(1), ismt: O(1), suchen: O(n)
Quicksort
Algorithmus Ungeordnetes ARRAY
- Pivot-Element wird ausgewählt;
- mit 2 Scannern von rechts und links über ARRAY fahren, bis je ein Element gefunden wird, das auf falscher Seite von Pivot steht --> vertauschen, beim Pivot teilen, - rekursiv aufrufen

PROCEDURE Quicksort( VAR A:ARRAY; l,r: INT);
... IF r>l THEN
i:=l-1; j:=r; v:=A[r];
LOOP
REPEAT INC (i) UNTIL A[i]>=v;
REPEAT DEC(j) UNTIL a[j]<=v;
IF i>=j THEN EXIT; END;
temp:= A[i]; A[i]:= A[j]; A[j]:= temp;
END;
t:=A[i]; A[i]:= A[r]; A[r]:=temp;
Quicksort (A, l, i-1);
Quicksort (A, i+1, r);
END;....

nicht stabil!

O (n log n)
Römische Zahl umwandeln
Algorithmus Immer noch die vorhergehende Zahl anschauen

Falls A[i-1]<A[i] THEN sum:=sum+A[i]-a[i-1]; i:=i+2;
Sonst sum:=sum+A[i-1]; INC (i)


Rucksackproblem
Algorithmus n Gegenstände, Gewichtslimite L, Werte w[i] imd Gewochte g[i] für jeden Gegestand sind gegeben.

1. Gewicht diskretisieren, in zB 100g Päckchen aufteilen.
2. Matrix, senkrecht: Gegenstände, waagrecht:
Gewichtszähler.
3. Zum Anfangen: überall 0 einfüllen (= kein
Gegenstand gewählt --> kein Wert erzielt)
4. Nun beginnt man bei Zeile 1, wird Ggstand
gewählt: um g[i] nach rechts und dort neuer
Wertestand eintragen; nicht gewählt: von
oberer Zeile übertragen,
5. Es wird immer das Optimum dieser beiden
Möglichkeiten gewählt.

Beste Packung: unten rechts beginnen, nach links wandern, bis keine 0 mehr steht,

falls oberhalb gleiche Zahl: Ggstand nicht gewählt, falls nicht: g[i] Schritte nach linksgehen, Ggstand gewählt, eins nach oben

O (n* G) pseudopolynomiell
Selbstanordnende Bäume Move to Root
Datenstruktur Der zugegriffene Knoten wird mit Rotationen neu an die Wurzel befördert.

Ergibt einen degenerierten Baum, O(n)

sehr schlääääääächt!


Selbstanordnende Bäume Splay-Trees Tarjan Datenstruktur Idee gleich wie bei Move to Root, aber:
Bei Situation x und Zugriff auf z wird die ganze
Gruppe / aufs Mal gedreht.
y
/
z

--> statisch optimal, gleich gut wie optimaler Suchbaum bei bekannten Zugriffshäufigkeiten

--> degenerieren nicht, sind gleichgut balanciert wie AVL, immer O (log n)

Falls Suche erfolgreich: key in Wurzel
Falls Suche erfolglos: letzter Vater vor NIL in Wurzel

Join: (alle key in TB 1 kleiner als in TB 2)
- Suche nach Max in TB 1, nach oben splayen
- in TB 2 unten einhängen
Split: - nach Trennpunkt suchen
- an Wurzel teilen
Insert: - Suche nach x
- falls nicht vorhanden: Split,
- x einsetzen, Join
Delete: - Suche nach x
- Wurzel weg
- Teilbäume Join

Alles in O(log n)
Selbstanordnende Liste Frequency count
Datenstruktur Lineare Liste, jedes Elem hat Zugriffszähler,
bei Zugriff wird Zähler um 1 erhöht,
wird die ganze Zeit neu nach Zugriffshäufigkeit angeordnet

TYPE Elem=POINTER TO Elemdesc
Elemdesc=RECORD
next:Elem;
freq: INTEGER;
END;


Selbstanordnende Liste Move to Front
Datenstruktur Lineare Liste,
nach jedem Zugriff wird das zugegriffene Element an die vorderste Position gebracht,

bei Worst Case: Auch O(n)

kompetitive Analyse: Vergleich mit idealem Algorithmus

amortisierte Analyse:
balance = # Inversionen zwischen
imaginärem Gegner und mtf

???


Selbstanordnende Liste Transpose
Datenstruktur Lineare Liste,
bei jedem Zugriff wird das zugegriffene Element mit dem vorhergehenden vertauscht
(d.h. um eine Position nach vorne geschoben)

Vorteil: Funktioniert auch im ARRAY ohne Schwierigkeiten

Bei Worst Case O(n)
(immer auf hinterstes El zugreifen)


Set-Cover
Algorithmus S = Gesamtmenge mit n Elementen
T1, T2, T3, .... Teilmengen von S mit verschiedenen Anzahl von Elementen.

Suche minimale # Teilmengen, die alle Elemente aus S abdecken.

Nimm immer die Menge mit am meisten noch nicht abgedeckten Elementen

für Lösungsgüte: Elementkosten für Teilmenge berechnen: 5 noch nicht abgedeckte Elemente --> Preis pro Element = 1/5

via Durchschnittspreis, Summe der Elementenpreise ergibt sich

Lösungsgüte = 1 + log (n)


Skip-Listen
Datenstruktur Zeiger von verschiedener Höhe,
# Zeiger = 2n -1= n+n/2+n/4+...

Suchstrategie:
oberste Ebene beginnen,
nach rechts, falls zu gross:
eine Ebene tiefer nach rechts;
falls zu klein: gleiche Ebene einen Pfeil weiter

randomisiert:
neues Element einfügen:
- richtige Stelle suchen
- Höhe zufällig wählen (Random Uniform, falls >0.5 dann ein Niveau hinauf)
- Zeiger nachführen
(beim Suchen Weg registrieren)

Einfügen: O(log n); Suchen O (log n)
Skirental-Problem
Algorithmus Ausrüstung kaufen oder mieten

Kauf: Fr. 300.-
Miete: Fr 30.-/Tag

i Tage mieten, dann Kaufen --> i*30 + 300

Optimum: = Min( i*30, 300)

competitive ratio

für zB kaufen am 1. Tag, nachher aufgeben:
c.r.= 300/30 =10


für zB 5 Tage mieten, dann kaufen, 6. Tag aufgeben
c.r.= (5*30 + 300)/180 =2.5


Sortieren vorsortierter Folgen
Algorithmus Für Folgen, die schon nach einem bestimmten Mass vorsortiert sind, kann es Algorithmen geben,
die schneller als die Worst Case Zahl O(n log n) sind.

zB. A-Sort für eine Folge mit wenigen Inversionen


Stabile Heirat Gusfield Algorithmus Jeder Mann, jede Frau hat Prioritätenliste,
zB a: 1 , 2, 3, 4
b: 1, 3, 4, 2

1: c, b, d, a
2: d, a, c, b

(a, 1); (b, 2) ist nicht stabil: (b, 1) würde von b und von1 bevorzugt.

Gesucht: stabile Heirat

Algorithmus, der immer terminiert:
zuerst bei neuem Mann Prioritätenliste
durchschauen bis zur 1. Frau,

falls noch nicht vergeben: zuordnen,
sonst: bei Frau kontrollieren, ob Mann vor dem
eigentlich schon zugeordneten Partner kommt.

Wenn ja, dann Paar neu bilden,
alten Eintrag löschen, bei altem Mann um eine
Position weiter.

Wenn nein, dann bei neuem Mann eine
Position weiter


Stapel in Array, beschränkte Grösse
Datenstruktur FiLo

push: Immer hinten anhängen,
Zähler für hinterstes Element mitführen
pop: Hinterstes Element ausgeben und löschen, DEC(Zähler)
ismt?: Zähler auf 0?
Init: Neues Array initialisieren
full?: Zähler=n-1?

push: O(1), pop O(1), ismt: O(1), suchen: O(n)
Stapel in Liste
Datenstruktur FiLo

Lin. Liste, Stack mit POINTER top;
Elemente als ADT mit Zeiger next;
vorne einhängen/aushängen
ismt?: top-POINTER =NIL?
init: NEW (S^.top);

TYPE Element=POINTER TO Elementdesc;
Elemdesc=RECORD
next:Element;
END;
Stack=POINTER TO Stackdesc;
Stackdesc=RECORD
top:Element;
END;

PROCEDURE push* (VAR S:Stack; e:Element);
BEGIN
e^.next:=S^.top;
S^.top:=e;
END push;

push: O(1), pop O(1), ismt: O(1), suchen: O(n)
Star in der Menge
Algorithmus Star: Alle kennen ihn, er kennt niemanden

naiv: in Adjazenzmatrix alles kontrollieren n*(n-1)
O(n^2)

mit Induktion:
3 Fälle: Star in bisheriger Menge, neuer ist Star,
oder es gibt keinen, je nachdem jeder aus
schon bearbeiteten 2 Fragen stellen (kennst du
ihn ? Kennt er dich? 2*(n-1)+2*(n-2)....
O(n^2)

Duellvariante:
immer 2 wählen, Kennt A B? Ja -->A nicht Star,
Nein-->B nicht Star, bei letztem potentiellem
Star Zeile und Spalte der Matrix kontrollieren
(n-1)+2*(n-1) ---> O(n)

O(n)
Sternfiguren-Fraktale
Algorithmus 5-zackiger Stern, in jeder Ecke soll wieder ein Stern eingefügt werden usw.
Eingabe n: # Iterationen

PROCEDURE Stern(n,Seitenlänge:INTEGER)
BEGIN
FOR i:=1 TO 5 DO
Turtle.Go (Seitenlänge);Turtle.Turn (72);
IF n>0 THEN Stern (n-1, Seitenlänge/2);
END;
END;


Suchbaumtraversen
Algorithmus Preorder: - Wurzel
(HauptRF) - linker TB
- rechter TB

Inorder: - linker TB
(Symm. - Wurzel
RF) - rechter TB

--> ergibt aufsteigende Reihenfolge

Postorder: - linker TB
(NebenRF) - rechter TB
- Wurzel


Teleskopieren
Theorie T(2) = 1
T(n) = T(n/2)+T(n/2)+2
= 2*T(n/2)+2
= 2*(2*T(n/4)+2)+2 = 4*T(n/4)+4+2
= 4*(2*T(n/8)+2)+4+2
= 8*T(n/8)+8+4+2
= 2^i*T(n/2^i)+2^i+2^(i-1)+....+2

Wann hört auf? n/2^i:=2 --> n/2 = 2^i

= n/2*T(n/(n/2))+n/2 + n/4 + n/8 +....+ 2
= n/2*1 + n-2

= 3/2*n + 2

ist aber noch kein Beweis. Jetzt mit Induktion drüber!


Text Pattern Matching Knuth/Morris/Pratt, Boyer/Moore, Rabin/Karp Algorithmus Text der Länge n, Pattern der Länge m, n>>m
Ist Pattern im Text enthalten?

Naiv: Von vorne nach hinten, immer ganzes Pattern kontrollieren --> Laufzeit m*n

Knuth/Morris/Pratt: Hilfsstruktur Verschiebungsarray der Länge m vorher berechnen zB wenn an Pos 5 ein Mismatch auftritt, so haben alle vorangehenden Positionen gestimmt --> in Pos 5 des Verschiebungsarrays steht, um wieviel Positionen man das Muster nun schieben kann, bei denen sicher die Lösung nicht übergangen wird.

Boyer/Moore: Pattern an den Anfang des Texts, Von hinten im Pattern beginnen, falls Mismatch, kontrollieren, ob falscher Buchstabe überhaupt in Pattern vorkommt, sonst um Länge n schieben

Rabin/Karp: Hashfunktion des Patterns berechnen, zB ORD(Pos1)*B^2 +ORD(Pos2)*B+ORD(Pos3), dann vom Text das gleiche berechnen, Verschiebung um eines lässt sich inkrementell berechnen:
h neu= (h alt - ORD(Pos1)*B^2)*B + ORD(Pos4)


Topologisches Sortieren
Algorithmus Finde eine Reihenfolge, so dass alle Pfeile im gerichteten Graphen befolgt werden.
Bedingung: kein Zyklus

Verankerung: Wenn nur 1 Knoten im Graph,
bekommt er die Nummer n

Annahme: {1, 2, ...., n-1} schon bekannt

Schritt: 1 Knoten im Graph weglassen, von dem nur
Pfeile weggehen, bekommt die Nr. 1;
übrige Knoten Nr. 2 - n nummerieren;
wiederholen

Implementation:
Adjazenzliste, alle Knoten durchgehen, auf
welchen zeigt kein Pfeil? --> X auf Stack
Pfeile, die von X weggehen, löschen

O(|V| + |E|) ??


Transitive Hülle
Algorithmus Falls Verbindung von A nach B und von B nach C
--> C ist auch von A zu erreichen

Trans. Hülle: Finde alle Erreichbarkeiten

Adjazenzmatrix, Diagonal 1en einfügen, multipl. ergibt Wege der Länge 2

Induktion über Weglänge:
immer an grösstem Zwischenknoten k
aufteilen

Annahme: Wege mit Zwischenknoten < k sind schon bekannt

Schritt: k dazunehmen, neuer Weg muss k benutzen


O(n^3)
Transitive Hülle Warshall Algorithmus Welche Knoten sind von einem Startknoten alle erreichbar?

Adjazenzmatrix, Diagonalen 1 setzen, Induktion

Annahme: Alle Wege über Zwischenknoten bis Nr. j sind schon bekannt. Nun kommt noch j+1 dazu.

FOR i:=1 TO NofNodes DO A[i,i]:=1;
FOR j:=1 TO NofNodes DO
FOR i:=1 TO NofNodes DO
IF A[i,j]=1 THEN
FOR k:=1 TO NofNodes Do
IF A[j,k]=+ THEN
A[i,k]:=1; END;
END;
END;
END;
END;

O(n^3)
Travelling Salesman Problem (Dreiecksungl.)
Algorithmus Approximation mit MST (gilt nur, wenn Dreiecksungleichung AB + AC >= BC gilt)

MST berechnen,
aussen herum entlangfahren, wenn Knoten schon besucht, dann überspringen und Abkürzung zum nächsten noch nicht besuchten Knoten eintragen

| MST | < | Rundreise minus 1 Kante | < | opt TSP |

ohne Abkürzungen wäre der app TSP = 2 * MST

wegen Dreiecksungleichung: mit Abkürzungen sicher nicht schlechter als ohne


--> Lösungsgüte <=2

Variante: MST erstellen,
Knoten mit deg = gerade --> unverändert
Knoten mit deg = ungerade --> Kante angehängt, die immer 2 solche Knoten verbindet.

Lösungsgüte = 1,5


Türme von Brahma
Algorithmus 3 Stäbe, n Scheiben, müssen von A nach B mit Hilfe von C;
Rekursiv lösen:
Falls nur 2 Scheiben vorhanden sind:
kleine Scheibe auf C, grosse Scheibe (= n-1 restliche Scheiben) auf B, kleine Scheibe auf B drauf.

Lässt sich so für n Scheiben rekursiv lösen:


PROCEDURE Brahma (n: INTEGER; A,B,C :Säulen );
BEGIN
IF n=1 THEN ...
ELSE Brahma (n-1,....


Typerweiterung
Theorie RECORD und POINTER können in Oberon erweitert werden.

TYPE Adr1= RECORD
Nummer:INTEGER; END;
Adr2= RECORD (Adr1)
Name: ARRAY OF CHAR; END;

VAR a: Adr1; b: Adr2;

Jetzt hat a nur das Feld a.Nummer, b hingegen die Felder b.Nummer und b.Name (dh. b ist Erweiterung).

a:=b; ist gültig, alle Felder von a sind in b auch definiert, die zusätzlichen Infos gehen in a verloren

b:=a; ist ungültig, b hat Felder, die nicht gefüllt werden können. Bei anfrage b.Name hats nichts dort.


Union-Find
Datenstruktur verwalten von Mengen
Jedes Element zeigt auf ein anderes, das zur gleichen Menge gehört, bis zum „Wurzelelement“, das auf sich selber zeigt.

Find: Pfeilen entlang, bis ein Element auf sich selber
zeigt --> Wurzel

Union: Die kleinere Menge wird in die grössere Menge
eingehängt, d.h. die Wurzel der kleineren
Menge zeigt neu auf die Wurzel der grösseren
Menge

Nachteil: kann grosse Pfadlänge=Suchzeit ergeben


Union-Find Pfadverkürzung
Algorithmus path splitting:

Beim Find wird jeder Knoten auf dem Weg mit seinem Grossvater verbunden. Dadurch wird der Pfad in 2 separate Wege aufgeteilt.


path halving:

Es wird beim Find nur jeder 2. Knoten auf dem Weg zur Wurzel mit seinem Grossvater verbunden. Dadurch ergibt sich ein verästelter halb so langer Weg

Laufzeit: Ackermannfkt alpha, viel kleiner als log


collapse:

Alle Knoten werden direkt an Wurzel angehängt. Dafür muss der Weg zweimal zurückgelegt werden: 1. Mal um die Wurzel zu finden, 2. Mal zum Einhängen

Find O(alpha (m,n))
Union-Find Pfadverkürzung collapse
Datenstruktur Jedes Element wird direkt an der Wurzel angehängt.

--> grosser Zeitgewinn beim Find, O(1)
--> Riesenaufwand bei Union, alle Pfeile müssen
umgehängt werden O(n*log n)

--> nicht so toll


Untere Schranke für Sortierverfahren
Theorie Vergleichsbasierte Sortierverfahren basieren auf einem Entscheidungsbaum, an jedem Knoten eine Entscheidung „a1> a2?“ --> Pfade führen zu allen möglichen Permutationen in den Blättern

# Permutiationen für n Objekte: n!

Suchbaumpfade nicht alle gleich lang; kürzester Pfad (a1 < a2 < .... < an) ist mindestens n-1 lang (mit Transitivität kann nach a1 < a2, a2 < a3 gefolgert werden a1 < a3).
Maximale Pfadlänge:
Auf einer Ebene sind 2^höhe # Blätter --> alle Permutationen, falls auf der gleichen Höhe:
2^n = n!, mit Stirlingscher Formel --> maximal mögliche Pfadlänge O (log n) --> untere Schranke für Sortieralgorithmus:
O (n log n)

O (n log n)
Wächter im Graph (Vertex Cover)
Algorithmus Wie viele Wächter müssen auf die Knoten positioniert werden, damit jede Kante überwacht wird?

Idee 1: Zuerst die Knoten mit den höchsten Graden, alle Kanten, die dadurch überwacht werden wegstreichen

Lösungsgüte: log(n)

Idee 2: Wähle Knoten v, gehe einer Kante entlang und wähle auch noch Nachbarknoten w. Nun entferne alle Kanten, die dadurch abgedeckt sind

Lösungsgüte: 2

Grund: in der optimalen Lösung müsste ich auch entweder Knoten v oder Knoten w wählen. Ich habe also mit diesem Algorithmus höchstens das doppelte erwischt.


Weg finden in dag
Algorithmus Breitensuche
Knoten in Queue speichern


Zahlen in 4 Grp sortieren, Dijkstra
Algorithmus N-1 positive REAL, in 4 Grp einteilen,
0 < o <=1; 1 < p<=5<, 5 < q <=50; r> 50;
jede Zahl nur einmal anschauen,
kein zusätlicher Speicherplatz

x,i,j,k:=0,0,0,N-1

do 0<A[x]<=1 --> swap x,i; i:=i+1; j:=j+1; x:=x+1
1<A[x]<=5 --> swap x,j;j:=j+1, x:=x+1
5<A[x] <=50 --> x:=x+1;
50<A[x] --> swap x,k; k:=k-1; x:=x+1
od




Ziege vor dem Zaun, Exploration
Algorithmus suchen nach bester Strategie,

zB immer pendeln: 1 Haus links, 2 Häuser rechts, 3 Häuser links etc.

competitive ratio = (1 + 2 + 3 + 4 + ....d) / d =~ d

besser: immer Distanz verdoppeln