有没有人知道如何将序列排序为惰性列表以及急切列表sort [3,4,2,1]
,并使用sort
sort = foldr insert []
where
insert x [] = [x]
insert x (y:ys) =
if x<y
then x:y:ys
else y:insert x ys
答案 0 :(得分:2)
您编写了insertion sort的实现,与所有其他基于确定性比较的排序算法一样,strict。 sort
返回的第一个值被定义为输入列表的最小值,这意味着sort
必须检查列表中的每个元素以确保它找到最小值。您不能提前返回最小值,因为实际最小值可能正好在列表的末尾 - 在您全部测试之前,您永远不会知道。
所以sort
不可能是懒惰的。如果列表是无限的,它将永远不会返回值。如果列表中的任何元素为undefined
,则会崩溃。
换句话说,您的sort
版本(以及我所说的任何确定性基于比较的sort
)对待惰性列表只是相同的< / em> as eager list(那些已经完全评估为normal form的列表) - 它会在输出产生任何输出之前始终评估输入的每个元素。
答案 1 :(得分:0)
Selection sort可以逐步和严格地实施非严格。
sort :: Ord a => [a] -> [a]
sort [] = []
sort (x:xs) = let (y, ys) = foldr select (x, []) xs
in y : sort ys
select :: Ord a => a -> (a, [a]) -> (a, [a])
select x (y, ys)
| x < y = (x, y:ys)
| otherwise = (y, x:ys)
sort :: Ord a => [a] -> [a]
sort [] = []
sort (x:xs) = let (y, ys) = foldr select (x, []) xs
in let zs = sort ys in seq zs (y:zs)
select :: Ord a => a -> (a, [a]) -> (a, [a])
select x (y, ys)
| x < y = (x, y:ys)
| otherwise = (y, x:ys)
但是,对于所有情况,选择排序始终需要O(n^2)
次。对于大多数情况,最好使用Data.List
模块导出的sort
函数。