A few years ago I did some analysis of sorting algorithms in F # in a very imperative style; I tried to defeat the implementation of .NET stocks and was able to do it here . Went today to answer this question, but FPish will not allow me to create an account. Argh! Gotta make my post somewhere, and here, like nowhere else, lol ...
While reading "Learn You a Haskell For Great Good" yesterday, the author created an example for implementing quicksort. The description was pretty clear, and even before I got into the code sample, an elegant recursive solution appeared in my head (in Haskell). I guess I never had an intuitive idea of ββhow quicksort does its job, because the trivial solution is quite simple, if not very effective.
Here is my version in F #:
let rec quicksort = function | [] -> [] | pivot :: xs -> (left pivot xs) @ pivot :: (right pivot xs) and left pivot xs = quicksort [ for x in xs do if x <= pivot then yield x ] and right pivot xs = quicksort [ for x in xs do if x > pivot then yield x ]
And, the equivalent of Haskell (I like this ... clean!):
quicksort :: Ord a => [a] -> [a] quicksort [] = [] quicksort (pivot : xs) = left ++ pivot : right where left = quicksort [ x | x <- xs, x <= pivot ] right = quicksort [ x | x <- xs, x > pivot ]
For grins, here is another version of F # (mostly tail recursive), which is about 2 times faster than the trivial version. Don't bother with the fact that this contradicts my original post, so donβt imagine how it stacks up with the volatile version of my OP on FPish.net (FSHub) a few years ago ...
let rec quicksort' xs = let rec aux pivot left right = function | [] -> (quicksort' left) @ pivot :: (quicksort' right) | x :: xs -> if x <= pivot then aux pivot (x :: left) right xs else aux pivot left (x::right) xs match xs with | [] -> [] | x :: xs -> aux x [] [] xs
James Hugard
source share