在Haskell中对列表进行排序

时间:2016-11-22 12:17:24

标签: haskell functional-programming

我想编写一个获取已排序列表列表的函数,然后将所有内容合并在一起并再次对它们进行排序。

到目前为止我设法写了这个:

merge_:: Ord a => [[a]] -> [a] --takes in the list and merges it
merge_ [] = []
merge_ (x:xs) = x ++ merge_ xs

isort:: Ord a => [a] -> [a] --Sorts a list
isort [] = []
isort (a:x) = ins a (isort x)
        where
            ins a []                = [a]
            ins a (b:y) | a<= b     = a:(b:y)
                        | otherwise = b: (ins a y)

我无法找到一种方法将这两者合并为一个有意义的方式。请注意,我不允许使用诸如('。','$'等)(家庭作业)之类的东西

2 个答案:

答案 0 :(得分:5)

我们开始简单。我们如何合并两个排序列表?

mergeTwo :: Ord a => [a] -> [a] -> [a]
mergeTwo [] ys         = ys
mergeTwo xs []         = xs
mergeTwo (x:xs) (y:ys)
  | x <= y    = x : mergeTwo    xs  (y:ys)
  | otherwise = y : mergeTwo (x:xs)    ys

我们如何合并多个?好吧,我们从第一个和第二个开始并将它们合并在一起。然后我们将新的和第三个合并在一起:

mergeAll :: Ord a => [[a]] -> [a]
mergeAll (x:y:xs) = mergeAll ((mergeTwo x y) : xs)
mergeAll [x]      = x
mergeAll _        = []

奥莱特。现在,要对所有元素进行排序,我们需要从每个元素创建一个列表,然后将它们合并。让我们编写一个为单个项目创建列表的函数:

toList :: a -> [a]
toList x = -- exercise 

现在是一个包含列表中所有元素的函数:

allToList :: [a] -> [[a]]
allToList = -- exercise

现在我们已经完成了。我们只需要使用allToList然后使用mergeAll

isort :: Ord a => [a] -> [a]
isort xs = mergeAll (allToList xs)

请注意,这项练习变得更加容易,因为我们已将其分为四个功能。

练习(对你来说可能是不可能的(家庭作业))

  • 撰写toListallToList
  • 尝试allToList的列表理解。请为allToList尝试更高阶的功能。
  • isort无点((.))。
  • 检查是否已存在具有相同类型的toList函数。使用那个。
  • 使用mergeAll
  • 重写foldr

答案 1 :(得分:0)

试试这个(未经测试):

merge :: Ord a => [a] -> [a] -> [a]
merge [] l1 = l1
merge l1 [] = l1
merge (e1:l1) (e2:l2)
    | e1<e2 = e1:merge l1 (e2:l2)
    | otherwise = e2:merge (e1:l1) l2