正如他们所说,"true quicksort sorts in-place"。所以short Haskell code的标准quicksort,
quicksort :: Ord a => [a] -> [a]
quicksort [] = []
quicksort (p:xs) = (quicksort lesser) ++ [p] ++ (quicksort greater)
where
lesser = filter (< p) xs
greater = filter (>= p) xs
究竟是什么算法/计算过程 ?
肯定不是what Tony Hoare devised,缺乏最明确的功能,即就地分区算法。
(答案可能是众所周知的,但在SO上还没有。)
更正:这个问题实际上是重复的:毕竟在SO上已知答案 :cf。 Pseudo-quicksort time complexity。
答案 0 :(得分:11)
我更愿意说“quicksort最初是为了原地开发的”,而不是“真正的quicksort就地完成”。快速排序有很多变种,包括随机选择枢轴以避免更糟糕的行为等。这是链接列表快速排序的明智,清晰的定义。
这个定义完全符合我们向英国16岁的数学学生教授快速入学的方式。 (我们正在教算法,而不是编程。)就地非常模糊了目的和设计,这就是为什么我们不教这个细节,尽管距离教授函数式编程或链表只有一百万英里。 (这并没有改变这样一个事实,即当你有破坏性的更新数组时,对交换技巧就地算法是最好的。)
此定义存在时间损失,因为它会为两个子列表遍历列表两次。当然可以将其重写为分区而不是过滤,但我断言这是优化而不是在这里更改基本算法,快速排序。
答案 1 :(得分:1)
所有就地算法都需要在Haskell中进行一些“仪式”,其中可变状态隐藏在monad后面。 上面的算法是快速排序,而不是就地。
答案 2 :(得分:1)
预期的答案(来自here)是“这真的是一种砍伐森林的树种”。事实证明,haskellwiki也提到了它。