v15 alp1 abstrakte datentypen 2013 - inf.fu-berlin.de · abstrakt datentypen alp i: margarita...
TRANSCRIPT
ALP IAlgebraische Datentypen
undAbstrakte Datentypen
Prof. Dr. Margarita Esponda
SS 2013
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Abstrakt Datentypen
ALP I: Margarita Esponda, 12. Vorlesung, 26.11.2012
Algebraischen Datentypen für BäumeBeispiel:
data SBTree = L | N SBTree SBTree
L
N
N N
L N LL
L
Abstrakt Datentypen
ALP I: Margarita Esponda, 12. Vorlesung, 26.11.2012
Einfache binäre Bäume
data SBTree = L | N SBTree SBTree deriving Show
type Depth = Integer
genSBTree :: Depth -> SBTree
genSBTree 0 = L
genSBTree (n+1) = N (genSBTree n) (genSBTree n)
genSBTree 3 ⇒
Ein balancierter Baum
mit der eingegebenen
Tiefe wird erstellt.
L LL L L L L L
N
N N
N N N N
Abstrakt Datentypen
ALP I: Margarita Esponda, 12. Vorlesung, 26.11.2012
nodes :: SBTree -> Integernodes L = 1nodes (N leftT rightT) = 1 + nodes leftT + nodes rightT
nodes (genSBTree 3) ⇒ 15
Berechnung aller Knoten des Baumes
L LL L L L L L
N
N N
N N N N
Abstrakt Datentypen
ALP I: Margarita Esponda, 12. Vorlesung, 26.11.2012
depth :: SBTree -> Integerdepth L = 0depth (N lt rt) = (max (depth lt) (depth rt)) + 1
Tiefe des Baumes
L L
L L L
N
N N
N
depth N (N (N L L) L) (N L L) ⇒ 3
Abstrakt Datentypen
ALP I: Margarita Esponda, 12. Vorlesung, 26.11.2012
joinTrees :: SBTree -> SBTree -> SBTreejoinTrees leftTree rightTree = N leftTree rightTree
L L
N
L L
L
N
N
joinTrees leftT rightT ⇒ N leftT rightT
N
leftT rightT
L L
L
N
NL L
NleftT rightT
Abstrakt Datentypen
ALP I: Margarita Esponda, 12. Vorlesung, 26.11.2012
balanced :: SBTree -> Boolbalanced L = Truebalanced (N lt rt) = (balanced lt) && (balanced rt) && depth lt == depth rt
L L
L
N
N
L L
N
N
L L
N N
L L
N
N
L L
N
L
balanciert balanciert nicht balanciert
Abstrakt Datentypen
ALP I: Margarita Esponda, 12. Vorlesung, 26.11.2012
Beispiel:
data Tree = Leaf Int | Node Int Tree Tree | Nil
53
27 69
13 34 63 95
46
Algebraischer Datentyp für Binäre Suchbäume
Die gespeicherte Information
ist sortiert.
Operationen für Binäre Suchbäume
data BSTree a = Nil | Node a (BSTree a) (BSTree a) deriving ( Show, Eq )
-- findet das kleinste Element
smallest:: (Ord a) => BSTree a -> asmallest (Node x Nil _) = x
smallest (Node x leftTree _) = smallest leftTree
Prof. Dr. Margarita Esponda
53
27 69
13 34 63 95
46
Algebraische Datentypen für Binäre Suchbäume
Algebraischer Datentyp für Binäre Suchbäume
data BSTree a = Nil | Node a (BSTree a) (BSTree a)
deriving ( Show, Eq )
-- findet das größte Element
biggest:: (Ord a) => BSTree a -> a
biggest(Node x _ Nil) = x
biggest(Node x _ rightTree) = biggest rightTree
-- spiegelt einen Baum
mirror:: (Ord a) => BSTree a -> BSTree a
mirror Nil = Nil
mirror (Node x xl xr) = Node x (mirror xr) (mirror xl)
Prof. Dr. Margarita Esponda
Algebraische Datentypen für Binäre Suchbäume
ALP I: Margarita Esponda, 12. Vorlesung, 26.11.2012 23
Traversierung binärer Bäume
Preorder: Wurzel – linker Unterbaum – rechter Unterbaum
Inorder: linker Unterbaum - Wurzel – rechter Unterbaum
Postorder: linker Unterbaum – rechter Unterbaum - Wurzel
Levelorder: von oben nach unten in jeder Ebene von links
nach rechts
Baumtraversierung bedeutet, alle Knoten des Baumes in einer bestimmten Reihenfolge zu besuchen.
Algebraische Datentypen für Binäre Suchbäume
ALP I: Margarita Esponda, 12. Vorlesung, 26.11.2012
Traversierung binärer BäumeInorder Linker Unterbaum - Wurzel - Rechter Unterbaum
F
D I
B E G J
HA C
F
D I
B E G J
HA C
JHG IB D FCA E
Traversierung von Binärbäumen
-- verwandelt einen sortierten Baum in eine sortierte Liste
inOrder :: (Ord a) => BSTree a -> [a]
inOrder Nil = []
inOrder (Node x ltree rtree) = inOrder ltree ++ x : inOrder rtree
Prof. Dr. Margarita Esponda
Algebraische Datentypen für Binäre Suchbäume
-- verwandelt einen Baum in eine ListepreOrder :: (Ord a) => BSTree a -> [a]preOrder Nil = []preOrder (Node x ltree rtree) = x : preOrder ltree ++ preOrder rtree
Prof. Dr. Margarita Esponda
F
D I
B E G J
HA C
F
D I
B E G J
HA C
JGI HD A EBF C
Algebraische Datentypen
ALP I: Margarita Esponda, 12. Vorlesung, 26.11.2012
Binärbäume
Binärbäume
Baumstrukturen
AVL-Bäume
Red-Black-Bäume
B-Bäume
usw.
ausgeglichene Bäume
einfachste
Beispiele:
Die wichtigste Voraussetzung für die effiziente Verwaltung von
Datenmengen mit Hilfe von Bäumen ist, dass die Bäume balanciert
sind.
Suchen
search :: (Ord a) => a -> BSTree a -> Bool
search _ Nil = False
search k (Node x ltree rtree) | k==x = True
| k<x = search k ltree
| otherwise = search k rtree
3 11
7 19
3 9 15
161 5
Nil Nil Nil Nil Nil Nil
Nil 3
11
7 19
3 9 15
161 5
Nil Nil Nil Nil Nil Nil
Nil
Prof. Dr. Margarita Esponda
Algebraische Datentypen
Einfügen11
7 19
3 9 15 23
161 5
Nil Nil Nil NilNil Nil
NilNilNil Nil
6
11
7 19
3 9 15 23
161 5
Nil NilNil Nil
NilNilNil Nil
Nil 6
Nil Nil
Prof. Dr. Margarita Esponda
Algebraische Datentypen
Einfügen
insert :: (Ord a) => a -> BSTree a -> BSTree a
insert a Nil = Node a Nil Nil
insert a (Node x ltree rtree)
| a<x = Node x (insert a ltree) rtree
| otherwise = Node x ltree (insert a rtree)
Prof. Dr. Margarita Esponda
Algebraische Datentypen
-- findet das kleinste Element
smallest (Node x Nil _) = x
smallest (Node x leftTree _) = smallest leftTree
-- findet das größte Element
biggest(Node x _ Nil) = x
biggest(Node x _ rightTree) = biggest rightTree
Prof. Dr. Margarita Esponda
Minimum und Maximum
53
27 69
13 34 63 95
17 46
Der ersteKnoten, derkeine linkenKinder mehrhat, beinhaltetdas kleinsteElement.
MaximumMinimum
Algebraische Datentypen
Löschen
list2Tree [] = Nil
list2Tree (x:xs) = insert x (list2Tree xs)
remove _ [] = []
remove y (x:xs) | y==x = xs
| otherwise = x:(remove y xs)
delete a Nil = Nil
delete a tree = list2Tree(remove a (preOrder tree))
mit "Brute force"
Prof. Dr. Margarita Esponda
Algebraische Datentypen
Nachfolger
53
69
13 34 63 95
17 468
39
30
Minimum
1. Fall
Es gibt einen rechten Unterbaum.
Prof. Dr. Margarita Esponda
Algebraische Datentypen
Nachfolger53
69
13 34 63 95
17 468
39
30
2. Fall
Maximum
Es gibt keinenrechten Unterbaum.
Wie können wir nach oben laufen?
Prof. Dr. Margarita Esponda
Algebraische Datentypen
Delete-Operation ( Löschen )
1. Fall
Löschen eines Knotens ohne Kinder
2. Fall
Löschen eines Knotens mit nur einem Kind
53
27 69
13 34 63 95
17 46
Nil
53
27 69
13 34 63 95
46
Prof. Dr. Margarita Esponda
Algebraische Datentypen
LöschenLöschen eines Knotens mit zwei Kindern3. Fall
53
27 69
13 34 63 95
17 468
32
30
53
69
13 34 63 95
17 468 32
30
Der Nachfolger von 27 ist das Minimum des rechten Unterbaumes.
Der Knoten, den man löschen möchte, wird durch seinen Nachfolger ersetzt.
Das Minimum ist entweder ein Blatt oder hat maximal ein rechtes Kind.
Prof. Dr. Margarita Esponda
Algebraische Datentypen
LöschenLöschen eines Knotens mit zwei Kindern
53
27 69
13 34 63 95
17 468
32
30
Wir brauchen eine join-Funktion, die aus zwei Kinder-Bäumen einen baut.
join
Prof. Dr. Margarita Esponda
69
13 34 63
53
95
17 468
32
30
Algebraische Datentypen
Löschen
delete :: (Ord a) => a-> BSTree a-> BSTree a
delete x Nil = Nil
delete x (Node y ltree rtree)
| x < y = Node y (delete x ltree) rtree
| x == y = join ltree rtree
| x > y = Node y ltree (delete x rtree)
……
etwas besser
Prof. Dr. Margarita Esponda
Algebraische Datentypen
Join-Funktion
join :: (Ord a) => BSTree a-> BSTree a-> BSTree a
join xtree Nil = xtree
join xtree ytree = Node e xtree ntree
where
(e, ntree) = splitMin ytree
-- splitMin :: BSTree a -> (a, BSTree a)
splitMin (Node x Nil tree) = (x, tree)
splitMin (Node x ltree rtree) = (f, Node x ntree rtree)
where
(f, ntree) = splitMin ltree
Prof. Dr. Margarita Esponda
Algebraische Datentypen
Probleme mit einfachen binären Suchbäumen
balancierter Binärbaumnicht
balancierter Binärbaum
53
27 69
13 34 63 95
17 46 13930
53
83
71
59 95
62
77
60
65
30
Prof. Dr. Margarita Esponda
Algebraische Datentypen
Algebraische Datentypen
-- für arithmetische Ausdrücke
data Expr = Lit Int | Add Expr Expr | Sub Expr Expr | Mult Expr Expr
eval :: Expr -> Int
eval (Lit n) = n
eval (Add x y) = eval x + eval y
eval (Sub x y) = eval x - eval y
eval (Mult x y) = eval x * eval y
eval (Mult (Add (Lit 3) (Lit 4)) (Lit 3)) => 21
Prof. Dr. Margarita Esponda
Algebraische Datentypen
Haskell Typsystem
Monomorphe Funktionen Der Datentyp wird genau durch die Signatur bestimmt
Beispiel:
asciiCode :: Char -> Int
Polymorphe Funktionen Typvariablen in der Signatur lassen beliebige Datentypen zu
Beispiel:
length :: [a] -> [a]
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Einschränkung von Typen
Mit Hilfe von vordefinierten Typ-Klassen können polymorphe
Funktionen mit Einschränkung definiert werden
Beispiel: equalList :: Eq a => [a]->[a]->Bool
nur für Datentypen mit Gleichheitsoperator
add2List:: Num a => [a] -> a -> [a]
add2List xs y = map (+y) xs
nur numerische Typen mit definierten
arithmetischen Operationen
Verwendung eines Kontextes
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Einige vordefinierte Typ-Klassen
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Show, Readanzeigbar oder lesbar
(a → String), (String → a) show, read
Eq vergleichbar (==), (/=)
Ord sortierbar compare, (<), (>), (<=), (>=), min, max, ..
Enum aufzählbar succ, pred, [..]
Num allgemeine Zahlen (+), (-), (*), negate, abs
Integral ganzzahlig mod, div, quot, rem
Fractional Kehrwert-Funktion (/), recip,...
Klassenname Eigenschaften Funktionen
Typ-Anpassung
Explizites Type-Casting muss stattfinden
fromIntegral (mod 3 2) + 1.5
In Haskell ist Typ-Anpassung für numerische Werte wie in
anderen Programmiersprachen nicht erlaubt.
Beispiel: mod 3 2 + 1.5
Fehler:<interactive>:1:10: Ambiguous type variable `t' in the constraints: `Fractional t' arising from the literal `1.5' at <interactive>:1:10-12 `Integral t' arising from a use of `mod' at <interactive>:1:0-6 Probable fix: add a type signature that fixes these type variable(s)
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Typ-KlassenTypen werden durch die Operationen, die auf ihren Werten definiert werden sollen, beschrieben.
Class Num a where
(+) :: a -> a -> a
(*) :: a -> a -> a
(-) :: a -> a -> a
. . .
Typklassen sind abstrakte
Schnittstellen, weil keine
Implementierung vorgegeben
wird.
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Instanzen von Typ-Klassen
instance Num Int
where
x+y = primAdd x y
neg x = primNegateInt x
. . .
Mit einer Instanz-Deklaration definieren wir, welche Typen zu
welchen Typ-Klassen gehören.
Vordefinierte primitive Funktionen
instance Eq Char where
x == y = ord x == ord y
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Instanzen von Typ-Klassen
Der Instanz-Typ einer Klasse muss die vorgeschriebenen Operationen einer Typ-Klasse implementieren.
Implementierung: instance (Eq a) => Eq [a] where
(==) [] [] = True
(==) [] (x:xs) = False
(==) (x:ys) [] = False
(==) (x:xs) (y:ys) = x == y && xs == ys
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Instanzen von Typ-Klassen
data Menge a = Menge [a]
instance (Eq a) => Eq (Menge a) where
Menge xs == Menge ys = subset xs ys && subset ys xs
subset :: Eq a => a -> a -> Bool
subset xs ys = all (’elem’ ys) xs
instance (Ord a) => Ord (Menge a) where
Menge xs <= Menge ys = subset xs ys
...
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Subklassen
class (Eq a, Show a) => Num a where
(+), (-), (*) :: a -> a -> a
negate :: a -> a
abs, signum :: a -> a
fromInteger :: Integer -> a
-- Minimal complete definition:
-- All, except negate or (-)
x - y = x + negate y -- Default-Definitionen
negate x = 0 - x
Klassen dürfen andere Klassen umfassen
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Mehrere Oberklassenclass Enum a where
fromEnum :: a -> Int
toEnum :: Int -> a
. . .
class Num a where
(+) :: a -> a -> a
neg :: a -> a
. . .
class (Enum a, Num a) => Integral a where
quot, rem, div, mod :: a -> a -> a
quotRem, divMod :: a -> a -> (a, a)
even, odd :: a -> Bool
toInteger :: a -> Integer
toInt :: a -> Int
Integral erbt die Operationen von Enum und Num und fügt noch weitere Operationen hinzu. Ausprägungen von Integral müssen folglich auch Ausprägungen von Enum und Num sein.
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Klassenhierarchie
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Eq Show
FloatingIntegral
FractionalRealEnum
NumOrd
Algebraische Datentypen
ALP I: Margarita Esponda, 12. Vorlesung, 26.11.2012 53
Standard
Klassenhierarchie
Prelude
Abstrakte Datentypen
Konkrete Datentypen• konkrete Darstellung der Information
innerhalb einer Sprache
• Listen, Bäume usw.
DatentypenAbstrakte Datentypen• definiert durch die Operationen
unabhängig von einer konkreten
Darstellung des Datentyps.
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Abstrakte Datentypen
-sind Datentypen, die durch die auf ihren Werten
erlaubten Operationen definiert sind und dessen
Implementierung den Nutzern des Typs
verborgen (Datenkapselung) ist
- in Haskell werden abstrakte Datentypen mit
Hilfe des Modul-Konzepts implementiert
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Module in Haskell
Ein Haskell-Modul ist eine Datei mit folgender Struktur:
module <Name> (<Exportliste>) where
• Nur die Datentypen und Funktionen, die in
<Exportliste> angegeben werden, sind nach außen
sichtbar.
• Wenn <Exportliste> weggelassen wird, sind alle
Definitionen automatisch nach außen sichtbar.
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Module in Haskell
module Stapel
(Stapel, push, pop, top, createStack, isEmpty, show)
where
createStack :: Stapel a
isEmpty :: Stapel a -> Bool
push :: a-> Stapel a -> Stapel a
pop :: Stapel a -> Stapel a
top :: Stapel a -> a
data Stapel a = Empty | S a (Stapel a)
. . .
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Module in Haskellmodule Stapel . . . . . . createStack = Empty
isEmpty Empty = True isEmpty _ = False
push x s = S x s
pop Empty = error "pop from an empty stack ..." pop (S _ s) = s
top Empty = error "top from an empty stack ..." top (S x _) = x
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Algebraische Datentypen
ALP I: Margarita Esponda, 12. Vorlesung, 26.11.2012 59
module Menge (Menge, emptySet, isEmpty, inSet, insertSet, list2Set,
subSet, (\\), (|||), (&&&), powerSet )
where
data Menge a = Menge [a]
instance Eq a => Eq (Menge a) where
(==) s1 s2 = subSet set1 set2 && subSet s2 s1
instance (Show a) => Show (Menge a) where
. . .
Abstrakte Datentyp für Mengen
Algebraische Datentypen
ALP I: Margarita Esponda, 12. Vorlesung, 26.11.2012 60
module Menge . . . .
emptySet :: (Menge [Int])
isEmpty :: Eq a => Menge a -> Bool
inSet :: Eq a => a -> Menge a -> Bool
(|||) :: Eq a => Menge a -> Menge a -> Menge a
(\\) :: Eq a => Menge a -> Menge a -> Menge a
(&&&) :: Eq a => Menge a -> Menge a -> Menge a
subSet :: Eq a => Menge a -> Menge a -> Bool
powerSet :: Eq a => Menge a -> Menge (Menge a)
Abstrakte Datentyp für Mengen
Algebraische Datentypen
ALP I: Margarita Esponda, 12. Vorlesung, 26.11.2012 61
module Menge . . . .
emptySet = Menge []
isEmpty (Menge []) = True
isEmpty _ = False
inSet x (Menge ys) = elem x ys
Abstrakte Datentyp für Mengen
Algebraische Datentypen
ALP I: Margarita Esponda, 12. Vorlesung, 26.11.2012 62
module Menge . . . .
-- Vereinigung von zwei Mengen
(|||) (Menge (x:xs)) m = insertSet x ((Menge xs) ||| m)
(|||) (Menge []) m = m
-- Differenzmenge
(\\) (Menge xs) m = Menge [x|x<-xs, not(inSet x m)]
-- Schnittmenge
(&&&) (Menge xs) m = Menge [x|x<-xs, (inSet x m)]
Abstrakte Datentyp für Mengen
Algebraische Datentypen
ALP I: Margarita Esponda, 12. Vorlesung, 26.11.2012 63
module Menge . . . .
subSet (Menge []) _ = TruesubSet _ (Menge []) = FalsesubSet (Menge (x:xs)) m = (inSet x m) && (subSet (Menge xs) m)
powerSet (Menge xs) = Menge powerMenge where powerMenge = map Menge (powerList xs)
powerList :: [a] -> [[a]]powerList [] = [[]]powerList (x:xs) = (powerList xs) ++ (map (x:) (powerList xs))
Abstrakte Datentyp für Mengen