V15 ALP1 Abstrakte Datentypen 2013 - inf.fu-berlin.de · Abstrakt Datentypen ALP I: Margarita...

Post on 17-Aug-2019

229 views 0 download

Transcript of V15 ALP1 Abstrakte Datentypen 2013 - inf.fu-berlin.de · Abstrakt Datentypen ALP I: Margarita...

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