• Keine Ergebnisse gefunden

Grundlagen der Algorithmen und Datenstrukturen Kapitel 7

N/A
N/A
Protected

Academic year: 2022

Aktie "Grundlagen der Algorithmen und Datenstrukturen Kapitel 7"

Copied!
88
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

Grundlagen der Algorithmen und Datenstrukturen

Kapitel 7

Christian Scheideler + Helmut Seidl SS 2009

(2)

Wörterbuch

S: Menge von Elementen

Jedes Element e identifiziert über e.key().

Operationen:

• S.insert(Element e): S = S [ {e};

• S.removeKey(Key k): S = Sn{e}; wobei e das Element ist mit e.key()==k

• S.find(Key k): Falls es ein e2 S gibt mit

e.key()==k, dann gib e aus, sonst gib ? aus

(3)

Suchstruktur

S: Menge von Elementen

Jedes Element e identifiziert über key(e).

Operationen:

• S.insert(Element e): S = S [ {e};

• S.removeKey(Key k): S = Sn{e}; wobei e das Element ist mit e.key()==k

• S.locate(Key k): gib e2 S aus mit

minimalem e.key() so dass e.key() ≥ k

(4)

Wörterbuch vs. Suchstruktur

• Wörterbuch effizient über Hashing realisierbar (insert, remove und find kosten amortisiert / worst case O(1) Zeit)

• Hashing zerstört Ordnung und erlaubt daher

1 3 5 10 14 19

14 5 3 19 1 10

(5)

Suchstruktur

Erste Lösung: sortierte Liste (mit Wächter)

Problem: insert, remove, locate kosten im worst case Θ (n) Zeit

Einsicht: Wenn locate effizient zu implementieren wäre, dann auch alle anderen Operationen

null 3

19 42

(6)

Suchstruktur

Idee: füge Navigationsstruktur hinzu, die locate effizient macht

null 3

19 42

Navigationsstruktur

(7)

Binärer Suchbaum (ideal)

1 3 5 10 14 19 28

1 5

3

14 28

19 10

(8)

Binärer Suchbaum

Suchbaum-Regel:

Damit locate Operation einfach zu imple- mentieren.

k

T1 T2

Für alle Schlüssel k´ in T1 und k´´ in T2: k´ < k < k´´

(9)

locate(k) Operation

Locate-Strategie:

• Starte in Wurzel des Suchbaums

• Für jeden erreichten Knoten v:

– Falls key(v) > k, gehe zum linken Kind von v, sonst gehe zum rechten Kind

k

T1 T2

Für alle Schlüssel k´ in T1 und k´´ in T2: k´< k < k´´

(10)

Binärer Suchbaum

Formal: für einen Baumknoten v sei

• key(v) der Schlüssel in v

• d(v) die Anzahl Kinder von v

• Suchbaum-Invariante: (s.o.)

• Grad-Invariante:

Alle Baumknoten haben max. zwei Kinder

• Schlüssel-Invariante:

Für jedes Element e in der Liste gibt es genau einen Baumknoten v mit key(v) == e.key().

(11)

locate(9)

1 3 5 10 14 19 28

1 5

3

14 28

19 10

(12)

Insert und Remove Operationen

Strategie:

• insert(e):

Suche einen Knoten entweder mit e.key() < key und linkem Nachfolger null oder mit e.key() > key und rechtem Nachfolger null. Füge für e ein neues

Suchbaumblatt ein, so dass Suchbaum-Regel erfüllt ist.

• removeKey(k):

Suche einen Knoten mit key == k. Lösche den Inhalt des Knoten. Hat er keine Nachfolger, lösche den ganzen

Knoten. Hat er einen Nachfolger, verkürze. Hat er zwei Nachfolger, überschreibe ihn mit dem größten Knoten des linken Nachfolgers.

(13)

Insert(5)

1 10 14 28

1

28 14

10

(14)

Insert(5)

1 10 14 28

1

28 14

10

5 5

(15)

Insert(12)

1 10 14 28

1

28 14

10

5 5

(16)

Insert(12)

1 10 14 28

1

28 14

10

5 5

12 12

(17)

removeKey(1)

1 10 14 28

1

28 14

10

5 5

12 12

(18)

removeKey(1)

10 14 28

28 14

10

5 5

12 12

(19)

removeKey(14)

10 14 28

28 14

10

5 5

12 12

(20)

removeKey(14)

10 14 28

28 14

10

5 5

12 12

(21)

removeKey(14)

10 12 28

28 12

10

5 5

(22)

Datenstruktur

// Item: Typ für , TreeItem: Typ für

interface Elem<K extends Comparable<K>> { K key();}

class Item<K extends Comparable<K>, E extends Elem<K>> { // doppelt verketttete Liste von Elementen und Baumknoten TreeItem<K,E> t = null;

E e = null;

Item<K,E> prev, next;

Item () { prev = next = this;}

Item (E e, TreeItem<K,E> t, Item<K,E> prev, Item<K,E> next) { this.e = e; this.t = t; this.prev = prev; this.next = next;}

Item<K,E> insertBefore(E e, TreeItem<K,E> t) {...}

Item<K,E> insertAfter(E e, TreeItem<K,E> t) {...}

void remove() {...}

e

(23)

Datenstruktur

class TreeItem<K extends Comparable<K>, E extends Elem<K>> { // Baumknoten mit Schlüssel, Item, Vater und Nachfolgern

K key;

Item<K,E> item = null;

TreeItem<K,E> pa = null;

TreeItem<K,E> lc = null;

TreeItem<K,E> rc = null;

TreeItem(K key,TreeItem<K,E> pa) { this.key = key; this.pa = pa;

} ...

k

e

(24)

Datenstruktur

class SearchTree<K extends Comparable<K>, E extends Elem<K>> {

// erzeuge leere doppeltverkettete Liste Item<K,E> l;

TreeItem<K,E>;

SearchTree() {

l = new Item<K,E>();

t = new TreeItem(null,null); // leerer Baumknoten mit

t.item = l; // Verweis auf leeren Listenknoten l.t = t;

} ...

}

(25)

Locate Operation

// in SearchTree

Item<K,E> locate(K key) { if (t.rc == null) return l;

return t.rc.locate(key); // starte Suche in Wurzel }

// in TreeItem

Item<K,E> locate(K key) {

switch (key.compareTo (this.key)) { case -1: if (lc == null) return item;

else return lc.locate(key);

case 0: return item;

case +1: if (rc == null) return item.next;

return rc.locate(key);

}

return null;

(26)

Insert Operation

// in SearchTree

void insert(Element e) { K key = e.key();

if (t.rc == null) {

t.rc = new TreeItem<K,E> (key,t);

t.rc.item = l.insertAfter(e, t.rc);

} else t.rc.insert(e);

}

(27)

Insert Operation

// in TreeItem

void insert (E e) { K key = e.key();

if (key.compareTo(this.key) < 0) if (lc == null) { lc = new TreeItem<K,E>(key,this);

lc.item = item.insertBefore(e,lc);

} else lc.insert(e);

else if (rc == null) {

rc = new TreeItem<K,E>(key,this);

rc.item = item.insertAfter(e,rc);

} else rc.insert(e);

(28)

RemoveKey Operation

// in SearchTree

void removeKey(K key) { if (t.rc == null) return;

t.rc. removeKey(key);

}

// in TreeItem

void removeKey(K key) {

switch (key.compareTo(this.key)) { case -1: if (lc == null) break;

else lc.removeKey(key); break;

case +1: if (rc == null) break;

else rc.removeKey(key); break;

...

(29)

RemoveKey Operation

...

case 0: item.remove();

if (lc == null)

if (this == pa.lc) pa.lc = rc; // Hochkopieren des Nachfolgers else pa.rc = rc; // Hochkopieren des Nachfolgers if (rc!= null) rc.pa = pa; // Korrektur des Vaterverweises } else if (rc == null) {

if (this == pa.lc) pa.lc = lc;

else pa.rc = lc;

lc.pa = pa;

} else lc.removeMax(this);

} }

(30)

RemoveKey Operation

// in TreeItem

void removeMax(TreeItem<K,E> t) { if (rc == null) {

item.t = t;

t.item = item; t.key = item.e.key();

if (this == pa.lc) { pa.lc = lc;

if (lc != null) lc.pa = pa;

} else {

pa.rc = lc;

if (lc != null) lc.pa = pa;

}

} else rc.removeMax(t);

(31)

Binärbaum

Problem: Binärbaum kann entarten!

Beispiel: Zahlen werden in sortierter Folge eingefügt

1

3 5

14

28 19

10

locate() benötigt Θ (n) Zeit im worst case

(32)

(a,b)-Bäume

Problem: Binärbaum kann entarten!

Lösung: (a,b)-Baum Idee:

• Alle Knoten v außer der Wurzel enthalten

d(v)-1 Schlüssel mit a ≤ d(v) ≤ b, wobei a ≥ 2 und b ≥ 2a-1 ist

• Alle Blätter sind in derselben Ebene

(33)

(a,b)-Bäume

Formal: für einen Baumknoten v sei

• d(v)-1 die Anzahl der Schlüssel in v

• t(v) die Tiefe von v (Wurzel hat Tiefe 0)

• Form-Invariante:

Für alle Blätter v,w: t(v)=t(w)

• Grad-Invariante:

Für alle inneren Knoten v außer Wurzel: d(v) 2 [a,b], für Wurzel r: d(r) 2 [2,b]

(sofern #Elemente >1)

(34)

(a,b)-Bäume

Lemma 7.1: Ein (a,b)-Baum für n Elemente hat Tiefe max. 1+ loga (n/2)

Beweis:

• Die Wurzel hat Grad ≥ 2 und jeder andere innere Knoten hat Grad ≥ a.

• Bei Tiefe t gibt es mindestens 2at-1 Blätter

• n ≥ 2at-1 , t ≤ 1+loga n/2

(35)

(a,b)-Bäume

(a,b)-Suchbaum-Regel:

Damit locate Operation einfach zu imple-

s1, s2,…,sd-1

T1 T2 . . . . Td

Für alle Schlüssel k in Ti und k´ in Ti+1: k < si < k´

(36)

Locate(9)

1 3 5 10 14 19 28

1 3 5 14 19 28

10

(37)

Insert(e) Operation

Strategie:

• Suche Blatt v, in das e.key() gehört. Finde benachbartes Element e´ in dem Blatt.

Falls e'.key()>e.key(), füge e vor e´ ein, ansonsten dahinter.

. . . . . .

(38)

Insert(e) Operation

Strategie:

• Suche Blatt v, in das e.key() gehört. Finde benachbartes Element e´ in dem Blatt.

Falls e'.key()>e.key(), füge e vor e´ ein, ansonsten dahinter.

e‘

. . . e . . .

(39)

Insert(e) Operation

• Füge e.key() und Verweis auf e in Baumknoten v ein. Falls v nachher

weniger als b Elemente hat, dann fertig.

x y z

. . . . . . . . . x y z . . .

… x z … … x y z …

v v

(40)

Insert(e) Operation

• Falls v nachher b Elemente enthält, teile v in zwei Knoten auf.

(Beispiel: a=2, b=4)

x u u‘ y v

… a b…

w

x u y

… a u' b …

e e’ e e’

(41)

Insert(e) Operation

• Falls Grad von w größer als b, dann teile w in zwei Knoten auf (usw, bis Grad ≤ b oder Wurzel aufgeteilt wurde)

x y z t

w w

x y t

… z …

(42)

Insert(8)

3 5 10 14 19 28 42

3 5 10 19 28 42

a=2, b=4 14

(43)

Insert(8)

3 5 10 14 19 28 42

3 5 8 10 19 28 42

a=2, b=4 14

8

(44)

Insert(8)

3 5 10 14 19 28 42

3 5 19 28 42

8 14

a=2, b=4

8

10

(45)

Insert(32)

3 5 10 14 19 28 42

3 5 19 28 42

8 14

a=2, b=4

8

10

(46)

Insert(32)

3 5 10 14 19 28 32

3 5 19 28 32 42

8 14

a=2, b=4

8

10

42

(47)

Insert(32)

3 5 10 14 19 28 32

3 5

8 14 32

a=2, b=4

8

10

42

3 5 42

(48)

Insert Operation

• Form-Invariante:

Für alle Blätter v,w: t(v)=t(w) Erfüllt durch insert!

• Grad-Invariante:

Für alle inneren Knoten v außer Wurzel: d(v) 2 [a,b], für Wurzel r: d(r) 2 [2,b]

1) Insert splittet Knoten mit b Schlüsseln in Knoten mit b/2 bzw. (b-1)/2 Schlüsseln. Wenn b ≥ 2a-1, dann

beide Werte ≥ a-1.

2) Wenn Wurzel b Schlüssel enthält, wird eine neue Wurzel mit einem Schlüssel d.h. Grad 2 erzeugt.

(49)

removeKey(k) Operation

Strategie:

• Erst locate(k) bis Element e in Liste

erreicht. Falls e.key()==k, entferne e aus Liste, ansonsten stop.

. . . . . .

(50)

RemoveKey(k) Operation

Strategie:

• Erst locate(k) bis Element e in Liste

erreicht. Falls e.key()==k, entferne e aus Liste, ansonsten stop.

e´´

. . . . . .

(51)

RemoveKey(k) Operation

• Entferne Verweis auf e und Schlüssel k vom Baumknoten v mit e. Falls v ein Blatt ist und noch a-1 Schlüssel enthält, dann fertig.

x k y

. . . . . . . . . x y . . .

… x k y … … x y …

v v

(52)

RemoveKey(k) Operation

• Falls d(v) < a und direkter Nachbar von v hat Grad > a Schlüssel, nimm Kante von diesem Nachbarn. (Beispiel: a=2, b=4)

v

u r z

r s t u k z

k s t

(53)

RemoveKey(k) Operation

• Falls d(v) < a und kein direkter Nachbar

von v hat Grad >a, merge v mit Nachbarn.

(Beispiel: a=3, b=5)

v

u t

x y r s

x r s

u y t

(54)

Remove(k) Operation

• Veränderungen hoch bis Wurzel, und Wurzel hat Grad <2: entferne Wurzel.

x y z x y z

(55)

Remove(k) Operation

• Falls y in innerem Knoten gelöscht wird, ersetze durch max. Schlüssel in linkem Teilbaum. (Beispiel: a=2, b=4)

x y r s

u z t

x r s

u y t

(56)

Remove(10)

1 3 5 10 14 19 28

1 3 5 14 28

10 19

a=2, b=4

(57)

Remove(10)

1 3 5 14 19 28

1 3 5 14 28

a=2, b=4 19

(58)

Remove(10)

1 3 5 14 19 28

1 3 28

5 19

a=2, b=4

14

(59)

Remove(14)

1 3 5 14 19 28

1 3 28

5 19

a=2, b=4

14

(60)

Remove(14)

1 3 5 19 28

1 3 28

5 19

a=2, b=4

(61)

Remove(14)

1 3 5 19 28

28 3 19

a=2, b=4

5 1

(62)

Remove(3)

1 3 5 19 28

28 3 19

a=2, b=4

5 1

(63)

Remove(3)

1 5 19 28

28 1 19

a=2, b=4

5

(64)

Remove(3)

1 5 19 28

28

a=2, b=4 19

1 5

(65)

Remove(1)

1 5 19 28

28

a=2, b=4 19

1 5

(66)

Remove(1)

19

5 28

28

a=2, b=4 19

5

(67)

Remove Operation

• Form-Invariante:

Für alle Blätter v,w: t(v)=t(w) Erfüllt durch Remove!

• Grad-Invariante:

Für alle inneren Knoten v außer Wurzel: d(v) 2 [a,b], für Wurzel r: d(r) 2 [2,b]

1) Remove verschmilzt Knoten mit Grad a-1 mit Knoten mit Grad a. Wenn b ≥ 2a-1, dann hat resultierender

Knoten Grad ≤ b.

2) Remove verschiebt Kante von Knoten mit Grad >a nach Knoten mit Grad a-1. Auch OK.

3) Wurzel gelöscht: Kinder vorher verschmolzen, Grad vom verbleibenden Kind ≥ a (und ≤ b), also auch OK.

(68)

Mehr Operationen

• min/max Operation:

Verwende die first und last Operationen, um das kleinste oder größte Element auszugeben. Zeit O(1).

• Bereichsanfragen:

Um alle Elemente im Bereich [x,y] zu suchen, führe locate(x) aus und durchlaufe dann die Liste, bis ein Element >y gefunden wird. Zeit O(log n + Ausgabegröße).

(69)

Mehr Operationen

• Konkatenation:

Ziel: Verknüpfe zwei (a,b)-Bäume T1 und T2 mit s1 und s2 Elementen zu (a,b)-Baum T (Schlüssel in T1 < Schlüssel in T2)

T1 + T2 = T

(70)

Mehr Operationen

• Konkatenation:

Strategie (s1 ≤ s2):

T1

T2

k …

>b Kanten:

wie insert-Op behandeln

k

<a Kanten:

wie remove-Op behandeln

(71)

Mehr Operationen

• Aufspaltung:

Ziel: Spalte (a,b)-Baum T in (a,b)-Bäume T1 und T2 bei Schlüssel k auf.

T

T1

T2

(72)

Split-Operation

1. Suche nach k

k

v1 v2

v3

vk . . .

Pfad

nach k : Such-

pfad

(73)

Split-Operation

2. Aufspaltung entlang Suchpfad

k

s1 … k si … sd-1

s s … s s1 … si si+1 … sd-1

s1 … si si+1 … sd-1 links rechts

links rechts

: Such- pfad

(74)

Split-Operation

2. Abbruch bei Aufspaltung:

k s1 s1>k: Aufspal-

tung hier been- den

Fall 1:

k

….sd-1 sd-1<k: Aufspal- tung hier been- den

Fall 2:

(75)

Split-Operation

1. Gradreparatur in den beiden Teilbäumen

Strategie: bottom-up entlang Suchpfad, um zu gültigen (a,b)-Bäumen zurückzukeh- ren. (Wie bei insert und remove

Operationen.)

(76)

Split(1)

3 10

1 5 14 19 28

1 3 5 14 17 28

10 19

a=2, b=4

17

(77)

Split(1)

3 5 10 14 19 28

3 5 14 17 28

10 19

17 1

1

(78)

Split(5)

3 5 10 14 19

1 28

1 3 5 14 17 28

10 19

a=2, b=4

17

(79)

Split(5)

10 14 19 28

14 17 28

10 19

3 5 17 1

1 3 5

(80)

Split(5)

10 14 19 28

28 14 19

17 10

3 5

1

1 3 5 17

(81)

Split(10)

3 5 10 14 19

1 28

1 3 5 14 17 28

10 19

a=2, b=4

17

(82)

Split(10)

3 5 10 14 19

1 28

1 3 5 14 17 28

17

10 19

(83)

Split(10)

3 5 10 14 19

1 28

14 17 28

17

5 19

1 3 10

(84)

n Update-Operationen

Theorem: Es gibt eine Folge von n insert und removeKey Operationen im (2,3)- Baum, so dass Gesamtanzahl der split und merge Operationen Ω (n log n) ist.

Beweis: Übung.

(85)

n Update-Operationen

Theorem 7.3: Betrachte einen (a,b)-Baum mit b ≥ 2a, der anfangs leer ist. Für jede Folge von n insert und remove Opera-

tionen ist die Gesamtanzahl der split und merge Operationen O(n).

Beweis:

Amortisierte Analyse

(wird nicht in Vorlesung behandelt)

(86)

Zusammenfassung

• Binäre Suchbäume

• (a,b)-Bäume

• Zusätzliche Operationen

• Weiter mit Graphrepräsentationen (Kapitel 8)

(87)

Externer (a,b)-Baum

Prozessor

Interner Speicher

Externer Speicher Blockgröße B

Größe M

(88)

Externer (a,b)-Baum

Problem: Minimiere Blocktransfers zwischen internem und externem Speicher

Lösung:

• verwende b=B (Blockgröße) und a=b/2

• halte oberste loga(M/b) Ebenen des (a,b)-Baums im internen Speicher (Speicher <= M)

• Lemma 7.1: Tiefe des (a,b)-Baums max.1+bloga (n+1)/2c

• loga[(n+1)/2] - loga(M/b) = loga[(n+1)/(2M)] + logab

• logab = O(1)

• Kosten für insert, remove und locate Operationen:

O(log (n/M)) Blocktransfers

Referenzen

ÄHNLICHE DOKUMENTE

We model the life cycle of a private key as a finite state machine. Each phase in a private key’s life is represented by an appropriate state of the machine. Having these states, it

Hier geht es um die Berechnung eines gemeinsamen Geheimnisses durch A und B, welches zur Erzeugung symmetrischer Schl ¨ussel verwendet werden kann.. A und B f ¨uhren dazu ein

Die Evidenz basierte Medizin (EbM) bezieht neben der externen Evidenz aus Studien auch die klinische Erfahrung des Arztes und die Entscheidung des Patienten (interne Evidenz) als

clustering index stores records on consecutive disk pages insertion between two consecutive pages not possible if disk page is full, overflowing records go to overflow pages

create table tweet id integer not null primary key user id integer null references twitter user on delete set null tweet date timestamp not null tweet text varchar 140 not mail

Gerade Verfahren wie XTR oder NTRU mit Laufzeiten von deutlich unter einer Sekunde und wenigen hundert Bytes Speicher- verbrauch erm¨oglichen den Entwurf neuer Protokolle

For a detailed record of security incidents occurring in Nigeria, subscribers should refer to Scott Wilcox Online information System (OIS)..

SMartNose showed different aroma profiles for milk samples collected after forage provision, before and after TMR feeding.. With exception of Sinapis arvensis, the milk samples