问题描述
|
我正在学习Erlang并决定在其中实现气泡排序,这花了我一些精力,结果我成功了,但是我发现我的思维方式不正确,是否有更有效的方法实现它?
bubble_sort(L) ->
if
length(L) > 1 ->
SL=bubble_sort_p(L),bubble_sort(lists:sublist(SL,1,length(SL)-1)) ++ [lists:last(SL)];
true -> L
end.
bubble_sort_p([]) -> [];
bubble_sort_p([F | R]) ->
case length(R) > 0 of
true -> case F > hd(R) of
true -> [hd(R)] ++ bubble_sort_p([F|tl(R)]);
false -> [F] ++ bubble_sort_p([hd(R)|tl(R)])
end;
false -> [F]
end.
解决方法
请允许我以一种更具可读性的方式重写您的代码(无需更改任何语义):
bubble_sort(L) when length(L) =< 1 ->
L;
bubble_sort(L) ->
SL = bubble_sort_p(L),bubble_sort(lists:sublist(SL,1,length(SL)-1)) ++ [lists:last(SL)].
bubble_sort_p([]) ->
[];
bubble_sort_p([F]) ->
[F];
bubble_sort_p([F,G|T]) when F > G ->
[G|bubble_sort_p([F|T])];
bubble_sort_p([F,G|T]) ->
[F|bubble_sort_p([G|T])].
这样应该可以更轻松地考虑程序中实际发生的事情。
,从我的头开始的实现是:
bubble_sort(L) -> bubble_sort(L,[],false).
bubble_sort([A,B | T],Acc,_) when A > B ->
bubble_sort([A | T],[B | Acc],true);
bubble_sort([A,Tainted) ->
bubble_sort([B | T],[A | Acc],Tainted);
bubble_sort([A | T],Tainted) ->
bubble_sort(T,Tainted);
bubble_sort([],true) ->
bubble_sort(lists:reverse(Acc));
bubble_sort([],false) ->
lists:reverse(Acc).
如果我们在谈论效率,那么我们就不应该首先进行泡沫排序。
,并雇用lists:foldr
:
bubble(List) ->
Step = fun
(E,{S,[]}) -> {S,[E]};
(E,{_,[X|XS]}) when E > X -> {swapped,[X|[E|XS]]};
(E,XS}) -> {S,[E|XS]}
end,case lists:foldr(Step,{intact,[]},List) of
{intact,XS} -> XS;
{swapped,XS} -> bubble(XS)
end.
,在http://en.literateprograms.org/Bubble_sort_%28Erlang%29有一个答案
-module(bubblesort).
-export([sort/1]).
-import(lists,[reverse/1]).
sort(L) -> sort(L,true).
sort([],L,true) -> reverse(L);
sort([],false) -> sort(reverse(L),true);
sort([ X,Y | T ],_) when X > Y ->
sort([ X | T ],[ Y | L ],false);
sort([ X | T ],Halt) -> sort(T,[ X | L ],Halt).
排序2,4,3,5,1的示例
排序([2,1])
第1轮
=>排序([2,1],[],true)
=>排序([4,1],[2],是)
=>排序([4,1],[3,2],假)
=>排序([5,1],[4,2],假)
=>排序([5],[1,2],假)
=> sort([],[5,2],false)
=>排序([2,5],[],true)
第二轮
=>排序([3,5],[2],是)
=>排序([4,5],[3,2],是)
=>排序([4,5],[1,2],假)
=>排序([5],[4、1、3、2],否)
=> sort([],[5,5],[],true)
第三回合
=>排序([3,5],[2],是)
=>排序([3,2],假)
=>排序([4,2],假)
=>排序([5],[4,5],真)
第四回合
=>排序([2,5],[1],否)
=>排序([3,5],[2,1],假)
=>排序([4,2,1],假)
=>排序([5],[4,1],假)
=> sort([],[5,1],false)
=>排序([1,5],[],是)
第五回合
=>排序([2,5],[1],是)
=>排序([3,1],是)
=>排序([4,1],是)
=>排序([5],[4,1],true)
=> sort([],[5,1],true)
=> [1,5]
,-module(bubbleSort).
-compile(export_all).
-include_lib(\"eunit/include/eunit.hrl\").
sort(L) ->
sort(L,length(L),[]).
sort(_L,_Res) -> [];
sort([H | _T],Res) -> [H | Res];
sort(L,Len,Res) ->
T1 = lists:sublist(L,Len),T2 = inner_sort(T1,[]),Last = lists:last(T2),sort(T2,Len - 1,[Last | Res]).
inner_sort([A,B],Res) when (A < B)->
Res ++ [A,B];
inner_sort([A,Res) ->
Res ++ [B,A];
inner_sort([A,Res) when (A < B) ->
inner_sort([B | T],Res ++ [A]);
inner_sort([A,Res) ->
inner_sort([A | T],Res ++ [B]).
test()->
L = [5,-1,10,6,100,99],?assert(sort([]) =:= []),?assert(sort([1]) =:= [1]),?assert(sort([1,4]) =:= [1,4]),?assert(sort([10,1]) =:= [1,10]),?assert(sort(L) =:= [-1,99,100]).
,易于阅读和理解的实现方式,带有递增的排序方向。
采用尾递归,计算复杂度和内存使用情况很经典。
bsort([]) -> [];
bsort([H|T]) -> bsort([H|T],[]).
bsort([],[]) -> [];
bsort([],[H|T]) -> [H|T];
bsort([A|B],Sorted) when is_list(Sorted) -> M = lists:max([A|B]),bsort([A|B] -- [M],[M] ++ Sorted).