3 Dynamische Datenstrukturen

Werbung
Praktische Informatik I - Algorithmen und Datenstrukturen
3
Wintersemester 2006/07
Dynamische Datenstrukturen
Beispiele für dynamische Datenstrukturen sind
Lineare Listen
Schlangen
Stapel
Bäume
Prof. Dr. Dietmar Seipel
128
Praktische Informatik I - Algorithmen und Datenstrukturen
3.1
Wintersemester 2006/07
Lineare Listen
Eine Folge
kann implementiert werden als eine lineare
Liste von Knoten von folgendem Typ:
Node
public class Node {
int key;
Node next;
Node(int k) {
key = k;
next = null;
}
}
Prof. Dr. Dietmar Seipel
129
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
Diese Klassendefinition zeigt an, dass ein Knoten aus zwei Komponenten
besteht:
die key – Komponente ist eine ganze Zahl
die next – Komponente ist ein Verweis auf einen (anderen) Knoten.
Veranschaulichung
L:
a1
a2
...
an
head
Prof. Dr. Dietmar Seipel
130
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
Bereitstellen von Speicherplatz für ein Listenelement durch die
Konstruktorfunktion :
Node x = new Node(v);
Die Konstruktorfunktion liefert als Resultat einen Verweis auf einen freien
Speicherplatz für ein Listenelement.
Prof. Dr. Dietmar Seipel
131
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
Implementierung
für lineare Listen:
Kopfzeiger head
Anzahl count der gespeicherten Elemente
Die leere Liste ist gegeben durch den Verweis head = null und
count = 0.
Sie wird durch folgende Konstruktorfunktion erzeugt:
Konstruktorfunktion
List() {
head = null;
count = 0;
}
Prof. Dr. Dietmar Seipel
132
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
Zum Einfügen eines neuen Elements v hinter dem Knoten t einer linearen
Liste verwenden wir die Funktion insert.
t
ai
ai+1
x
v
Zum Entfernen eines Knotens t aus einer linearen Liste verwenden wir die
Funktion remove.
x
Prof. Dr. Dietmar Seipel
ai-1
t
ai
t’
ai+1
133
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
Falls t nicht der Kopf der Liste ist, so bestimmen wir den Vorgängerknoten
x von t und setzen dessen Verweis auf den Nachfolgerknoten t’ von t.
Zum Verketten zweier linearer Listen L1 und L2 gegeben durch head1,
count1 und head2, count2 verwenden wird die Funktion concat.
Um das Entfernen von Listenelementen bei gegebener Position möglichst
einfach ausführen zu können, kann man zu jedem Listenelement nicht nur
einen Verweis next auf das nächstfolgende, sondern auch einen Verweis
prior auf das vorhergehende Listenelement abspeichern.
( doppelt verkette Speicherung)
Prof. Dr. Dietmar Seipel
134
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
Double Node
public class DoubleNode {
int key;
DoubleNode next, prior;
DoubleNode(int k) {
key = k;
next = prior = null;
}
}
next
.. .. ..
prior
Prof. Dr. Dietmar Seipel
135
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
Bei doppelt verketteter Speicherung können das Entfernen und das
Verketten einfacher realisiert werden.
Wir haben die nach dem Entfernen nicht mehr benötigten Knoten nicht zur
neuen – und eventuell anderen – Verwendung explizit freigegeben, sondern
sie nur aus der Liste durch Umlegen von Verweisen entfernt.
Man muss in C diese Knoten explizit freigeben. In JAVA werden Elemente,
auf die keine Verweise mehr existieren vom Garbage – Kollektor
automatisch aus dem Speicher entfernt.
Prof. Dr. Dietmar Seipel
136
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
Node
/** Ein Listen- bzw. Stackelement. */
public class Node {
/** Schluesselwert */
int key;
/** Das naechste Element */
Node next;
/**
* Ein einfachern Konstruktor mit Schluessel.
*/
Node(int k) {
key = k;
next = null;
}
Prof. Dr. Dietmar Seipel
137
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
Node
/**
* Liefert eine Textausgabe des Objektes, siehe
* {@link java.lang.Object#toString}
*/
public String toString() {
return "[" + key + "]";
}
}
Prof. Dr. Dietmar Seipel
138
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
Double Node
/** Ein Listenelement */
public class DoubleNode {
/** Schluesselwert */
int key;
/** Das naechste Element */
DoubleNode next;
/** Das vorhergehende Element */
DoubleNode prior;
Prof. Dr. Dietmar Seipel
139
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
Double Node
/**
* Ein einfacher Konstruktor mit Schluessel.
*/
DoubleNode(int k) {
key = k;
next = prior = null;
}
}
Prof. Dr. Dietmar Seipel
140
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
Lineare Liste
/** Eine einfach verkettete lineare Liste. */
public class List {
/** Das erste Element der Liste */
Node head;
/** Die Anzahl der gespeicherten Elemente */
int count;
/**
* Konstruktor fuer eine leere Liste
*/
List() {
head = null;
count = 0;
}
Prof. Dr. Dietmar Seipel
141
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
Lineare Liste
/**
* Fuegt einen neuen Knoten mit Schluessel v
* nach dem Knoten t in die Liste ein.
*/
void insert(int v, Node t) {
Node x = new Node(v);
count++;
if (t == null) { //Einfuegen am Anfang
x.next = head;
head = x;
} else {
x.next = t.next;
t.next = x;
}
}
Prof. Dr. Dietmar Seipel
142
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
Lineare Liste
/**
* Haengt einen neuen Knoten mit Schluessel v an das
* Ende der Liste an (unter Benutzung von insert).
*/
void add(int v) {
Node last = head;
if (last == null) {
insert(v, null);
} else {
//Letztes Listenelement suchen
while (last.next != null)
last = last.next;
insert(v, last);
}
}
Prof. Dr. Dietmar Seipel
143
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
Lineare Liste
/**
* Loescht den Knoten aus der Liste.
*/
void remove(Node t) {
count--;
if (t == head) {
head = t.next;
} else {
Node x = head;
while (x.next != t)
x = x.next;
x.next = t.next;
}
}
Prof. Dr. Dietmar Seipel
144
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
Lineare Liste
/**
* Haengt die Listen von head1 und head2 aneinander
* und speichert sie in dieser Liste.
*/
void concat (Node head1, int count1,
Node head2, int count2) {
count = count1 + count2;
if (head1 == null) {
head = head2;
} else {
head = head1; Node x = head1;
while (x.next != null) x = x.next;
x.next = head2;
}
}
Prof. Dr. Dietmar Seipel
145
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
Lineare Liste
/** Liefert eine Textausgabe des Objektes */
public String toString() {
String s = getClass().getName() + "[count="
+ count + ",{";
for (Node i = head; i != null; i = i.next) {
s += i.toString() + "->";
}
s += "null}]";
return s;
}
Prof. Dr. Dietmar Seipel
146
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
Lineare Liste
/** Kleines Testprogramm. */
public static void main(String[] args) {
List l = new List();
for (int i = 0; i < args.length; i++) {
l.add(Integer.parseInt(args[i]));
}
System.out.println(l);
}
}
Prof. Dr. Dietmar Seipel
147
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
Doppelt verkettete lineare Liste
/** Eine doppelt verkettete lineare Liste.*/
public class DoubleList {
/** Das erste Element der Liste */
DoubleNode head;
/** Die Anzahl der gespeicherten Elemente */
int count;
/** Konstruktor fuer eine leere Liste */
DoubleList() {
head = null;
count = 0;
}
Prof. Dr. Dietmar Seipel
148
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
Doppelt verkettete lineare Liste
void insert(int v, DoubleNode t) {
DoubleNode x = new DoubleNode(v);
count++;
if (t == null) { //Einfuegen am Anfang
x.next = head;
x.prior = null;
head.prior = x;
head = x;
} else {
x.next = t.next;
x.prior = t;
t.next = x;
x.next.prior = x;
}
}
Prof. Dr. Dietmar Seipel
149
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
Doppelt verkettete lineare Liste
void remove (DoubleNode t) {
count--;
if (t.prior != null)
t.prior.next = t.next;
if (t.next != null)
t.next.prior = t.prior;
if (t == head)
head = t.next;
}
}
Prof. Dr. Dietmar Seipel
150
Praktische Informatik I - Algorithmen und Datenstrukturen
3.2
Wintersemester 2006/07
Schlangen
Eine Schlange (engl.: queue) ist eine lineare Liste, bei der das Einfügen und
Entfernen von Listenelementen auf die beiden extremalen Listenelemente
(d.h. Listenanfang und Listenende) beschränkt ist.
Prof. Dr. Dietmar Seipel
151
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
Bezeichnungen
pushhead(v), pushtail(v):
fügt das Element v am Anfang bzw. am Ende der Schlange ein.
pophead(), poptail():
entfernt das erste bzw. letzte Element der Schlange und gibt seinen
Wert als Resultat zurück;
undefiniert, falls die Schlange leer ist.
v = top():
gibt das erste Element der Schlange als Resultat zurück;
ebenfalls undefiniert, falls die Schlange leer ist.
empty():
testet ob die Schlange leer ist.
init():
erzeugt eine Leere Schlange
Prof. Dr. Dietmar Seipel
152
Praktische Informatik I - Algorithmen und Datenstrukturen
3.3
Wintersemester 2006/07
Stapel
Ein Stapel (oder Keller; engl.: stack) ist eine lineare Liste, bei der das
Einfügen und Entfernen eines Elements auf den Listenkopf beschränkt ist.
Realisierung mit verketteten Listen
top
a1
a2
...
an
Prof. Dr. Dietmar Seipel
head
null
top
153
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
Implementierung
Stack
/**
* Stack-Klasse
*/
public class Stack {
/** Oberster Knoten des Stacks */
Node top;
/**
* Konstruktor. Initialisiert den Stack (leer).
*/
Stack() {
top = null;
}
Prof. Dr. Dietmar Seipel
154
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
Stack
/**
* Legt ein neues Element auf den Stack
*/
void push(int v) {
Node t = new Node(v);
t.next = top;
top = t;
}
/**
* Liefert das oberste Element des Stacks
*/
int top() {
return top.key;
}
Prof. Dr. Dietmar Seipel
155
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
Stack
/**
* Liefert das oberste Element des Stacks und
* loescht dieses vom Stack
*/
int pop() {
int v = top.key;
top = top.next;
return v;
}
/**
* Liefert true, falls der Stack leer ist.
*/
boolean empty() {
return (top == null);
}
Prof. Dr. Dietmar Seipel
156
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
Stack
/**
* Liefert eine Textausgabe des Objektes, siehe
* {@link java.lang.Object#toString}
*/
public String toString() {
String s = getClass().getName() + "[";
for (Node i = top; i != null; i = i.next) {
s += i.toString() + "<-";
}
s += "null]";
return s;
}
Prof. Dr. Dietmar Seipel
157
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
Stack
/**
* Kleines Testprogramm.
*/
public static void main (String[] args) {
Stack s = new Stack();
for (int i = 0; i < args.length; i++) {
s.push(Integer.parseInt(args[i]));
}
System.out.println(s);
}
}
Prof. Dr. Dietmar Seipel
158
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
Anwendung
Speicherung der Rücksprungadressen bei geschachtelten
Unterprogrammaufrufen.
Hauptprogramm
Unterprogramm 1
Unterprogramm 2
(2) push (A2)
(1) push (A1)
A2
(3) A2 = pop
Unterprogramm 3
A1
(4) push (A3)
A3
(6) A1 = pop
Prof. Dr. Dietmar Seipel
(5) A3 = pop
159
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
Beim Sprung zum Unterprogramm wird die aktuelle Adresse A auf den
Stapel gelegt ( push(A) ).
Beim Rücksprung wird die ehemals aktuelle Adresse des aufrufenden
Programms vom Stapel geholt ( A = pop() ).
Wir erhalten folgende Folge von Stapelzuständen:
A2
(0)
Prof. Dr. Dietmar Seipel
A3
A1
A1
A1
A1
A1
(1)
(2)
(3)
(4)
(5)
(6)
160
Praktische Informatik I - Algorithmen und Datenstrukturen
3.4
Wintersemester 2006/07
Geordnete binäre Wurzelbäume
3.4.1 Der Wurzelbaum
Beispiel
Knoten: 4
Kante: (4,5)
(5 ist Nachfolger von 4)
4
5
7
3
8
6
2
11
10
1
9
Prof. Dr. Dietmar Seipel
161
Praktische Informatik I - Algorithmen und Datenstrukturen
besteht aus
Ein Wurzelbaum
Wintersemester 2006/07
einer Menge
von Kanten,
von Knoten, und
einer Menge
,
so dass es einen eindeutigen Knoten, genannt Wurzel gibt, von dem alle
Knoten über jeweils eindeutige Wege erreichbar sind.
ist dabei eine Folge
von Knoten,
Ein Weg von nach
so dass für je zwei aufeinanderfolgende Knoten und
eine Kante
existiert.
kann als Weg von nach aufgefasst werden!)
(Merke:
Prof. Dr. Dietmar Seipel
162
Praktische Informatik I - Algorithmen und Datenstrukturen
Für einen Knoten
Wintersemester 2006/07
bezeichnet
die Menge der Vorgänger bzw. der Nachfolger von
in .
Offensichtlich gilt in einem Wurzelbaum:
nicht die Wurzel ist,
die Wurzel ist.
falls
falls
Ein Wurzelbaum heißt binär , falls jeder Knoten höchstens zwei Nachfolger
hat:
Prof. Dr. Dietmar Seipel
163
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
Ein binärer Wurzelbaum heißt geordnet , falls für jeden Knoten
injektive Abbildung
eine
auf seiner Nachfolgermenge gegeben ist.
mit
heißt linker Sohn,
mit
heißt rechter Sohn
von v.
v
v’
Prof. Dr. Dietmar Seipel
v’’
164
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
3.4.2 Baumdarstellung mittels einer Zeigerstuktur
Ein Baum kann also durch die Angabe eines Zeigers root auf den
Wurzelknoten angegeben werden.
Die Zeiger lSon bzw. rSon werden in einem Knoten auf null gesetzt,
wenn die entsprechenden Söhne nicht existieren.
Für die Klasse BinTree wird ein Stack benötigt, der BinTreeNodes oder
allgemein Objects speichern kann (im Gegensatz zu dem oben erstellten
Stack für ints.)
Falls eine Stack-Implementierung mit Objects gewählt wird, muss in der
Methode wlr_durchlauf die Zeile t = s.pop() durch
t = (BinTreeNode) s.pop() ersetzt werden.
Prof. Dr. Dietmar Seipel
165
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
Implementierung
BinTreeNode
/**
* Knoten eines binaeren Baumes
*/
public class BinTreeNode {
/** Schluesselwert */
int key;
/** Linker Sohnknoten */
BinTreeNode lson;
/** Rechter Sohnknoten */
BinTreeNode rson;
Prof. Dr. Dietmar Seipel
166
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
BinTreeNode
/**
* Konstruktor.
*/
BinTreeNode(int v) {
key = v;
lson = rson = null;
}
Prof. Dr. Dietmar Seipel
167
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
BinTreeNode
/**
* Gibt die Anzahl der Soehne des Knotens
* zurueck (0, 1 oder 2)
*/
int countSons() {
if (lson == null)
return (rson == null)?0:1;
else
return (rson == null)?1:2;
}
Prof. Dr. Dietmar Seipel
168
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
BinTreeNode
/**
* Liefert true, falls der Knoten ein
* Blatt ist, d.h. keine Kinder hat
*/
boolean isLeaf() {
return (lson == null) && (rson == null);
}
Prof. Dr. Dietmar Seipel
169
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
BinTreeNode
/**
* Liefert true, falls der Knoten keinen
* Sohn auf der Seite hat, in der der Schluessel
* s zu suchen waere
*/
boolean isLeaf(int s) {
return ( (key > s) && (lson == null) )
|| ( (key < s) && (rson == null) );
}
Prof. Dr. Dietmar Seipel
170
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
BinTreeNode
/**
* Liefert eine Textausgabe des Objektes, siehe
* {@link java.lang.Object#toString}
*/
public String toString() {
return "[" + key + "]";
}
}
Prof. Dr. Dietmar Seipel
171
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
BinTree
/**
* Binaerer Baum
*/
public class BinTree {
/**
* Baumdurchlauf in LWR-Ordnung
*/
void lwr_durchlauf(BinTreeNode t) {
if (t != null) {
lwr_durchlauf(t.lson);
System.out.println(t);
lwr_durchlauf(t.rson);
}
}
Prof. Dr. Dietmar Seipel
172
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
BinTree
/**
* Generische Methode zum Baumdurchlauf entsprechend
* String id (von der Form "LWR", "WLR" oder "LRW")
*/
void durchlauf(String id, BinTreeNode t) {
if (t != null) {
for (int i = 0; i < id.length(); i++) {
switch (id.charAt(i)) {
case ’L’: durchlauf(id, t.lson);break;
case ’R’: durchlauf(id, t.rson);break;
case ’W’: System.out.println(t);break;
}
}
}
}
Prof. Dr. Dietmar Seipel
173
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
BinTree
/**
* Nicht-rekursiver Baumdurchlauf in WLR-Ordnung
*/
void wlr_durchlauf(BinTreeNode t) {
Stack s = new Stack();
while (t != null) {
System.out.println(t);
if (t.rson != null) s.push(t.rson);
Prof. Dr. Dietmar Seipel
174
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
BinTree
if (t.lson != null) {
t = t.lson;
} else {
if (!s.empty())
t = s.pop();
else
t = null;
}
}
}
}
Prof. Dr. Dietmar Seipel
175
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
3.4.3 Ordnungen und Durchlaufprizipien
1. Inordnungen LWR, RWL
Beim Durchlaufen der Knoten in LWR- bzw. RWL-Ordnung wird
zunächst
der linke bzw. rechte Teilbaum, dann
die Wurzel, und dann
der rechte, bzw. linke Teilbaum
durchlaufen.
Im Beispiel erhalten wir:
Prof. Dr. Dietmar Seipel
LWR
RWL
176
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
Die Ordnungen LWR und RWL sind stets invers zueinander, d.h. ist
LWR
, so ist RWL
4
5
7
3
8
6
2
11
10
1
9
Prof. Dr. Dietmar Seipel
177
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
2. Randordnungen
(a) Präordnungen WLR, WRL
Hier wird die Wurzel vor den beiden Teilbäumen durchlaufen.
im Beispiel:
WLR
WRL
4
5
7
3
8
6
2
11
10
1
9
Prof. Dr. Dietmar Seipel
178
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
(b) Postordnungen LRW, RLW
Hier werden die beiden Teilbäume vor der Wurzel durchlaufen.
im Beispiel:
LRW
RLW
Offenbar sind WLR und RLW bzw. WRL und LRW jeweils zueinander
invers .
Prof. Dr. Dietmar Seipel
179
Praktische Informatik I - Algorithmen und Datenstrukturen
Lemma
Wintersemester 2006/07
(Durchlaufordnungen)
(i) Ein geordneter binärer Wurzelbaum ist eindeutig bestimmt durch die
Angabe einer Inordnung zusammen mit einer Randordnung.
z.B. durch LWR und WLR oder durch LWR und LRW.
(ii) Die Angabe zweier Inordnungen bzw. zweier Randordnungen reicht für
die eindeutige Charakterisierung eines geordneten Wurzelbaumes i.a.
nicht aus.
z.B. reichen LWR und RWL nicht aus, und ebenso reichen WLR und
LRW nicht aus.
Prof. Dr. Dietmar Seipel
180
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
Beweis
Wegen der Äquivalenz von LWR und RWL bzw. von WLR und RLW
reicht es aus, den Fall zu betrachten, dass die Inordnung LWR ist und
die Randordnung WLR.
Wir zeigen die Behauptung durch vollständige Induktion über die
Eckenzahl des Baums.
: trivial
Induktionsanfang,
:
Induktionsschluss,
bereits
Sei die Behauptung für alle – eckigen Bäume mit
gezeigt.
– eckigen Baum . Die Wurzel von
Wir betrachten nun einen
ist offenbar das erste Element in der WLR – Ordnung.
Prof. Dr. Dietmar Seipel
181
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
Für die beiden Teilbäume der Wurzel – welche eventuell auch leer sein
können – kann nun wie folgt die LWR – Ordnung und die WLR –
Ordnung aus den Ordnungen des gesamten Baumes eindeutig bestimmt
werden:
, so dass
a) Die LWR – Folge kann mittels zerlegt werden in
bzw. die LWR – Folge für den linken bzw. den rechten Teilbaum
von ist.
b) Da man jetzt weiß, welche Elemente im linken bzw. rechten Teilbaum
von liegen, kann man nun auch die WLR – Folge zerlegen in
, so dass bzw. die WLR – Folge für den linken bzw.
rechten Teilbaum von ist.
Dann können wir die Induktionsannahme auf die beiden Teilbäume von
bzw. deren Folgen und bzw. und anwenden (denn die
beiden Teilbäume haben jeweils maximal Knoten).
Also kann der gesamte Baum eindeutig rekonstruiert werden.
Prof. Dr. Dietmar Seipel
182
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
Beispiel zu (i)
LWR
WLR
die Wurzel des linken Teilbaumes.
Also ist
– LWR:
– WLR:
die Wurzel.
Also ist
1
2
5
Prof. Dr. Dietmar Seipel
3
4
183
Praktische Informatik I - Algorithmen und Datenstrukturen
Wintersemester 2006/07
Folgende Bäume haben sowohl die gleiche WLR – als auch die gleiche
LRW – Ordnung:
T1:
T2:
1
2
3
1
2
5
5
WLR
LRW
Prof. Dr. Dietmar Seipel
3
184
Herunterladen