以下 Haskell 快速排序的实现是否有效?
Is the following Haskell implementation of quicksort efficient?
我在名为 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
我的问题是,鉴于
,这不会破坏快速排序的效率吗
- ++ 操作相当昂贵
- 列表理解用于构造两个子列表?
算法点,不是原地算法。因此,它不会像您所知道的传统命令式实现那样高效。 (就地是类似快速排序的排序算法卓越性能的一个重要方面。)
它将 运行 具有快速排序的典型复杂性(平均 O(N * log(N))
最坏情况 O(N²)
)。因此,从某种意义上说,它是有效的,因为它能够随输入进行扩展。但它不会像高度调整的实现那样快(例如,参见 this question)。
作为一个小调整,我记得用 (x:biggerSorted)
替换 [x] ++ biggerSorted
是一个容易实现的目标,可以稍微提高性能。那是很多年前的事了,所以也许今天的优化编译器可以自动进行低级优化。
我在名为 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
我的问题是,鉴于
,这不会破坏快速排序的效率吗- ++ 操作相当昂贵
- 列表理解用于构造两个子列表?
算法点,不是原地算法。因此,它不会像您所知道的传统命令式实现那样高效。 (就地是类似快速排序的排序算法卓越性能的一个重要方面。)
它将 运行 具有快速排序的典型复杂性(平均 O(N * log(N))
最坏情况 O(N²)
)。因此,从某种意义上说,它是有效的,因为它能够随输入进行扩展。但它不会像高度调整的实现那样快(例如,参见 this question)。
作为一个小调整,我记得用 (x:biggerSorted)
替换 [x] ++ biggerSorted
是一个容易实现的目标,可以稍微提高性能。那是很多年前的事了,所以也许今天的优化编译器可以自动进行低级优化。