Несмотря на запоздание, вот версия, которая должна не утекать так много места (и, кажется, работает примерно в два раза быстрее, чем другая трехсторонняя версия здесь):
qsort3 xs = go xs []
where
go (x:xs) zs = part x xs zs [] [] []
go [] zs = zs
part x [] zs a b c = go a ((x : b) ++ go c zs)
part x (y:ys) zs a b c =
case compare y x of
LT -> part x ys zs (y:a) b c
EQ -> part x ys zs a (y:b) c
GT -> part x ys zs a b (y:c)
Это устраняет возможную проблему с использованием кортежей, где let (a,b) = ...
фактически преобразуется в let t= ...; a=fst t; b=snd t
, что приводит к ситуации, когда даже после того, как a
было использовано и обработано, он все еще остается живым как часть кортежа t
для чтения b
. от него - хотя конечно совершенно ненужного. Это известно как «проблема утечки парного пространства Вадлера». Или, может быть, GHC (с -O2
) умнее этого. :)
Также здесь явно используется подход списки различий (спасибо, hammar), что также делает его немного более эффективным (примерно в два раза быстрее, чем версия, использующая кортежи). Я думаю, что part
использует параметры аккумулятора, так как строит их в обратном порядке.
person
Will Ness
schedule
03.03.2012
O(n lg n)
... - person Etienne de Martel   schedule 04.10.2011O(3n log n) == O(n log n)
поэтому сложность времени выполнения одинакова (фактическое время выполнения может быть не таким же, но это отличается от сложности). - person ivanm   schedule 04.10.2011