Three Beautiful Quicksorts
catonmat.net
catonmat.net
I just wanted to tell you that if you like my articles, you can subscribe to my rss feed here:
http://feeds.feedburner.com/catonmat
Thanks! :)
module Quicksort where
quicksort (x:xs) =
quicksort [ i | i <- xs, i < x ]
++ [x] ++
quicksort [ i | i <- xs, i >= x ]
quicksort [] = []Beautiful, elegant, useless. Maybe that should be the Haskell motto.
qsort([]) -> [];
qsort([Pivot|Rest]) ->
qsort([ X || X <- Rest, X < Pivot])
++ [Pivot] ++
qsort([ X || X <- Rest, X >= Pivot]).
More: http://en.literateprograms.org/Category:Quicksort quicksort (x:xs) = let (a, b) = span (< x) xs in (quicksort a) ++ [x] ++ (quicksort b) quicksort (x:xs) = let (a, b) = span (< x) xs in (quicksort a) ++ [x] ++ (quicksort b)
Actually, this is incorrect. span will split the list as soon as it finds the predicate to be false on an item, instead of finding the smaller elements of the whole list. So, for instance, if we try your function as in the following, we get improper results: > quicksort [1, 2, 3, 2, 1]
[1,2,1,2,3]
> quicksort [1, 2, 3, -2, -1]
[1,2,-2,-1,3]
> quicksort [1, 2, 3, -2, 0, -1]
[1,2,-2,-1,0,3] (defun qsort (ax)
(and ax
(let ((a (car ax))
(x (cdr ax)))
(append (qsort [y (y <- x) (< y a)])
(list a)
(qsort [y (y <- x) (>= y a)])))))
If you want the x:xs stuff you could load fare-matcher and write something like: (defun qsort (l)
(ematch l
(nil nil)
((cons x xs) (append (qsort [ i (i <- xs) (< i x) ])
(list x)
(qsort [ i (i <- xs) (>= i x) ]))))) qsort [] = []
qsort (x:xs) = qsort (filter (< x) xs) ++ [x] ++ qsort (filter (>= x) xs)I know that some compilers are smart, and can inline things, but still method calls are not necessary the most efficient way to go.
Sure, it might look pretty, but it is not efficient.
Also, you only have to push a handful of pointers to the stack, which doesn't seem to be expensive to me.
def quicksort(lst):
if len(lst) == 0:
return []
else:
return quicksort([x for x in lst[1:] if x < lst[0]]) + [lst[0]] + \
quicksort([x for x in lst[1:] if x >= lst[0]])