1. 排序算法
(1)选择排序
-- selection sort
ssort :: (Ord a) => [a] -> [a]
ssort [] = []
ssort xs = m:(ssort $ delete m xs)
where m = minimum xs
delete = delete' []
delete' :: (Eq a) => [a] -> a -> [a] -> [a]
delete' _ v [] = []
delete' acc v (x:xs) | v == x = acc ++ xs
| otherwise = delete' (acc ++ [x]) v xs
(2)插入排序
-- insert sort
isort :: (Ord a) => [a] -> [a]
isort [] = []
isort (x:xs) = insert x $ isort xs
where insert :: (Ord a) => a -> [a] -> [a]
insert x xs = takeWhile (<= x) xs
++ [x]
++ dropWhile (<= x) xs
(3)快速排序
-- quick sort
qsort :: (Ord a) => [a] -> [a]
qsort [] = []
qsort (x:xs) = qsort [i | i <- xs, i <= x]
++ [x]
++ qsort [i | i <- xs, i > x]
(4)归并排序
-- merge sort
msort :: (Ord a) => [a] -> [a]
msort [] = []
msort [x] = [x]
msort xs = merge (msort xs1) (msort xs2)
where k = (length xs) `div` 2
xs1 = take k xs
xs2 = drop k xs
merge :: (Ord a) => [a] -> [a] -> [a]
merge [] b = b
merge a [] = a
merge a@(x:xs) b@(y:ys) | x <= y = x:(merge xs b)
| otherwise = y:(merge a ys)
(5)堆排序
-- priority queue
module PQueue(PQueue,emptyPQ,pqEmpty,enPQ,dePQ,frontPQ) where
newtype PQueue a = PQ [a]
deriving Show
emptyPQ :: PQueue a
emptyPQ = PQ []
pqEmpty :: PQueue a -> Bool
pqEmpty (PQ []) = True
pqEmpty _ = False
enPQ :: (Ord a) => a -> PQueue a -> PQueue a
enPQ x (PQ q) = PQ (insert x q)
where insert :: (Ord a) => a -> [a] -> [a]
insert x [] = [x]
insert x r@(y:ys) | x <= y = x:r
| otherwise = y:insert x ys
dePQ :: (Ord a) => PQueue a -> PQueue a
dePQ (PQ []) = error "dePQ: empty priority queue"
dePQ (PQ (x:xs)) = PQ xs
frontPQ :: (Ord a) => PQueue a -> a
frontPQ (PQ []) = error "frontPQ: empty priority queue"
frontPQ (PQ (x:xs)) = x
-- heap sort
import PQueue
mkPQ :: (Ord a) => [a] -> PQueue a
mkPQ xs = foldr enPQ emptyPQ xs
hsort :: (Ord a) => [a] -> [a]
hsort xs = hsort' (mkPQ xs)
where hsort' :: (Ord a) => PQueue a -> [a]
hsort' pq | pqEmpty pq = []
| otherwise = (frontPQ pq):(hsort' $ dePQ pq)
(6)树排序
-- binary search tree
{-# LANGUAGE GADTs #-}
module BinTree(BinTree, inTree, addTree, delTree, buildTree, preorder, inorder, postorder) where
data BinTree a where
EmptyBT :: (Ord a) => BinTree a
NodeBT:: (Ord a) => a -> BinTree a -> BinTree a -> BinTree a
inTree :: (Ord a, Show a) => a -> BinTree a -> Bool
inTree v EmptyBT = False
inTree v (NodeBT v' lf rt) | v == v' = True
| v < v' = inTree v lf
| v > v' = inTree v rt
addTree :: (Ord a, Show a) => a -> BinTree a -> BinTree a
addTree v EmptyBT = NodeBT v EmptyBT EmptyBT
addTree v (NodeBT v' lf rt) | v == v' = NodeBT v' lf rt
| v < v' = NodeBT v' (addTree v lf) rt
| otherwise = NodeBT v' lf (addTree v rt)
delTree :: (Ord a, Show a) => a -> BinTree a -> BinTree a
delTree v EmptyBT = EmptyBT
delTree v (NodeBT v' lf EmptyBT) | v == v' = lf
delTree v (NodeBT v' EmptyBT rt) | v == v' = rt
delTree v (NodeBT v' lf rt) | v < v' = NodeBT v' (delTree v lf) rt
| v > v' = NodeBT v' lf (delTree v rt)
| v == v' = NodeBT k lf (delTree k rt)
where k = minTree rt
minTree :: BinTree a -> a
minTree (NodeBT v EmptyBT _) = v
minTree (NodeBT _ lf _) = minTree lf
buildTree :: (Ord a, Show a) => [a] -> BinTree a
buildTree lf = foldr addTree EmptyBT lf
preorder :: (Ord a, Show a) => BinTree a -> [a]
preorder EmptyBT = []
preorder (NodeBT v lf rt) = [v] ++ preorder lf ++ preorder rt
inorder :: (Ord a, Show a) => BinTree a -> [a]
inorder EmptyBT = []
inorder (NodeBT v lf rt) = inorder lf ++ [v] ++ inorder rt
postorder :: (Ord a, Show a) => BinTree a -> [a]
postorder EmptyBT = []
postorder (NodeBT v lf rt) = postorder lf ++ postorder rt ++ [v]
import BinTree
-- tree sort
tsort :: (Ord a) => [a] -> [a]
tsort xs = inorder . buildTree $ xs
2. 时间复杂度与空间复杂度
参考
Algorithms: A Functional Programming Approach