Haskell合并排序

emu*_*isa 3 mergesort haskell

这是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
Run Code Online (Sandbox Code Playgroud)

我看不出怎么了?或者我不理解编译器。

Red*_*edu 10

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
Run Code Online (Sandbox Code Playgroud)

  • @FabianSchneider,不,不应该。Haskell 列表的元素和尾部(这里重要的是)都是惰性的。因此,按照上述代码的方式构造 Haskell 列表是高效的:*首先*分配列表构造函数,然后才对尾部进行求值。 (2认同)
  • @dfeuer 感谢您提供的信息;我思考了一下,并阅读了更多有关惰性和列表构造函数的内容,这很有道理。另外,在 repl 上对其进行“基准测试”。这并不是一件真正可靠的事情...... (2认同)

eps*_*lbe 6

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
Run Code Online (Sandbox Code Playgroud)

  • @emuterisa 如果它解决了您的问题,这应该是一个可接受的答案;哪怕这是三年前的事…… (2认同)

L.-*_*hen 6

将列表减半不是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
Run Code Online (Sandbox Code Playgroud)

其中merge已经被别人给的。