Ocaml高效快速排序

时间:2012-05-15 10:29:55

标签: ocaml quicksort

我想知道如何编写快速排序的高效版本,其中列表在一次传递中被分区

我有这段代码,

    let rec quicksort' = function
[] -> []
| x::xs -> let small = List.filter (fun y -> y < x ) xs
           and large = List.filter (fun y -> y > x ) xs

in quicksort' small @ (x :: quicksort' large);;

但是在这里,我要经历超过1次的清单(对于小型和大型呼叫2次快速排序)。

这个想法是在只需一步的情况下完成,而不会超过1次。

2 个答案:

答案 0 :(得分:18)

List.partition是要走的路:

let rec quicksort = function
    | [] -> []
    | x::xs -> let smaller, larger = List.partition (fun y -> y < x) xs
               in quicksort smaller @ (x::quicksort larger)

请注意,List.partition有助于避免通过xs进行一次冗余遍历。你仍然需要递归地对较小的部分和较大的部分进行排序,因为这是Quicksort的工作方式。

我不得不说这个版本的quicksort远没有效率。 Quicksort algorithm是一种固有的就地算法,它递归地改变输入数组。另一个因素是枢轴选择;选择第一个元素作为支点并不总是一个好主意。

这些因素导致效率的实现极为不同(可能使用Array和变异)。 List上的Quicksort应该用于演示算法的概念及其递归的美感。

答案 1 :(得分:4)

如果您需要编写有效的排序功能,您可能需要阅读这篇富有洞察力的论文:Engineering a sort function。否则,我很确定List.sort也写得很好。