这是Mergesort的一个实现,使用更高阶函数,警卫,where和递归。
但是从编译器6:26: parse error on input ‘=’
mergeSort :: ([a] -> [a] -> [a]) -> [a] -> [a]
mergeSort merge xs
| length xs < 2 = xs
| otherwise = merge (mergeSort merge first) (mergeSort merge second)
where first = take half xs
second = drop half xs
half = (length xs) `div` 2
我看不出什么错?或者说我不懂编译器。
答案 0 :(得分:5)
将列表减半不是O(1)运算,而是O(n),因此与命令式合并排序相比,给定的解决方案会带来额外的成本。避免减半的一种方法是简单地通过制作单例直接开始合并,然后直接合并每两个连续的列表:
sort :: (Ord a) => [a] -> [a]
sort = mergeAll . map (:[])
where
mergeAll [] = []
mergeAll [t] = t
mergeAll xs = mergeAll (mergePairs xs)
mergePairs (x:y:xs) = merge x y:mergePairs xs
mergePairs xs = xs
其中merge
已由其他人给出。
答案 1 :(得分:3)
Haskell是一种缩进敏感的编程语言,您只需要修复它(顺便说一句。如果您使用制表符将其更改为使用空格)。
mergeSort :: ([a] -> [a] -> [a]) -> [a] -> [a]
mergeSort merge xs
| length xs < 2 = xs
| otherwise = merge (mergeSort merge first) (mergeSort merge second)
where first = take half xs
second = drop half xs
half = length xs `div` 2
答案 2 :(得分:2)
Haskell中的另一个msort
实现;
merge :: Ord a => [a] -> [a] -> [a]
merge [] ys = ys
merge xs [] = xs
merge (x:xs) (y:ys) | x < y = x:merge xs (y:ys)
| otherwise = y:merge (x:xs) ys
halve :: [a] -> ([a],[a])
halve xs = (take lhx xs, drop lhx xs)
where lhx = length xs `div` 2
msort :: Ord a => [a] -> [a]
msort [] = []
msort [x] = [x]
msort xs = merge (msort left) (msort right)
where (left,right) = halve xs