05 Datenstrukturen

Werbung
Datenstrukturen & Algorithmen
Matthias Zwicker
Universität Bern
Frühling 2010
Übersicht
Elementare Datenstrukturen für
dynamische Mengen
• Stapel
p & Warteschlangen
g
• Verkettete Listen
• Bäume
• Anwendungsbeispiel: kd-Bäume
2
Dynamische Mengen
• Daten speichern und abfragen
• Daten: Records aus Schlüssel und
Satellitendaten
class Record {
int key;
SatelliteData data;
}
class SatelliteData{
String name;
String address;
...
}
3
Operationen
• Dynamische Menge S, Schlüssel k, Referenz
auf Record x
–
–
–
–
–
–
–
Search(S,k)
Insert(S,x)
Delete(S x)
Delete(S,x)
Minimum(S)
Maximum(S)
Successor(S,x)
Predecessor(S,x)
4
Datenstrukturen
• Geeignete Datenstruktur je nach
Operationen die effizient unterstützt
Operationen,
werden soll
• Zeitkomplexität wird als Funktion der
Grösse n der Menge gemessen
• Beispiel:
p
Heaps
p
– Abfragen von Minimum, Maximum in O(1)
5
Stapel & Warteschlangen
• Dynamische Mengen mit effizientem
Einfügen und Entfernen in O(1)
– Insert(S,x)
– x = Remove(S)
( )
Stapel
• Einfügen und Entfernen mit last-in-, firstout Strategie (LIFO)
out-Strategie
Warteschlangen
g
• Einfügen und Entfernen mit first-in-, firstout Strategie (FIFO)
out-Strategie
6
Stapel (LIFO)
• Einfügen = push, Entfernen = pop, Aufwand O(1)
• Hier: Implementation mit Feld
– Implementation mit anderen Datenstrukturen
möglich
– Elemente hier Integers der Einfachkeit halber,
Records mit Satellitendaten funktioniern gleich
g
• Statusvariable top
1 23 4 5 6 7 8
Stack S 161410 8 7
topp = 5
class Stack {
private int top;
private
p
ate int
t S[];
/* constructor,
methods push, pop */
}
7
Stapel
• Beispiel
push(4); push(6); pop; push(8); pop; pop;
1 23 4 5 6 7 8
Stack S 161410 8 7
top = 5
8
Anwendung
• Verwaltung von Methodenaufrufen
– Speichert Rücksprungadresse und lokale
Variablen
• Aufruf einer Methode
– P
Push:
h Rü
Rücksprungadresse
k
d
– Push: Speicherplatz für lokale Variablen der
aufgerufenen Methode
• Ende der Methode
– Pop: lokale Variablen
– Pop: Rücksprungadresse
9
Anwendung
Stack
H
H;
void
id H {
…;
e();
…;
}
void
id e {
…;
l();
…;
W();
…;
}
void
id l() {
…;
o();
…;
}
10
Stack overflow
• Zu tiefe Verschachtelung von Aufrufen
• Zu hohe Rekursionstiefe
Rekursionstiefe, so dass Stack
Speicher zu klein
• Führt zu Terminierung des Programms
• Beispiel: worst case Ablauf von Quicksort
• Rekursive Aufrufe können durch eigene
Verwaltung
g eines Stacks vermieden werden
• Vorteile
– Kl
Kleinerer
i
Aufwand
A f
d
– Programm kann mehr Speicher für Stack
allokieren wenn nötig
11
Anwendung
• Nicht-rekursiver QuickSort mit Stack
void quickSort(int array[], int left, int right)
{
Stack leftStack = new Stack();
Stack rightStack = new Stack();
leftStack.push(left); rightStack.push(right);
while(!leftStack.isEmpty())
(
p y())
{
left = leftStack.pop(); right = rightStack.pop();
if(left<right)
{
int p = partition(array, left, right);
leftStack push(left); rightStack
leftStack.push(left);
rightStack.push(p-1);
push(p 1);
leftStack.push(p+1); rightStack.push(right);
}
}
}
12
Warteschlange (FIFO)
• Einfügen = queue, Entfernen = dequeue, Aufwand
O(1)
• Hier: Implementation mit Feld
– Implementation
p
mit anderen Datenstrukturen möglich
g
(z.B. verkettete Listen)
• Statusvariable kopf, ende
– ende zeigt auf erstes freies Element
Queue Q
1 23 4 5 6 7 8
10 8 7 1614
kopf
p =3
ende = 8
class Q
Queue {
private int kopf, ende;
private int Q[];
/* constructor,
methods queue,
dequeue */
}
13
Warteschlange
• Beispiel
queue(6); queue(9); queue(11); dequeue; dequeue
Queue Q
1 23 4 5 6 7 8
10 8 7 1614
kopf = 3
ende = 8
14
Anwendungen
• Verwaltung von Aufträgen, die mittels
einer first-come,
first-come first-serve Strategie
bearbeitet werden sollen
– Z.B. Printer Server, Datenbankabfragen über
Internet
15
Übersicht
Elementare Datenstrukturen
• Stapel & Warteschlangen
• Verkettete Listen
• Bäume
• Anwendungsbeispiel: kd-Bäume
16
Verkettete Listen
• Vorteil gegenüber Feldern: maximale Anzahl
Elemente ist dynamisch
y
• Nachteil: Zugriff auf ein Element in
konstanter Zeit mittels Index nicht möglich
• Können Stacks und Warteschlangen auch mit
verketteten Listen implementieren
• Varianten
–
–
–
–
Einfach verkettete Liste
D
Doppelt
l verkettete
k
Li
Liste
Zyklische Liste
(Sortierte
S
Liste)
17
Verkettete Listen
• Listenelemente bestehen aus
– Schlüssel ((oder Referenz auf andere Daten))
– Zeiger next auf nachfolgendes Listenelement
– Doppelt verkettet: Zeiger prev auf vorheriges
Listenelement
• Anfang: Zeiger head auf erstes Listenelement
• Ende:
E d null
ll Zeiger
Z i
class LinkedList {
private class ListElement {
ListElement prev, next;
i
int
k
key;
}
ListElement head;
/* methods to add elements, etc. */
}
18
Durchsuchen
ListElement Search(int k) {
ListElement cur = head;
while(cur!=null
hil (
!
ll && k!
k!=cur.key)
k )
cur = cur.next;
return cur;
}
19
Einfügen
• Doppelt verkettete Liste
void insert(ListElement e) {
e.next = head;
if(head!=null)
head prev = e;
head.prev
head = e;
e.prev = null;
}
20
Entfernen
• Doppelt verkettete Liste
void
id d
delete(ListElement
l t (Li tEl
t d) {
if(d.prev!=null)
d.prev.next = d.next;
else
head = d.next;
if(d.next!=null)
d.next.prev = d.prev;
}
21
Wächter
• Spezielles Wächterobjekt nil, um Randbedingungen
zu vereinfachen
• Verknüpfte Liste zu einem Ring (zyklische Liste)
• Zeiger auf Wächter nil,
il ersetzt head
h d
• Hier doppelt verkettete Liste
class CyclicList {
private class ListElement {
ListElement prev, next;
int key;
}
ListElement nil;
/* methods to add elements,
/
, etc. */
/
}
22
Einfügen in Liste mit Wächter
void insertElement(ListElement e) {
e.next = nil.next;
nil.next.prev
il
= e;
nil.next = e;
e.prev = nil;
}
23
Parameterisierte Klasse in Java
class LinkedList<T> {
private class Element {
private Element prev, next;
private T data; // Satellitendaten
}
private Element nil;
LinkedList()
() {
nil = new Element();
nil.next = nil;
nil.prev = nil;
}
void insert(T e) {
{...}
}
/* add other operations */
}
24
Zeiger und Objekte mit Feldern
• Was, wenn eine Programmiersprache keine
Zeiger zur Verfügung stellt?
• Implementiere
p
Zeiger
g und Objekte
j
mit
Feldern
25
Zeiger und Objekte mit Feldern
• Liste
head
9
16
4
1
• Mehrfelddarstellung
1 2 3 4 5 6 7 8
next
key
prev
• Einfelddarstellung
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
1 16 17
1 18 19 20 21 22 23 24
26
Allokieren und Freigeben von Objekten
• Wollen Operationen auf dynamischen Listen anbieten
wie vorher
– Insbesondere, allokieren und einfügen neuer Objekte
– Allokieren ähnlich „new()“ in Java
– Brauchen Zugriff auf freie Elemente in Felder
• Unterhalte zwei Listen
• Liste mit Daten
– Doppelt verknüpft
– Kopf heisst head
• Liste mit freien Objekten
– Einfach verknüpft
– Kopf heisst free
next
k
key
prev
27
Allokieren und Freigeben
x = allocateObject();
insert(x);
key[x] = 25;
delete(5);
1 2 3 4 5 6 7 8
next
y
key
prev
1 2 3 4 5 6 7 8
next
y
key
prev
1 2 3 4 5 6 7 8
next
y
key
prev
28
Übersicht
Elementare Datenstrukturen
• Stapel & Warteschlangen
• Verkettete Listen
• Bäume
• Anwendungsbeispiel: kd-Bäume
29
Gerichtete Bäume
• Verallgemeinerung von linearen Listen mit
Verkettung zu einer Baumstruktur
• Wie bei Listen: Elemente enthalten
– Schlüssel (oder Referenzen auf Satellitendaten)
– Referenzen zur Verkettung
• Grundlage für viele Algorithmen
– z.B. Suchen
• Heute
– Binäre Bäume
– Bäume mit unbeschränktem Grad
30
Binäre Bäume
class BinaryNode {
BinaryNode parent, left, right;
i t key;
int
k
}
31
Bäume mit unbeschränktem Grad
class Node {
Node parent, firstChild, nextSibling;
i
int
k
key;
}
32
Übersicht
Elementare Datenstrukturen
• Stapel & Warteschlangen
• Verkettete Listen
• Bäume
• Anwendungsbeispiel: kd-Bäume
33
kd-Bäume
Problem
• Speichere Position einer Menge von
Punkten im d-dimensionalen Raum
• Wollen effiziente Abfragen wie
– Gegeben Abfragepunkt, finde nächsten
Nachbarn in der Punktmenge
– Finde k-nächste Nachbarn
– Finde
Fi d alle
ll N
Nachbarn
hb
iin einem
i
gewissen
i
R
Radius
di
• Naiver Ansatz erlaubt Abfragen
g in O(n)
( )
34
Kd-Bäume
• Räumliche Datenstruktur
– Aufbau der Datenstruktur hat mit räumlicher
Anordnung der Daten zu tun
• Erlaubt effiziente Abfragen in O(lg n)
• Anwendungen
A
d
– Künstliche Intelligenz
Intelligenz, Klassifikation
http://en.wikipedia.org/wiki/K-nearest_neighbor_algorithm
http://en.wikipedia.org/wiki/Nearest_neighbor_search
– Computergrafik,
C
t
fik Ray
R T
Tracing
i
35
Konstruktion
• kd-Baum teilt Raum rekursiv entlang einer SplitEbene in zwei Halbräume
• Jeder Knoten
– Speichert
p
einen Punkt
– Definiert eine Split-Ebene durch den Punkt
• Split-Ebenen
– Sind immer achsenparallel
– Orientierung der Split-Ebene gegeben durch Tiefe im
Baum
– Alle Punkte im linken Teilbaum liegen „unter“ der
p
, im rechten Teilbaum „über“ der Splitp
Split-Ebene,
Ebene
• Siehe auch
http://en.wikipedia.org/wiki/Kd-tree
p
p
g
36
Beispiel
Menge
g von Punkten in 2D
kd-Baum
37
Konstruktion
• Balancierter kd-Baum
– axis
i ist
i t eine
i Koordinatenachse
K di t
h (x
( oder
d y iin 2D)
– cycle(axis) rotiert durch die Koordinatenachsen:
h
cycle(x) = y, cycle(y) = x
node
d constructKdTree
t
tKdT
(
(set
t of
f points,
i t
axis)
i )
if set of points is empty return null;
else {
select median point along axis
split set of points into set below and above median
create node with location of median point
node.left = kdtree(points below median, cycle(axis))
node.right = kdtree(points above median, cycle(axis))
return node
}
}
38
Einfügen
• Eingabe: neuer Punkt
• Ausgabe: kd-Baum der neuen Punkt enthält
• Ablauf
– Traversiere kd-Baum bis zu einem Blatt
• Bei jedem Knoten, entscheide basierend auf
Vergleich
g
von Position von Knoten und neuem
Punkt, in welchen Teilbaum zu gehen
– Wenn Blatt erreicht,, erstelle neuen Knoten,,
der dem Blatt als Kind angehängt wird
39
Einfügen
Neuer Punkt ((3,5)
, )
40
Nächster Nachbar
• Input: Abfragepunkt, Punktemenge in kd-Baum
• Output: Punkt im kd-Baum,
kd Baum der am nächsten
beim Abfragepunkt liegt
• Ablauf
– Traversiere kd Baum bis zu Blatt
Blatt, in das der
Abfragepunkt fällt
– Blattknoten
latt ote ist
st Kandidat
a d dat für
ü nächster
äc ste Nac
Nachbar
ba
– Traversiere Baum zurück zur Wurzel, bei jedem
Knoten
• Falls Knoten näher als bisheriger Kandidat, wird neuer
Kandidat
• Falls im anderen Teilbaum näherer Punkt möglich,
möglich
traversiere anderen Teilbaum
41
Beispiel
Nächster Nachbar von
Abfragepunkt (3.5, 4.5)
kd-Baum
42
Beispiel
Nächster Nachbar von
Abfragepunkt (6.5, 0)
kd-Baum
43
Nächstes Mal
• Kapitel 11: Hashtabellen
44
Herunterladen