我已经设法在几行中实现了insertionsort和quicksort,但是selectionsort和mergesort仍让我感到头痛;)
selectionsort [] = []
selectionsort (x:xs) =
let (minimum, greater) = extractMinimum x [] xs
in minimum : selectionsort greater
extractMinimum minimumSoFar greater [] = (minimumSoFar, greater)
extractMinimum minimumSoFar greater (x:xs)
| x < minimumSoFar = extractMinimum x (minimumSoFar:greater) xs
| otherwise = extractMinimum minimumSoFar (x:greater) xs
类似于标准库中的extractMinimum
函数吗?我试着在(a -> a -> Bool/Ordering) -> [a] -> (a, [a])
没有任何运气的情况下唠叨。
mergesort [ ] = [ ]
mergesort [x] = [x]
mergesort xs =
let (left, right) = splitAt (length xs `div` 2) xs
in merge (mergesort left) (mergesort right)
merge xs [] = xs
merge [] ys = ys
merge xxs@(x:xs) yys@(y:ys)
| x < y = x : merge xs yys
| otherwise = y : merge xxs ys
同样,我是否必须自己编写merge
,还是可以重用现有组件? Hoogle没有给我(a -> a -> Bool/Ordering) -> [a] -> [a] -> [a]
的有用结果。
答案 0 :(得分:2)
标准库中没有任何内容,但merge
上的包提供了至少hackage,但我不确定是否值得为这样一个简单的函数提供依赖。
然而,
merge xxs@(x:xs) yys@(y:ys)
| x < y = x : merge xs yys
| otherwise = y : merge xxs ys
生成不稳定的排序,为了获得稳定的排序,放置x
的条件应为x <= y
。
对于extractMinimum
,我也没有找到任何东西,但我可以提供另一种定义,
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)
selectionSort
的一个很好的定义是
import Data.List -- for unfoldr
selectionSort :: Ord a => [a] -> [a]
selectionSort = unfoldr getMin
where
getMin [] = Nothing
getMin (x:xs) = Just $ extractMinimum x xs
答案 1 :(得分:0)
我对选择排序的建议:
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)