VDS 11 - Binär- und Suchbäume

Werbung
Vorlesung Datenstrukturen
Binärbaum
Suchbaum
Dr. Frank Seifert
Vorlesung Datenstrukturen - Sommersemester 2016
Folie 356
Datenstruktur Binärbaum
Strukturrepräsentation des mathematischen Konzepts Binärbaum
struct node {
Elementtyp data; node* left;
// linker Teilbaum / Kindknoten
node* right;
// rechter Teilbaum / Kindknoten
};
Es existieren zwei Verbindungen zu den Kindknoten und Nullzeiger realisieren externe Knoten.
Mit dieser Darstellung können die meisten Operationen für binäre Bäume effizient realisiert
werden, allerdings lassen sich so nur Bewegungen von der Wurzel weg im Baum ausdrücken,
d.h. nur Kindknoten verarbeiten.
Für Algorithmen, die auf der direkten Kenntnis der übergeordneten Knoten basieren, bietet sich
analog zur doppelt verketteten Liste die Ergänzung der Knotenstruktur um einen Verweis auf den
Vorgänger eines Knotens an.
Dr. Frank Seifert
Vorlesung Datenstrukturen - Sommersemester 2016
Folie 357
Beispiel - Aufbau eines Binärbaums
Gesucht
Algorithmus zum Aufbau eines möglichst ausgeglichenen Binärbaums mit beliebiger Knotenanzahl
Idee
Rekursive Verteilung der zu erzeugenden Knotenanzahl gleichmäßig auf die Teilbäume
node* exampleTree( int count ) {
if ( count ) {
int leftNodes
= count / 2;
int rightNodes = count - leftNodes - 1;
node* newNode
= new node;
newNode->left
= exampleTree( leftNodes );
newNode->right = exampleTree( rightNodes );
return newNode;
}
else return 0;
}
Dr. Frank Seifert
Vorlesung Datenstrukturen - Sommersemester 2016
Folie 358
Traversieren von Binärbäumen
Traversierung geordneter Bäume
Im Gegensatz zur linearen Durchmusterung von Listen muss bei Bäumen eine Entscheidung
getroffen werden: Diese Entscheidung besteht jedoch nicht darin, welcher Nachfolgerknoten
ausgewählt wird (denn die Reihenfolge ist durch die Ordnung bereits vorgegeben), sondern
wann ein Knoten bzgl. seiner Kindknoten ausgewertet wird.
Traversierung von Binärbäumen
Bei Binärbäumen gibt es drei Möglichkeiten:
• Präorder
- Traversierung = Auswertung eines Knotens vor seinen Kindern
• Inorder
- Traversierung = Auswertung eines Knotens inmitten seiner Kinder
• Postorder - Traversierung = Auswertung eines Knoten nach seinen Kindern
Ergebnis der Traversierung
Konvertierung einer komplexeren Baumstruktur in eine „flache“ Listenstruktur.
Dr. Frank Seifert
Vorlesung Datenstrukturen - Sommersemester 2016
Folie 359
Präorder-Traversierung
Reihenfolge
void traverse( node* n ) {
if ( n ) {
process ( n->info );
traverse( n->left );
traverse( n->right );
}
}
1. Auswertung des Knotens
2. Auswertung des linken Teilbaums
3. Auswertung des rechten Teilbaums
A
B
I
C
D
F
E
G
J
H
K
M
L
N
O
Bezeichnung
Ein Knoten wird vor seinen Kindknoten verarbeitet, also Präorder-Traversierung
Dr. Frank Seifert
Vorlesung Datenstrukturen - Sommersemester 2016
Folie 360
Inorder-Traversierung
Reihenfolge
void traverse( node* n ) {
if ( n ) {
traverse( n->left );
process ( n->info );
traverse( n->right );
}
}
1. Auswertung des linken Teilbaums
2. Auswertung des Knotens
3. Auswertung des rechten Teilbaums
H
D
L
B
A
F
C
E
J
G
I
N
K
M
O
Bezeichnung
Ein Knoten wird inmitten seiner Kindknoten verarbeitet, also Inorder-Traversierung
Dr. Frank Seifert
Vorlesung Datenstrukturen - Sommersemester 2016
Folie 361
Postorder-Traversierung
Reihenfolge
void traverse( node* n ) {
if ( n ) {
traverse( n->left );
traverse( n->right );
process ( n->info );
}
}
1. Auswertung des linken Teilbaums
2. Auswertung des rechten Teilbaums
3. Auswertung des Knotens
O
G
N
C
A
F
B
D
J
E
H
M
I
K
L
Bezeichnung
Ein Knoten wird nach seinen Kindknoten verarbeitet, also Postorder-Traversierung
Dr. Frank Seifert
Vorlesung Datenstrukturen - Sommersemester 2016
Folie 362
Level-Order-Traversierung
Wunsch
Ebenenweise Verarbeitung von Baumknoten
A
Problem
B
Im Gegensatz zu den bereits bekannten Traversierungs-
C
arten entspricht eine ebenenweise Verarbeitung von Baumknoten nicht der natürlichen rekursiven D
E
F
G
Definition eines Baums.
Lösung
H
I
J
K
L
M
N
Um Bäume ebenenweise verarbeiten zu können, ist eine Zwischenspeicherung von Baumknoten
nötig, die mit Hilfe der Datenstruktur Schlange realisiert wird.
Dr. Frank Seifert
Vorlesung Datenstrukturen - Sommersemester 2016
Folie 363
O
ADT Schlange / Queue
ADT Schlange
Für viele Aufgaben in der Informatik werden Datenstrukturen benötigt, die nach dem FIFO-Prinzip
arbeiten, d.h. dass das zuerst eingefügte Element auch als erstes wieder entnommen wird.
Analog zum ADT Stapel wollen wir deshalb einen abstrakten Datentyp für die Datenstruktur
Schlange entwickeln.
Anwendung
Da wir die Schlange konkret zur Baumtraversierung benötigen, muss sie Baumknoten bzw.
Zeiger auf Baumknoten verwalten. Dementsprechend gestalten wir die Schnittstelle des ADT:
class Queue {
Queue()
// Schlange mit Elementtyp „Baumknoten“
// Konstruktor
~Queue()
//
bool isEmpty()
//
void enqueue(node* data) //
node* dequeue()
//
Destruktor
Test auf leere Schlange
„Anstellen“ an die Schlange
„Abfertigen“ des ersten Elements
}
Dr. Frank Seifert
Vorlesung Datenstrukturen - Sommersemester 2016
Folie 364
ADT Queue - Interne Struktur
struct node {
Elementtyp data;
node* left;
node* right; };
class Queue {
struct list {
node* data;
// Wir fügen Baumknoten in Schlange ein
list* next;
list(node* value) { // Hier eine Variante mit struct-Konstruktor
data = value;
next = 0;
}
};
list* head;
// Einfügen und Entnehmen von Elementen erfolgt bei
list* tail;
// Schlangen an den entgegengesetzten Enden einer Liste
Dr. Frank Seifert
Vorlesung Datenstrukturen - Sommersemester 2016
Folie 365
ADT Queue - Methoden
public:
node* dequeue() {
if (isEmpty()) {
printf("Schlange leer");
Queue() {
head = tail = 0;
}
return 0;
}
else {
node* value = head->data;
bool isEmpty() {
return (head == 0);
}
list* next = head->next;
delete head;
head = next;
return value;
void enqueue(node* value) {
list* t = tail;
tail = new list(value);
if (!head)
}
head = tail;
}
~Queue() {
… // Löschen aller Listenelemente
t->next = tail;
}
else
}
Dr. Frank Seifert
};
Vorlesung Datenstrukturen - Sommersemester 2016
Folie 366
Level-Order-Traversierung
Um die ebenenweise Verarbeitung zu ermöglichen, modifizieren wir die Präorder-Traversierung:
• Zu Beginn fügen wir den Wurzelknoten des Baumes in eine Schlange ein.
• Solange die Schlange nicht leer ist entnehmen wir den aktuell zu verarbeitenden Knoten n aus der
Schlange, verarbeiten ihn und fügen die Kinder von n in die Schlange ein
void traverseLevelOrder( node* n ) {
Queue q;
q.enqueue( n );
while ( !q.isEmpty() ) {
n = q.dequeue();
process( n->info );
if ( n->left )
q.enqueue( n->left );
if ( n->right )
q.enqueue( n->right );
}
}
Dr. Frank Seifert
A
B
C
D
H
E
I
Vorlesung Datenstrukturen - Sommersemester 2016
J
F
K
L
G
M
N
Folie 367
O
Binärer Suchbaum
Dr. Frank Seifert
Vorlesung Datenstrukturen - Sommersemester 2016
Folie 368
Binärer Suchbaum
Definition
Ein binärer Suchbaum ist ein binärer Baum, dessen interne Knoten mit einem Schlüssel verbunden
sind.
8
Schlüssel sind eindeutig, es gibt keine verschiedenen Knoten mit dem selben Schlüssel.
4
12
Alle Knoten, deren Schlüssel kleiner als der Schlüssel eines Knotens ist, befinden sich im linken Teilbaum.
2
6
10
14
Alle Knoten, deren Schlüssel größer als der Schlüssel eines Knotens ist, befinden sich im rechten Teilbaum.
1
3
5
7
9
11
13
Konsequenz
Die Gestalt der Datenstruktur „Suchbaum“ ist abhängig von ihren Werten!
Dr. Frank Seifert
Vorlesung Datenstrukturen - Sommersemester 2016
Folie 369
15
Suchen im binären Suchbaum (1)
Rekursiver Algorithmus
8
Aus der Gestalt eines Suchbaums ergibt sich ein rekursiver Suchalgorithmus:
• Ist der aktuell betrachtete Baumknoten n ein externer Knoten ➔ erfolgloser Abbruch der Suche
• sonst Vergleich des gesuchten Schlüssels mit dem Schlüssel von n
1
4
12
2
6
3
5
10
7
9
14
11
13
- Stimmen die Schlüssel überein ➔ erfolgreicher Abbruch der Suche
- Ist der gesuchte Schlüssel kleiner, suche im linken Teilbaum von n
- Ist der gesuchte Schlüssel größer, suche im rechten Teilbaum von n
Initialisierung
Startknoten des Algorithmus ist die Wurzel des Suchbaumes
Dr. Frank Seifert
Vorlesung Datenstrukturen - Sommersemester 2016
Folie 370
15
Suchen im binären Suchbaum (2)
Quelltext
Algorithmus liefert Zeiger auf Baumknoten mit gefundenem Element oder Nullzeiger
node* search( node* tree, int value ) {
if ( tree == 0 ) {
// value nicht vorhanden
return 0;
if ( tree->data == value )
// Element gefunden
return tree;
if ( value < tree->data )
return search( tree->left, value );
// Suche links
else
return search( tree->right, value ); // Suche rechts
}
}
Dr. Frank Seifert
Vorlesung Datenstrukturen - Sommersemester 2016
Folie 371
Suchen im Suchbaum
Suche nach 37
50
20
70
11
40
6
3
15
7
12
Dr. Frank Seifert
59
31
19
26
45
37
44
85
55
48
51
66
57
Vorlesung Datenstrukturen - Sommersemester 2016
63
80
68
79
91
84
88
Folie 372
99
Suchen im Suchbaum
37 ist kleiner als 50 ➔ Verzweigung nach links
Suche nach 37
50
20
70
11
40
6
3
15
7
12
Dr. Frank Seifert
59
31
19
26
45
37
44
85
55
48
51
66
57
Vorlesung Datenstrukturen - Sommersemester 2016
63
80
68
79
91
84
88
Folie 373
99
Suchen im Suchbaum
Suche nach 37
50
20
70
11
40
6
3
15
7
12
Dr. Frank Seifert
59
31
19
26
45
37
44
85
55
48
51
66
57
Vorlesung Datenstrukturen - Sommersemester 2016
63
80
68
79
91
84
88
Folie 374
99
Suchen im Suchbaum
Suche nach 37
50
37 ist größer als 20 ➔ Verzweigung nach rechts
20
11
40
6
3
15
7
70
12
Dr. Frank Seifert
59
31
19
26
45
37
44
85
55
48
51
66
57
Vorlesung Datenstrukturen - Sommersemester 2016
63
80
68
79
91
84
88
Folie 375
99
Suchen im Suchbaum
Suche nach 37
50
20
70
11
40
6
3
15
7
12
Dr. Frank Seifert
59
31
19
26
45
37
44
85
55
48
51
66
57
Vorlesung Datenstrukturen - Sommersemester 2016
63
80
68
79
91
84
88
Folie 376
99
Suchen im Suchbaum
Suche nach 37
50
20
11
40
6
3
15
7
12
Dr. Frank Seifert
59
31
19
70
37 ist kleiner als 40 ➔ Verzweigung nach links
26
45
37
44
85
55
48
51
66
57
Vorlesung Datenstrukturen - Sommersemester 2016
63
80
68
79
91
84
88
Folie 377
99
Suchen im Suchbaum
Suche nach 37
50
20
70
11
40
6
3
15
7
12
Dr. Frank Seifert
59
31
19
26
45
37
44
85
55
48
51
66
57
Vorlesung Datenstrukturen - Sommersemester 2016
63
80
68
79
91
84
88
Folie 378
99
Suchen im Suchbaum
Suche nach 37
50
20
70
11 37 ist größer als 31 ➔ Verzweigung nach rechts
6
3
15
7
12
Dr. Frank Seifert
40
59
31
19
26
45
37
44
85
55
48
51
66
57
Vorlesung Datenstrukturen - Sommersemester 2016
63
80
68
79
91
84
88
Folie 379
99
Suchen im Suchbaum
Suche nach 37
50
20
70
11
40
6
3
15
7
12
Dr. Frank Seifert
59
31
19
26
45
37
44
85
55
48
51
66
57
Vorlesung Datenstrukturen - Sommersemester 2016
63
80
68
79
91
84
88
Folie 380
99
Suchen im Suchbaum
Suche nach 37
50
20
70
11
40
6
15
59
31
45
85
55
66
80
91
37 wurde mit nur 5 Vergleichen gefunden, bei 31 Elementen
3
7
12
Dr. Frank Seifert
19
26
37
44
48
51
57
Vorlesung Datenstrukturen - Sommersemester 2016
63
68
79
84
88
Folie 381
99
Suchen im Suchbaum
Suche nach 37
50
Komplexitätsanalyse
Die Suche benötigt in einem ausgeglichenen
binären Suchbaum bei N Knoten maximal
20
ld(N) Schritte. Damit hat das Suchverfahren
11
eine Komplexität von O(log N).
40
Vergleich
6
15
31
45
Im Vergleich zur linearen Laufzeit der Suche
nach einem Listenelement oder einer
3
7
12
19
26
37
44
48
Feldkomponente arbeitet die Suche nach
einem Element in einem ausgeglichenen
Suchbaum wesentlich effizienter.
Dr. Frank Seifert
Vorlesung Datenstrukturen - Sommersemester 2016
Folie 382
Einfügen in einen Suchbaum (1)
Such- und Einfügeoperationen
eines Suchbaums sind eng
miteinander verwandt:
Der Knoten, an dem die Suche
(nach einem nichtvorhandenen
Schlüssel) abbricht, entspricht
der Position, an dem ein neuer
Knoten mit diesem Wert
eingefügt werden muss.
Der eingefügte bzw. bereits
vorhandene Knoten wird als
Funktionswert zurückgeliefert.
Dr. Frank Seifert
node* insert(node* tree, int value) {
node* temp;
if (tree) {
if (tree->data == value) return tree;
if (value < tree->data)
if (tree->left)
return insert(tree->left, value);
else tree->left = temp = new node;
else
if (tree->right)
return insert(tree->right, value);
else tree->right = temp = new node;
}
else
temp = new node;
temp->data = value;
temp->left = 0;
temp->right = 0;
return temp;
}
Vorlesung Datenstrukturen - Sommersemester 2016
Folie 383
Einfügen in einen Suchbaum (2)
Komplexitätsanalyse
Analog der Suchoperation benötigen wir bei einem ausgeglichenen binären
Suchbaum mit N Knoten höchstens ld(N) Vergleiche um die Einfügeposition zu
bestimmen und einen neuen Knoten anzuhängen ➔ Komplexität O(log N).
Im Vergleich zur linearen Laufzeit zum Bestimmen der Einfügeposition in einer Liste
arbeitet das Einfügen in einen ausgeglichenen Suchbaum wesentlich effizienter.
Aber
Bei „falscher“ Reihenfolge des Einfügens kann ein Baum sehr schnell degenerieren.
Wenn das Ausgeglichenheitskriterium verletzt wird, tendiert die Laufzeit für Such- und
Einfügeoperationen in die Größenordnung der entsprechenden Listenoperationen.
Dr. Frank Seifert
Vorlesung Datenstrukturen - Sommersemester 2016
Folie 384
Ende der Vorlesung
Dr. Frank Seifert
Vorlesung Datenstrukturen - Sommersemester 2016
Folie 385
Herunterladen