刚刚在排序算法与Haskell湿了我的脚。我实现了插入排序和合并排序合并排序的方式比插入排序更快谜题
insert_sort :: (Ord a, Show a) => [a] -> [a]
insert_sort keys = foldr f [] keys
where f key [] = [key]
f key acc = insert key acc
insert y [] = [y]
insert y (x:xs)
| x < y = x : insert y xs
| otherwise = y : x : xs
merge_sort :: (Ord a, Show a) => [a] -> [a]
merge_sort (x:[]) = [x]
merge_sort keys = merge (merge_sort (take len keys)) (merge_sort (drop len keys))
where len = length keys `div` 2
merge :: [a] -> [a] -> [a]
merge (x:xs) [] = (x:xs)
merge [] (y:ys) = (y:ys)
merge (x:xs) (y:ys) = if x <= y
then x : merge (xs) (y:ys)
else y : merge (x:xs) ys
以下是我比较了它们的效率:
insert_sort $ take 100000 $ randomRs (1,100000) $ mkStdGen 1 ::[Int]
merge_sort $ take 100000 $ randomRs (1,100000) $ mkStdGen 1 ::[Int]
他们都开始多在短暂的延迟后,打印出结果,但合并排序打印更快。我们知道,合并排序比大数据集的插入排序快得多。我认为这将表现在他们如何给出结果(如长时间延迟与短时延迟),而不是他们如何输出结果。是因为我使用foldr
进行插入排序吗?现场背后是什么?
编辑:Thx guys。自从我开始学习Haskell以来,我听说过懒惰的评估,但还没有掌握它。有人会用一个小数据集说明一点,比如[5,2,6,3,1,4]?自从第一个元素终于出现以后,如何在使用foldr
完成排序之前输出结果?
欢迎来到懒惰的世界! – 2012-01-19 01:05:06
如果你想打印结果,他们首先必须计算。因此,计算结果更快的算法也可以更快地打印出结果。这令人惊讶吗?或者,也许我不明白你在问什么。 – sth 2012-01-19 01:07:20
添加了插图。 – 2012-01-19 02:27:10