4.4 Implementierung von Bäumen 4.4.1 Implementierung

Werbung
4.4 Implementierung von Bäumen
4.4.1 Implementierung vollständiger Bäume mit
Feldern
1 3
2
4
5
8
8 13
9
7
11
9
17
3
10 7
12
6
18
10
Reguläre Struktur: Nachfolger des Knoten i sind
die Knoten 2*i und 2*i+1.
hs / fub – alp3-14-TreeImp-5 1
18
a[1] = root
a[i] = Node n =>
( leftChild (Node n) = Empty
or a[2*i] = leftChild (Node n))
and
( rightChild (Node n) = Empty
or a[2*i] = rightChild (Node n))
4
8 13
8
2
11
7
9
1
3
17 5
9
6 12
9
3
10
7
Feldimplementierung
3
0
1
7
9
8
2
3
4
17 12
5
6
10
7
13
8
11 18
9
10...
hs / fub – alp3-14-TreeImp-5 2
1
Feldrepräsentation
public class BTArray {
// model: data Ord t => BTree t = E | N(BTree t) t
//
(BTree t)
// inv : true
Object [] a;
// the array implementing the tree
private int size;
//number of nodes
private int lgth;
//a.length
private int current;
// the current node
private final
int
ROOT = 1;
// the root
hs / fub – alp3-14-TreeImp-5 3
Abstraktionsfunktion und Invariante
Abstraktionsfunktion:
welchem abstrakten Baum entspricht eine
Baumrepräsentation durch ein Feld?
- Struktur
- Werte : Object -> t
// abstr: abstr :: (Object arrayT) -> BTree t
// abstr a = if (count==0) = E
// abstr a = abstr' 1
//
where abstr'' :: Object -> t
//
abstr' :: {1..lgth-1} -> BTree t
//
abstr' i = if (a[i] == null ) E
//
abstr' i
//
= N (abstr' (2*i) (abstr'' a[i])
//
(abstr (2*i+1)
hs / fub – alp3-14-TreeImp-5 4
2
Invariante
Repräsentationsinvariante: welche Feldwerte sind
erlaubt?
- erstes Feldelement nicht genutzt
- Größe des Baums immer kleiner Feldlänge
- Baumeigenschaft "zusammenhängender Graph"
// inv: a[0] == null
//
& size < lgth
//
& for all 1 <= i <= lgth
//
i !=1 & a[i] != null
=> a[i div 2] != null
hs / fub – alp3-14-TreeImp-5 5
Operationen
BTArray(int s ) {
// pre: lgth = power of 2
size = 0;
lgth = s-1;
a = new Object[lgth];
current = 1;
}
public BinTree left()throws.....{
// pre: a[current] != null & 2*current < lgth
// effects: current = current * 2
if (2*current > size)
throw ........
else current = 2*current;
return this;
}
hs / fub – alp3-14-TreeImp-5 6
3
Operationen
public BinTree parent(){
// pre: current != 1
// effects: current = current div 2
current = current/2;
return this;
}
public void setVal(Object o){
// pre: current < lgth
a[current] = o;
}
public Object root(){
// pre: current != 0
return a[current];
hs / fub – alp3-14-TreeImp-5 7
Traversierung
public void preorderTraverse(Func f) {
preOrder(ROOT, f);
}
// uses array representation
private void preOrder(int i, Func f) {
if (i > a.length) return;
if (a[i] == null) return;
f.call(a[i]);
preOrder (2*i,f);
preOrder (2*i+1,f);
}
Iterator?
Was heißt "next()" in einem Baum?
hs / fub – alp3-14-TreeImp-5 8
4
4.4.2 Implementierung durch verketteten Baum
- direkte Implementierung:
BinTree1 {
- val
- left
- right
BinTree1 {
- val
- left
- right
BinTree1 r
BinTree1 {
- val
- left
- right
hs / fub – alp3-14-TreeImp-5 9
Binärbaum: Erste Implementierung
class BinTree1 implements BinTree{
Object val;
BinTree1 left, right;
// abstr(null) = E
// abstr (val, left, right) =
//
N((abstr left) val (abstr right))
public BinTree1 (BinTree1 l, Object o, BinTree1 r){
val
= o;
left
= l;
right
= r;
}
public Object val() {
return val;
}
hs / fub – alp3-14-TreeImp-5 10
5
Binärbaum: Erste Implementierung
public BinTree1 left() {
return left;
}
...
public boolean isEmpty(BinTree1 b){
return (b==null);
}
public boolean isEmpty(){} //cannot be applied to this
public boolean isLeaf(){
return (isEmpty(left) && isEmpty(right);
}
public void postorderPrint(){
if (!isLeaf()){
left.postorder();
right.postorder();
// process value;
System.out.print(val); }
}}
hs / fub – alp3-14-TreeImp-5 11
4.4.3 Implementierung mit Knoten-Objekten
BinaryTree
root ---->
lft val
BinaryTree
lft val
r
TreeNode
lft val
r
r
r
lft val
r
hs / fub – alp3-14-TreeImp-5 12
6
Knotenobjekte
class TreeNode {
Object val ;
TreeNode left = null, right = null;
public TreeNode (Object e) { val = e; }
public TreeNode left () { return left; }
public TreeNode right () { return right; }
public Object
val() { return val; }
public boolean isLeaf ()
{ return left == null && right == null;
public void setLeft (TreeNode n) { left = n; }
public void setRight (TreeNode n) { right = n; }
}
}
hs / fub – alp3-14-TreeImp-5 13
Binärbaum
class BinaryTree {
protected TreeNode root = null;
private int size = 0;
public BinaryTree() {}
public BinaryTree (Object val){
root=new TreeNode(val);
}
public TreeNode left() {
current = root.left();
}
Implementiert nicht
public Object val() {
BinTree – Interface.
return root.val();
} ....
hs / fub – alp3-14-TreeImp-5 14
7
InorderInorder-Iterator
Iterator-Interface:
next(), hasNext()
Problem: "nächster Knoten" ist nicht notwendig
"lokal":
a
c
b
d
x
y
e
....
Wenn a aktuell:
next() -> y
....
Wenn x aktuell:
next -> z
z
hs / fub – alp3-14-TreeImp-5 15
InorderInorder-Iterator für Binärbaum (1)
protected class BTreeIteratorInOrd implements
java.util.Iterator {
private Stack stack;
public BTreeIteratorInOrd (BinaryTree tree) {
stack = new StackArray();
TreeNode node = tree.root ();
while (node != null) {
stack.push (node);
node = node.left ();
}
}
public boolean hasNext () {
return !stack.isEmpty ();
}
hs / fub – alp3-14-TreeImp-5 16
8
InorderInorder-Iterator für Binärbaum (1)
public Object next () {
TreeNode node = (TreeNode) stack.pop ();
Object o = node.val ();
if (node.right () != null) {
node = node.right ();
while (node != null) {
stack.push (node);
node = node.left ();
}
}
return o;
}
public void remove () {
throw new UnsupportedOperationException ();
}
}
hs / fub – alp3-14-TreeImp-5 17
Ordnung auf Bäumen
Kann
man Bäume ordnen?
ja, wenn die Knotenwerte geordnet sind.
Vergleiche lexikographische Ordnung:
aabcdef < aabcedf
abcd
< abcde
Ordnungsrelation auf Binärbäumen
S, T Binärbäume.
S < T ! T.isEmpty() and
! S.isEmpty() and
S.val = T.val and
S.left =T.left and
(S.isEmpty
or
( S.val < T.val or
(S.left < T.left or
S.right < T.right)))
Was heißt
"=" ??
hs / fub – alp3-14-TreeImp-5 18
9
4.4.4 Binärbaum mit Rückverweisen
... vereinfachen
manche
Algorithmen...?
Abb.: aus Tamassia:
DS & Alg in Java
hs / fub – alp3-14-TreeImp-5 19
4.4.4 Binärbaum mit Rückverweisen
class BinTree2 {
Object val;
BinTree2 left, right, prev;
public BinTree2 (BinTree2 l, Object o, BinTree2 r){
val = o;
left = l;
Verweis auf Elternknoten,
right = r;
manchmal nützlich, ...
prev = null;
aber
}
(Inorder-) Traversierung??
....
public void setLeft(BinTree2 b){
left = b;
b.prev = this;
}...}
hs / fub – alp3-14-TreeImp-5 20
10
4.4.5 Gefädelter Binärbaum (Threaded
(Threaded Tree)
Tree)
a
b
c
d
e
h
f
g
i
Hier: Inorder-Faden
Beachte: keine zusätzlichen Vorwärtsverweise,
Rückverweise nur von "tieferer auf höhere Ebene"
hs / fub – alp3-14-TreeImp-5 21
4.4.6 nn-ärer Baum
class KTree {
int MAXSUCC = 5;
Object val;
KTree[] succ=null;
Direkte Implementierung
der rekursiven Definition
public KTree ( Object o){
val = o;
}
public boolean isLeaf()
{return succ==null;}
public KTree nth(int n) {
// pre: n >= 0 && succ != null
if (n < MAXSUCC) return succ[n];
else throw IllegalArityException;
} ....
}
hs / fub – alp3-14-TreeImp-5 22
11
4.4.7 Mehrwegbäume als binäre Bäume
Variante
A: Liste von Nachfolgern
class MTree1
{
Object val;
LinkedList successors;
....
Variante
B: Zurückführen auf Binärbaum
Verweise nicht auf Kinder sondern auf
- erstes Kind
- Geschwister
hs / fub – alp3-14-TreeImp-5 23
Mehrwegbäume als binäre Bäume
a
b
e
j
k
g
f
l
d
c
h
i
m
hs / fub – alp3-14-TreeImp-5 24
12
Mehrwegbäume als binäre Bäume
Datenstruktur identisch, andere Operationen (und
Algorithmen)
class MTree
{
Object val;
MTree first, nextSibling;
public MTree (Object o) {val=o;}
public Object findNthChild(int n){
....
...}
hs / fub – alp3-14-TreeImp-5 25
13
Herunterladen