码蚁儿

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

冒泡排序是比较简单的一种排序算法,

基本原理是依次比较两个相邻的元素,如果两个元素的顺序错误,则交换两个元素的位置,

算法流程图如下:

 

 

 对照流程图,用erlang代码实现:

 1 bubble([]) ->
 2     [];
 3 bubble([H]) ->
 4     [H];
 5 bubble([H | T]) ->
 6     bubble1(T, H, [], []).
 7 
 8 bubble1([], H, [], R) ->
 9     [H | R];
10 bubble1([], H, TailList, R) ->%%一轮结束,把最终的元素放在结果中,开始下一轮
11     [NewH | T] = lists:reverse(TailList),
12     bubble1(T, NewH, [], [H | R]);
13 bubble1([H1 | T], H, TailList, R) ->
14     if
15         H1 >= H ->
16             bubble1(T, H, [H1 | TailList], R);
17         true ->
18             bubble1(T, H1, [H | TailList], R)
19     end.

%%第二种方式

bb([]) ->
  [];
bb([H]) ->
  [H];
bb(L) ->
  Tuple = list_to_tuple(L),
  Len = erlang:size(Tuple),
  bb_(Tuple, Len, 1).

bb_(Tuple, 1, _) ->
  Tuple;
bb_(Tuple, L1, L1) ->
  bb_(Tuple, L1 - 1, 1);
bb_(Tuple, L1, L2) ->
  E1 = element(L2, Tuple),
  E2 = element(L2 + 1, Tuple),
  if
    E1 > E2 ->
    Tup1 = erlang:setelement(L2, Tuple, E2),
    Tup = erlang:setelement(L2 + 1, Tup1, E1),
    bb_(Tup, L1, L2 + 1);
  true ->
    bb_(Tuple, L1, L2 + 1)
  end.

观察上面的代码可以看到,每遍历一次元素(冒一次泡泡),就要对'尾巴(TailList)'做一次逆序,实际上是不需要的,这一点可以优化以节约开销

 1 bubble([]) ->
 2     [];
 3 bubble([H]) ->
 4     [H];
 5 bubble([H | T]) ->
 6     bubble1(T, H, [], []).
 7 
 8 
 9 bubble1([], H, [], R) ->
10     [H | R];
11 bubble1([], H, [NewH | T], R) ->%%一轮结束,把最终的元素放在结果中,开始下一轮
12     bubble1(T, NewH, [], [H | R]);
13 bubble1([H1 | T], H, TailList, R) ->
14     if
15         H1 >= H ->
16             bubble1(T, H, [H1 | TailList], R);
17         true ->
18             bubble1(T, H1, [H | TailList], R)
19     end.

 ps.网上还有一种通过增加标志位来降低时间复杂度的算法,回头有时间再来折腾

posted on 2020-11-20 09:59  码蚁儿  阅读(263)  评论(0)    收藏  举报