List Haskell中有序列表函数的排序
在我的课程作业中,我必须获取两个数字列表,对它们进行排序,然后将它们合并,并按顺序输出新列表。如果列表在键入时已按顺序排列,则此操作有效,但如果第一个列表的开头是9,则此操作无效。因此,我遇到的麻烦是在合并后对列表进行排序,在其他语言中,我会使用for循环,但在Haskell中不确定 下面是我的代码:List Haskell中有序列表函数的排序,list,sorting,haskell,List,Sorting,Haskell,在我的课程作业中,我必须获取两个数字列表,对它们进行排序,然后将它们合并,并按顺序输出新列表。如果列表在键入时已按顺序排列,则此操作有效,但如果第一个列表的开头是9,则此操作无效。因此,我遇到的麻烦是在合并后对列表进行排序,在其他语言中,我会使用for循环,但在Haskell中不确定 下面是我的代码: merge :: Ord a => [a] -> [a] -> [a] merge x [] = x merge [] x = x merge (x:xs) (y:ys) = i
merge :: Ord a => [a] -> [a] -> [a]
merge x [] = x
merge [] x = x
merge (x:xs) (y:ys) = if x < y
then x:(merge xs (y:ys))
else y:(merge (x:xs) ys)
merge::Ord a=>[a]->[a]->[a]->[a]
合并x[]=x
合并[]x=x
合并(x:xs)(y:ys)=如果x
因此,如果两个输入列表都已排序,则当前解决方案将返回一个已排序列表。如果输入列表未排序,则有两个选项,分别对输入列表进行排序,然后按原样合并,或者合并未排序的列表,然后对新列表进行排序
合并未排序的列表,然后将其作为一个列表进行排序似乎更合理,因此下面是解决方案。我已经使用了快速排序的快速实现,但是您可以使用任何您想要的排序算法
--takes 2 sorted or unsorted lists, merges them, then sorts them
merge :: (Ord a) => [a] -> [a] -> [a]
merge [] [] = []
merge x [] = sort x
merge [] y = sort y
merge x y = sort (x ++ y)
-- where first element of list is pivot
sort :: (Ord a) => [a] -> [a]
sort [] = []
sort (x:xs) = sort [x'|x'<-xs, x'<=x] ++ [x] ++ sort [x'|x'<-xs, x'>x]
——获取2个已排序或未排序的列表,合并它们,然后对它们进行排序
合并::(Ord a)=>[a]->[a]->[a]->[a]
合并[][]=[]
合并x[]=排序x
合并[]y=排序y
合并x y=排序(x++y)
--其中列表的第一个元素是pivot
排序::(Ord a)=>[a]->[a]
排序[]=[]
排序(x:xs)=排序[x'| x'x]
有很多方法可以做到这一点,这种方法的缺点是,即使列表已经排序,也必须使用列表。您可以通过检查列表是否已排序,然后根据需要对其排序来解决此问题。我希望这个答案有帮助。听起来你实际上应该实现的是 在“合并排序”中,将两个已排序列表合并为一个已排序列表,是的。缺少的观察是,大小为0或1的列表必须已经排序 这意味着,如果开始将函数应用于大小为0或1的列表,然后合并该合并的结果,然后合并该合并的结果,最终将得到一个完全排序的列表 下面是一个例子:
-- Your function
merge :: Ord a => [a] -> [a] -> [a]
merge x [] = x
merge [] x = x
merge (x:xs) (y:ys) = if x < y
then x:(merge xs (y:ys))
else y:(merge (x:xs) ys)
-- Arbitrarily split a list into two ~equally sized smaller lists.
-- e.g. [2,7,1,8,2] -> ([2,7,1], [8,2])
split list = splitAt ((length list) `div` 2) list
-- Split a list into halves until each piece is size 0 or 1,
-- then 'merge' them back together.
mergeSort [] = []
mergeSort [x] = [x]
mergeSort list =
let (firstHalf, secondHalf) = split list
in merge (mergeSort firstHalf) (mergeSort secondHalf)
——您的函数
合并::Ord a=>[a]->[a]->[a]
合并x[]=x
合并[]x=x
合并(x:xs)(y:ys)=如果x([2,7,1],[8,2])
拆分列表=拆分((长度列表)`div`2)列表
--将列表分成两半,直到每个部分的大小为0或1,
--然后将它们“合并”在一起。
合并排序[]=[]
合并排序[x]=[x]
合并排序列表=
let(上半部分,下半部分)=拆分列表
合并中(合并排序上半部分)(合并排序下半部分)
mergeSort[2,7,1,8,2]
将计算为[1,2,2,7,8]
。仅使用您的merge
功能,列表已排序。对于类似合并排序的问题,您希望分而治之,以便输入列表始终按顺序排列。一种方法是将输入分解为单例,这些单例总是按定义排序的,然后让合并函数尾部递归地插入两个列表头中较小的一个。当一个输入列表最终为空时,它会附加另一个。在本例中,merge xs ys=sort(xs++ys)
。或者实际上是merge=(sort.)。(++)