Reputation: 25812
I implemented quicksort
in OCaml. Here is the code:
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;;
First, I think maybe there is a better way to implement partition. List.partition
came to my mind, but I just wanted to implement the key part by myself
Second, I use @
a lot in the sorting which is inefficient
, right?
any suggestions?
Edit
One more question to think about is whether 3-way quicksort
affects the implementation in OCaml?
Upvotes: 1
Views: 585
Reputation: 9878
A micro optimization that you can try is to do List.concat[[qs left]; [pivot]; [qs right]]
to append the lists at once buth you will need to run some benchmarks to verify this even helps.
Upvotes: 2
Reputation: 31459
The p
function is badly indented; speaking of indentation, I tend to think the style of having a in
on the next line is overkill for single-line declarations, so I'd rather put them at the end of the one-liner declaration.
More importantly, there is no need for it to take a tuple of lists as arguments, you'll have something syntactically lighter using two separate (curried) arguments. You could also use the List.partition
function of the standard library.
Upvotes: 2