Erlang中的MergeSort和Quicksort无法正常工作

时间:2016-06-08 15:20:59

标签: erlang

有人可以帮我弄清楚我的排序算法有什么问题。我没有错误,但陷入某种无限循环。这些功能似乎单独起作用。

msort([])->
    [];
msort(L)->
    {L3, L4} =  msplit(L, [],[]),
    merge(msort(L3), msort(L4)).

msplit([], L1, L2)->
    {L1, L2};
msplit([H|[]], L1, L2)->
    msplit([], [H]++L1, L2);
msplit([H|[H2|T]], A, B)->
    msplit(T, A++[H], B++[H2]).

merge(L, [])->L;
merge([], R)->R;
merge([H1|T1], [H2|T2])-> 
    if H1 < H2
         -> [H1|merge(T1, [H2|T2])];
       true-> [H2|merge([H1|T1], T2)] 
    end.

qsort([])->[];
qsort([H|T])-> 
    {A, B} =qsplit(T, H, [], []),
    Small =qsort(A),
    Large = qsort(B),
    lists:append(Small,Large).

qsplit([], H, A, B)->
    {A++[H], B};
qsplit([H|T], P, A, B)->
    if H > P->
           qsplit(T, P, A++[H], B);
       true-> qsplit(T, P, A, B++[H])
    end.

经过一些更改后,代码正常运行:

msort([]) ->
        [];
msort([_] = L) ->
    L;
msort(L)->
    {L3, L4} =  msplit(L, [],[]),
    merge(msort(L3), msort(L4)).

msplit([], L1, L2)->
    {L1, L2};
msplit([H|[]], L1, L2)->
    msplit([], [H|L1], L2);
msplit([H|[H2|T]], A, B)->
    msplit(T, [H|A], [H2|B]).

merge(L, [])->L;
merge([], R)->R;
merge([H1|T1], [H2|T2])-> 
    if H1 < H2
         -> [H1|merge(T1, [H2|T2])];
       true-> [H2|merge([H1|T1], T2)] 
    end.

qsort([])->[];
qsort([_] = L)->L;
qsort([H|T])-> 
    {A, B} =qsplit(T, H, [], []),
    Large =qsort(A),
    Small = qsort(B),
    lists:append(Small,[H|Large]).

qsplit([], _, A, B)->
    {A, B};
qsplit([H|T], P, A, B)->
    if H > P->
           qsplit(T, P, [H|A], B);
       true-> qsplit(T, P, A, [H|B])
    end.

1 个答案:

答案 0 :(得分:1)

如果您使用仅包含一个msort/1项的列表来致电[X],则msplit/1将返回{[X], []},其中您使用msort/1调用[X] msort/1 }} 等等。您可以通过添加msort([])-> []; msort([_] = L) -> L; msort(L)-> ... 函数子句来修复它:

qsort/1

类似的问题出现在A++[H]

您的代码中存在更多问题。您应该将所有[H] ++ A替换为[H|A],这更好地写为[H, H2 | T]。它对代码的效率有很大影响。您可以使用[H | [H2 | T]]代替{{1}},这是一个很好的语法糖,有助于提高可读性。