ALP I Funktionale Programmierung Sortieren und Suchen (Teil 1) WS 2012/2013
Suchen 8 False unsortiert 21 4 16 7 19 11 12 7 1 5 27 3 8 False sortiert 2 4 6 7 9 11 12 18 21 24 27 36
Suchen in unsortierten Listen search :: Integer -> [Integer] -> Bool search b [] = False search b (a:xs) (a/=b) = search b xs otherwise = True >>> search3 2 (take 1000000 [1,3..]) False (1.51 secs, 68699880 bytes) search :: Integer -> [Integer] -> Bool search b [] = False Probleme: >>> search 2 (take 1000000 [1,3..]) False (2.24 secs, 117110684 bytes) search b (a:xs) = (a==b) search b xs search 'a' "bla blue..." geht nicht! search :: a -> [a] -> Bool Probleme: search b [] = False search b (a:xs) = (a==b) search b xs No instance for (Eq a)... Probable fix: add (Eq a) to the type signature(s) for `search'...
Suchen in sortierten Listen Für alle Typen a, für denen eine Gleichheit-Operation definiert ist. search :: Eq a => a -> [a] -> Bool search b [] = False search b (a:x) = (a==b) search b x search :: Ord a => a -> [a] -> Bool search b [] = False search b (a:x) a<b = search b x a==b = True otherwise = False Für alle Typen a, für denen Vergleichsoperationen definiert sind. >>> search 2 (take 1000000 [1,3..]) False (0.01 secs, 531908 bytes)
Suchen in sortierten Listen Binärsuche sortiert 8 8 < 7? 8 < 18? 2 4 6 7 9 11 12 18 21 24 27 36 40 53 77 n n 0 1...... n 4 2 False nur 4 Schritte Gut für imperative Programmiersprachen!
Maximale Schrittanzahl mit Arrays n = 128 = 2 7 7 = log 2 ( 128 ) 64 32 16 = 2 6 = 2 5 = 2 4 Im schlimmsten Fall log 2 (n) Schritte 8 = 2 3 4 = 2 2 2 = 2 1 1 = 2 0 Anzahl der Elemente 3... 1,023... 1,073,741,824 Lineare Suche Binäre Suche 3 2...... 1,023 10...... 1,073,741,824 30
Binärsuche binsearch :: (Ord a) => a -> [a] -> Bool binsearch b [] = False binsearch b [x] = b==x binsearch b xs b<mitte = binsearch b links b>mitte = binsearch b rechts b==mitte = True where half = (length xs) `div` 2 links = take half xs rechts = drop half xs mitte = head rechts
Sortierte Bereich
Sortierte Bereich
Sortierte Bereich
Sortierte Bereich
Größer als alle Elemente auf der linken Seite Es ist kein weiterer Vergleich notwendig
Kleiner als alle Elemente der linken Seite Schlimmster Fall
Alle Elemente müssen verschoben werden
isort :: (Ord a) => [ a ] -> [ a ] isort [] = [] isort (a:x) = ins a (isort x) where ins :: (Ord a) => a -> [a] -> [a] ins a [] = [a] ins a (b:y) a<= b = a:(b:y) otherwise = b: (ins a y)
Quick-Sort-Algorithmus Der Quicksort-Algorithmus (1962 von Hoare entwickelt) ist einer der beliebtesten Sortieralgorithmen, weil er sehr effizient und einfach zu implementieren ist. Grundidee: 1) Ein Element (Pivot) aus dem Array wird gewählt 2) Alle Zahlen des Arrays werden mit dem Pivot-Element verglichen und während des Vergleichsdurchlaufs in zwei Bereiche umorganisiert (Partitionierung). Der erste Bereich beinhaltet die Zahlen, die kleiner als das Pivot-Element sind und der zweite alle, die größer oder gleich sind. Am Ende des Durchlaufs wird das Pivot-Element in der Mitte beider Bereiche positioniert. 3) Nach jeder Partitionierung wird der Quicksort-Algorithmus rekursiv mit beiden Teilbereichen ausgeführt (solange die Teilbereiche mehr als ein Element beinhalten).
Quick-Sort-Algorithmus 5 7 3 4 9 1 6 5 9 2 0 4 8 3 6 < 3 4 1 2 0 4 3 5 7 9 6 5 9 8 6 < < 1 2 0 3 4 4 3 5 6 6 5 7 9 9 8 < < < < 0 1 2 3 3 4 4 5 5 6 6 7 8 9 9
Quick-Sort-Algorithmus 5 7 3 4 9 1 6 5 9 2 0 4 8 3 6 < 3 4 1 2 0 4 3 5 7 9 6 5 9 8 6 < < 1 2 0 3 4 4 3 5 6 6 5 7 9 9 8 < < < < 0 1 2 3 3 4 4 5 5 6 6 7 8 9 9 Der Quicksort-Algorithmus funktioniert am besten, wenn die Teilbereiche fast gleich gross sind.
0 1 2 3 4 5 6 7 8 Quick-Sort-Algorithmus 0 1 2 3 4 5 6 7 8 0 1 2 3 4 5 6 7 8 Im schlimmsten Fall! 0 1 0 1 2 2 3 4 5 6 7 8 3 5 6 7 8 4 sind alle Elemente bereits sortiert. 0 1 2 3 4 5 6 7 8 0 1 2 3 4 5 6 7 8 0 1 2 3 4 5 6 7 8 0 1 2 3 4 5 6 7 8
Quick-Sort-Algorithmus quicksort :: [Integer] -> [Integer] quicksort [] = [] quicksort (x:xs) = quicksort [ y y <- xs, y <= x ] ++ [x] ++ quicksort [ y y <- xs, y > x ] Das Problem in Haskell ist der Speicherverbrauch und die Komplexität der Verkettungsfunktion (++).
Quick-Sort-Algorithmus Quicksort-Algorithmus mit Hilfe der filter-funktion qsort :: (Ord a) => (a -> a -> Bool) -> [a] -> [a] qsort p [] = [] qsort p [x] = [x] qsort p (x:xs) = qsort p (filter (p x) xs) ++ [x] ++ qsort p (filter (np x) xs) where np x y = not (p x y)