【发布时间】:2013-08-18 13:35:55
【问题描述】:
insertionSort :: (Ord a) => [a] -> [a]
insertionSort (x:xs) = insertionSortIter [x] xs
where insertionSortIter sorted [] = sorted
insertionSortIter sorted (x:xs) = insertionSortIter (insert x sorted (length sorted)) xs
insert x list n --insert x in list at n
| n == 0 = x:list
| x < list !! (n - 1) = insert x list (n - 1)
| otherwise = firstns ++ (x:other) where (firstns, other) = splitAt n list
-- [1..10000] 30s
mergeSort :: (Ord a) => [a] -> [a]
mergeSort (x:[]) = [x]
mergeSort list = merge (mergeSort list1) (mergeSort list2)
where (list1, list2) = splitAt (length list `div` 2) list
merge [] list = list
merge list [] = list
merge (x:xs) (y:ys) = if x < y then x:(merge xs (y:ys)) else y:(merge (x:xs) ys)
-- [1..10000] 2.4s
执行时间由构建时间指定(1 或 1.5 秒)。但您仍然可以感受到不同。
问题可能是insert 函数或firstns ++ (x:other) 的每个分支的执行速度太慢。但无论如何,要将项目放在列表的末尾,我需要遍历整个列表 O(n)。
【问题讨论】:
-
还有什么问题?
-
insertionSortIter迭代 O(n) 个位置并在每次迭代时调用 O(n) 时间!!运算符,使其 O(n^2) 仅插入单个项目.不要那样做。 -
ДМИТРИЙ,很高兴在那里见到你。为何这么慢。我做错了什么。
-
@DanielWagner,好的。
!!和++在这种情况下很糟糕。我该怎么办? -
@IVlad,在这个综合测试中 (
[1..n]) 应该比归并排序更快。
标签: haskell mergesort insertion-sort