我在OCaml中实现了quicksort
。这是代码:
let shuffle d =
let nd = List.map (fun c -> (Random.bits (), c)) d in
let sond = List.sort compare nd in
List.map snd sond;;
let partition = function
| [] -> ([], [], [])
| pivot::tl ->
let rec p (left, right) = function
| [] -> (left, right, [pivot])
| first::rest ->
let c = compare pivot first
in
if c > 0 then
p (first::left, right) rest
else
p (left, first::right) rest
in
p ([], []) tl;;
let quicksort l =
let sl = shuffle l
in
let rec qs = function
| [] -> []
| l ->
let (left, right, pivot) = partition l
in
(qs left) @ pivot @ (qs right)
in
qs sl;;
首先,我想也许有更好的方法来实现分区。 List.partition
出现在我的脑海中,但我只想自己实施关键部分
第二次,我在排序@
中使用了inefficient
,对吗?
有什么建议吗?
修改
要考虑的另一个问题是3-way quicksort
是否会影响OCaml中的实现?
答案 0 :(得分:2)
p
函数严重缩进;说到缩进,我倾向于认为在下一行中使用in
的风格对于单行声明来说是过度的,所以我宁愿将它们放在单行声明的末尾。
更重要的是,没有必要将列表元组作为参数,你将使用两个独立的(curried)参数在语法上更轻松。您还可以使用标准库的List.partition
功能。
答案 1 :(得分:2)
您可以尝试的微优化是{{1}}立即附加列表但是您需要运行一些基准来验证这一点甚至是有帮助的。