n+1

Werbung
Stacks
Synonyme: Stapel, Keller, LIFO-Liste usw.
Stack kann als spezielle Liste aufgefaßt werden, bei der
alle Einfügungen und Löschungen an einem Ende,
TOP genannt, vorgenommen werden
Stack-Operationen:
- CREATE: Erzeugt den leeren Stack.
- INIT(S):
Initialisiert S als leeren Stack.
- PUSH(S, x): Fügt das Element x als oberstes Element von S
ein.
- POP(S):
Löschen des Elementes, das als letztes in den
Stack S eingefügt wurde.
- TOP(S):
Abfragen des Elementes, das als letztes in den
Stack S eingefügt wurde.
- EMPTY(S): Abfragen, ob der Stack leer ist.
G.Heyer
1
Algorithmen und Datenstrukturen
Schlangen
Synonyme: FIFO-Schlange, Warteschlange, Queue
Spezielle Liste, bei der die Elemente an einem Ende
(hinten) eingefügt und am anderen Ende (vorne) entfernt
werden
Operationen:
- CREATE: Erzeugt die leere Schlange
- INIT(Q): Initialisiert Q als leere Schlange
- ENQUEUE(Q, x) : Fügt das Element x am Ende der
Schlange Q ein
- DEQUEUE(Q): Löschen des Elementes, das am längsten
in der Schlange verweilt (erstes Element)
- FRONT(Q): Abfragen des ersten Elementes in der Schlange
- EMPTY(Q): Abfragen, ob die Schlange leer ist
G.Heyer
2
Algorithmen und Datenstrukturen
Vorrangwarteschlangen
Vorrangwarteschlange (priority queue)
- jedes Element erhält Priorität
- entfernt wird stets Element mit der höchsten Priorität
(Aufgabe des FIFO-Verhaltens einfacher Warteschlangen)
Operationen:
- CREATE:
Erzeugt die leere Schlange
- INIT(P):
Initialisiert P als leere Schlange
- INSERT(P, x): Fügt neues Element x in Schlange P ein
- DELETE(P): Löschen des Elementes mit der höchsten
Priorität aus P
- MIN(P):
Abfragen des Elementes mit der höchsten
Priorität
- EMPTY(P): Abfragen, ob Schlange P leer ist.
G.Heyer
3
Algorithmen und Datenstrukturen
Sequentielle Suche
Suche nach Element mit Schlüsselwert K
Falls nicht bekannt, ob die Elemente der Liste nach ihren
Schlüsselwerten sortiert sind, besteht nur die Möglichkeit,
die Liste sequentiell zu durchlaufen und elementeweise zu
überprüfen (sequentielle Suche)
pos := 1;
WHILE (pos <= L.Laenge) AND (L.Inhalt [pos].Key <> K)
DO
INC (pos)
END;
gefunden := (pos <= L.Laenge);
G.Heyer
4
Algorithmen und Datenstrukturen
Kosten
• Erfolglose Suche erfordert n Schleifendurchläufe
• erfolgreiche Suche verlangt im ungünstigsten Fall
n -1 Schleifendurchläufe ( und n Schlüsselvergleiche)
• mittlere Anzahl von Schleifendurchläufen bei
erfolgreicher Suche:
1 n-1
n-1
Cavg (n) =  i =
n i=0
2
G.Heyer
5
Algorithmen und Datenstrukturen
Binäre Suche
Auf sortierten Listen können Suchvorgänge effizienter
durchgeführt werden
Sequentielle Suche auf sortierten Listen bringt nur geringe
Verbesserungen (für erfolglose Suche, durchschnittlich N/2
Vergleiche)
Binärsuche wesentlich effizienter durch den Einsatz der
Divide-and-conquer-Strategie.
Suche nach Schlüssel K in Liste mit aufsteigend sortierten
Schlüsseln:
G.Heyer
6
Algorithmen und Datenstrukturen
1. Falls Liste leer ist, endet die Suche erfolglos.
Sonst: Betrachte Element Inhalt[m] an mittlerer Position m.
2. Falls K = Inhalt[m].Key dann ist das gesuchte Element
gefunden .
3. Falls K < Inhalt[m].Key, dann durchsuche die linke
Teilliste von Position 1 bis m-1 nach demselben
Verfahren.
4. Sonst (K > Inhalt[m].Key) durchsuche die rechte Teilliste
von Position m + 1 bis Listenende nach demselben
Verfahren.
G.Heyer
7
Algorithmen und Datenstrukturen
Binäre Suche (2)
Iterative Lösung
int binsearch(int v)
{
int l=1; int r= N; int x;
while (r>=1)
{
x = (l+r)/2;
if (v < a[x].key) r = x-1; else l = x+1;
if (v == a[x].key) return a[x].data;
}
return -1
}
G.Heyer
8
Algorithmen und Datenstrukturen
Kosten
Cmin ( n ) = 1
Cmax ( n ) = [ log2 (n+1)]
Cavg ( n )  log2 (n+1) -1, für große n
G.Heyer
9
Algorithmen und Datenstrukturen
Fibonacci-Suche
Ähnlich der Binärsuche, jedoch wird Suchbereich
entsprechend der Folge der Fibonacci-Zahlen geteilt.
Definition der Fibonacci-Zahlen
F0 = 0
F1 = 1
Fk = F k-1 + F k-2 für k >= 2.
Teilung einer Liste mit n = Fk-1 sortierten Elementen:
1
i
n
F k-2 -1
F k-1 -1
F k- 1
G.Heyer
10
Algorithmen und Datenstrukturen
- Element an der Position i = F k-2 wird mit dem Schlüssel K
verglichen
- Wird Gleichheit festgestellt, endet die Suche erfolgreich.
- Ist K größer, wird der rechte Bereich mit F k-1 -1
Elementen, ansonsten der linke Bereich mit F k-2 -1
Elementen auf dieselbe Weise durchsucht.
Kosten
- für n = F k -1 sind im schlechtesten Fall k-2 Suchschritte
notwendig, d. h. O ( k ) Schlüsselvergleiche
- Da gilt F k  c + 1.618 k , folgt
C max ( n ) = O ( log 1.618 ( n+1 ) ) = O ( log2 n) .
G.Heyer
11
Algorithmen und Datenstrukturen
Sprungsuche
Prinzip
- Zunächst wird der sortierte Datenbestand in
Sprüngen überquert, um den Abschnitt zu
lokalisieren, der ggf. den gesuchten Schlüssel enthält,
- danach wird der Schlüssel im gefundenen Abschnitt
nach irgendeinem Verfahren gesucht.
...
...
L
1
G.Heyer
...
m
...
2m
12
...
3m
n
Algorithmen und Datenstrukturen
Einfache Sprungsuche
- konstante Sprünge zu Positionen m, 2 m, 3 m, ...
- Sobald K <= Inhalt[i].Key mit i = j * m (j = 1, 2, ...),
wird im Abschnitt
Inhalt[(j-1)m+1] bis Inhalt[j*m]
sequentiell nach dem Suchschlüssel K gesucht.
Mittlere Suchkosten
ein Sprung koste a ; ein sequentieller Vergleich b Einheiten
n
Cavg (n) =  a *m
+  b ( m -1 )
G.Heyer
13
Algorithmen und Datenstrukturen
Optimale Sprungweite
m=V(a/b)n
bzw. m = V n
falls a = b
 C avg ( n ) = a V n - a / 2
 Komplexität
O (V n )
G.Heyer
14
Algorithmen und Datenstrukturen
Sprungsuche (2)
Zwei-Ebenen-Sprungsuche
- statt sequentieller Suche im lokalisierten Abschnitt wird
wiederum eine Quadratwurzel-Sprungsuche angewendet,
bevor dann sequentiell gesucht wird
- Mittlere Kosten:

Cavg ( n ) <=  * a * V n +  * b * n +  * c * n
a Kosten eines Sprungs auf der ersten Ebene;
b Kosten eines Sprungs auf der zweiten Ebene;
c Kosten für einen sequentiellen Vergleich
- Für a = b = c ergibt sich: Cavg ( n ) <= a
G.Heyer
15
Vn+n
Algorithmen und Datenstrukturen
Verbesserung durch optimale Abstimmung der
Sprungweiten m1 und m2 der beiden Ebenen
- Mit a = b = c ergeben sich als optimale Sprungweiten
m1 = n und
m2 = n
- mittlere Suchkosten: C avg ( n ) = 3/2* a * n
Verallgemeinerung zu n-Ebenen-Verfahren ergibt ähnlich
günstige Kosten wie Binärsuche
(Übereinstimmung bei log2n Ebenen)
Sprungsuche vorteilhaft, wenn Binärsuche nicht
anwendbar ist (z. B. bei blockweisem Einlesen der
sortierten Sätze vom Externspeicher)
G.Heyer
16
Algorithmen und Datenstrukturen
Exponentielle Suche
Anwendung wenn Länge des sortierten Suchbereichs
zunächst unbekannt bzw. sehr groß ist.
Vorgehensweise
- für Suchschlüssel K wird zunächst obere Grenze für den
zu durchsuchenden Abschnitt bestimmt
i := 1;
WHILE K > L.Inhalt [i].Key DO
i := i + i;
END;
- Für i > 1 gilt für den auf diese Weise bestimmten
Suchabschnitt
L.Inhalt [i DIV 2].Key < K <= L.Inhalt [i].Key
- Suche innerhalb des Abschnitts mit irgendeinem Verfahren
G.Heyer
17
Algorithmen und Datenstrukturen
Sind in der sortierten Liste nur positive, ganzzahlige
Schlüssel ohne Duplikate gespeichert,
wachsen Schlüsselwerte mindestens so stark wie die
Indizes der Elemente.
- i wird höchstens log2 K mal verdoppelt
- Bestimmung des gesuchten Intervalls erfordert maximal
log2 K Schlüsselvergleiche
- Suche innerhalb des Abschnitts (z. B. mit Binärsuche )
erfordert auch höchstens log2 K Schlüsselvergleiche
Gesamtaufwand O ( log2 K )
G.Heyer
18
Algorithmen und Datenstrukturen
Interpolationssuche
Schnellere Lokalisierung des Suchbereichs indem
Schlüsselwerte selbst betrachtet werden, um „Abstand“ zum
Schlüssel K abzuschätzen
nächste Suchposition pos wird aus den Werten ug und og
der Unter- und Obergrenze des aktuellen Suchbereichs wie
folgt berechnet:
K - Inhalt [ug]. Key
pos = ug +
* (og - ug)
Inhalt[og].Key - Inhalt [ug].Key
G.Heyer
19
Algorithmen und Datenstrukturen
Sinnvoll, wenn der Schlüsselwert im betreffenden Bereich
einigermaßen gleichverteilt ist
erfordert dann im Mittel lediglich
log2 log2n + 1
Schlüsselvergleiche
Im schlechtesten Fall
(stark ungleichmäßige Werteverteilung) entsteht jedoch
linearer Suchaufwand ( O ( n ) )
G.Heyer
20
Algorithmen und Datenstrukturen
Herunterladen