以下快速排序的Haskell实现是否有效?

我在名为 Learn You Haskell 的书中找到了快速排序的以下实现。

quicksort :: (Ord a) => [a] -> [a]  
quicksort [] = []  
quicksort (x:xs) =   
    let smallerSorted = quicksort [a | a <- xs, a <= x]  
        biggerSorted = quicksort [a | a <- xs, a > x]  
    in  smallerSorted ++ [x] ++ biggerSorted  

我的问题是,这是否会破坏快速排序的效率,因为

  1. ++ 操作相当昂贵
  2. 列表推导用于构造两个子列表?

回答

对于算法点,它不是就地算法。因此,它不会像您所知道的传统命令式实现那样高效。(就地是类似快速排序的排序算法卓越性能的一个关键方面。)

它将以快速排序的典型复杂性运行(平均而言O(N * log(N)),最坏情况O(N²))。因此,从能够随输入扩展的意义上说,它是有效的。但它不会像高度调整的实现那样快(例如,请参阅此问题)。

作为一个小调整,我记得更换[x] ++ biggerSorted(x:biggerSorted)是唾手可得的小幅提高性能。那是多年前的事了,所以也许今天优化编译器可以自动进行低级优化。

  • 快速排序是 O(n^2),如果枢轴是有利的,它只是 O(n log n)。
  • 不过,可以肯定地说,*预期的*运行时间是 O(n lg n); 当您使用新列表而不是交换来实现分区时,隐藏常量会增加。
  • 如今,GHC 确实足够聪明,可以将 `[foo] ++ bar` 转换为 `foo:bar`。

以上是以下快速排序的Haskell实现是否有效?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>