Heapソート

昼飯行き損ねたので、ついでなのでヒープソート作ってみた。
これは簡単。。。だけど、かっこ悪い。

%% Author: tkuro
%% Created: 2009/11/12
%% Description: heap sort
-module(heap).

%%
%% Include files
%%
-include_lib("eunit/include/eunit.hrl").
%%
%% Exported Functions
%%
-export ([sort/1, swap/3]).

%% --------------------------------------------------------------------
%% Test Functions
%% --------------------------------------------------------------------

sort_test_() ->
        [
                ?_assertEqual(sort([1,3,2]),[1,2,3]),
                ?_assertEqual(sort([3,2,0,1,5,8,4,2,2,7]),[0,1,2,2,2,3,4,5,7,8])
        ].

%% --------------------------------------------------------------------
%% Func: sort/1
%% Returns: sorted list
%% --------------------------------------------------------------------

sort(L) ->
    walk_heap(make_heap(L)).

walk_heap(L) -> walk_heap(L, []).

walk_heap([A], Acc) -> [A|Acc];
walk_heap([H|T], Acc) ->
    walk_heap(make_heap(T), [H|Acc]).

make_heap(L) ->
    make_heap(L, (length(L)) div 2).

make_heap(L, 0) -> L;
make_heap(L, I) ->
    make_heap(build_down_heap(L, I), I-1).

build_down_heap(L, I)
when length(L) < I*2 -> L;
build_down_heap(L, I) ->
    P  = lists:nth(I, L),
    C  = 2*I,
    Ix = case length(L) > C of
        true  ->
            case lists:nth(C, L) > lists:nth(C+1, L)  of
                true -> C;
                false -> C+1
            end ;
        false -> C
    end,
    case (P > lists:nth(Ix, L)) of
        true -> build_down_heap(L, Ix);
        false-> build_down_heap(swap(L, I, Ix), Ix)
    end.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

swap(L, P1, P2) ->
    {V1, V2} = {[lists:nth(P1, L)], [lists:nth(P2, L)]},
    lists:sublist(L, P1-1) ++ V2 ++
    lists:sublist(L, P1+1, P2-P1-1) ++ V1 ++
    lists:nthtail(P2, L).

lists:swap/3みたいなのってないんでしょうか? 誰か教えて。
追記:間違えて途中のをアップしてしまってました。修正