If you're interested, here's my prolog code:
% partition(Pivot, List, LL, RL).
quick_sort([], []).
quick_sort([H|T], SL) :-
qs_partition(H, T, LL, RL),
quick_sort(LL, SLL),
quick_sort(RL, SRL),
append(SLL, [H|SRL], SL).
qs_partition(_, [], [], []).
qs_partition(Pivot, [H|T], [H|LL], RL) :-
H #< Pivot,
qs_partition(Pivot, T, LL, RL).
qs_partition(Pivot, [H|T], LL, [H|RL]) :-
H #>= Pivot,
qs_partition(Pivot, T, LL, RL).
More at github.com/PeterBadzhakov/Prolog
Read left to right, top to bottom.
X :- A, B, C .... is "Predicate (functor) X is True if predicate A is true and predicate B is true ..."
Therefore,
A sequence with first element H(ead) and all the rest T(ail) becomes sorted sequence SL (sorted list), if:
>by partitioning the T(ail) with the pivot H(ead), we receive LL (left list) and RL (right list)
and
>LL and RL are sorted into respectively SLL and SRL
and
>by getting SLL, adding the pivot H to it and the SRL, we receive the SL (sorted list) we long for
Very simple indeed. You simply repeat the algorithm but in mathematics. Cause and effect - say what happens to which elements, the program does the 'how'. Don't fiddle around with pointers and weird swap functions.