Sorting 简化选择排序和合并排序

Sorting 简化选择排序和合并排序,sorting,haskell,implementation,mergesort,simplify,Sorting,Haskell,Implementation,Mergesort,Simplify,我已经成功地在几行中实现了insertionsort和quicksort,但selectionsort和mergesort仍然让我头疼;) 同样,我必须自己编写merge,还是可以重用现有组件?对于(a->a->Bool/Ordering)->[a]->[a]->[a]->[a]标准库中没有任何内容,但至少是由上的包提供的,尽管我不确定是否值得为这样一个简单的函数引入依赖项 但是, merge xxs@(x:xs) yys@(y:ys) | x < y = x : merg

我已经成功地在几行中实现了insertionsort和quicksort,但selectionsort和mergesort仍然让我头疼;)


同样,我必须自己编写
merge
,还是可以重用现有组件?对于
(a->a->Bool/Ordering)->[a]->[a]->[a]->[a]
标准库中没有任何内容,但至少是由上的包提供的,尽管我不确定是否值得为这样一个简单的函数引入依赖项

但是,

merge xxs@(x:xs) yys@(y:ys)
    | x < y     = x : merge  xs yys
    | otherwise = y : merge xxs  ys
selectionSort
的一个好定义是

import Data.List -- for unfoldr

selectionSort :: Ord a => [a] -> [a]
selectionSort = unfoldr getMin
  where
    getMin [] = Nothing
    getMin (x:xs) = Just $ extractMinimum x xs

我对选择排序的建议:

import Data.List

selectionsort xs = unfoldr f xs where
    f [] = Nothing
    f xs = Just $ extractMinimum xs

extractMinimum (x:xs) = foldl' f (x,[]) xs where
  f (minimum, greater) x | x < minimum = (x, minimum : greater)
                         | otherwise = (minimum, x : greater) 
导入数据。列表
selectionsort xs=展开f xs,其中
f[]=无
f xs=仅$x最小值xs
extractMinimum(x:xs)=foldl'f(x,[])xs其中
f(最小值,大于)x | x<最小值=(x,最小值:大于)
|否则=(最小值,x:更大)

n.b.@sudo_o和批准该编辑的人:是一个搜索引擎,允许您通过类型签名搜索Haskell库函数;这不是谷歌的错别字。顺便说一下,在Haskell中使用列表时,自顶向下的合并排序是一个非常糟糕的主意。您需要花费大量时间来拆分列表并查找列表的长度。自下而上的工作要简单得多。首先将输入转换为长度为1的列表,然后合并相邻的列表对,直到只剩下一个。@Carl如果我在开始时只计算一次列表的长度,然后将较小的长度显式向下传递,会怎么样?@FredOverflow它不会消除重复的
splitAt
s的成本。这是对不可变列表的O(n)操作。是否应该将其移动到codereview?
extractMinimum :: Ord a => a -> [a] -> (a,[a])
extractMinimum x = foldl' select (x, [])
  where
    select (mini, greater) y
      | y < mini  = (y, mini:greater)
      | otherwise = (mini, y:greater)
import Data.List -- for unfoldr

selectionSort :: Ord a => [a] -> [a]
selectionSort = unfoldr getMin
  where
    getMin [] = Nothing
    getMin (x:xs) = Just $ extractMinimum x xs
import Data.List

selectionsort xs = unfoldr f xs where
    f [] = Nothing
    f xs = Just $ extractMinimum xs

extractMinimum (x:xs) = foldl' f (x,[]) xs where
  f (minimum, greater) x | x < minimum = (x, minimum : greater)
                         | otherwise = (minimum, x : greater)