erlang 实现并行快速排序

%在保证尾递归的情况下,使用一个辅助函数 handl 对parallel_qsort进行包装,则parallel_qsort只管 分发任务即可,计算好了 再进行树形通信合并,之前一直在纠%结于是不是要使用进程字典,来保存有哪些进程,进程字典,在erlang program一书中,不建议采用,因为其提供了共享数据的可能,破坏了erlang的设计原则,erlang是面向消息的语言,进行间通信只能通过消息。<pre name="code" class="plain">-module (parallel_qsort).
-export ([start/2,handle/5]).

% 测试数据
% parallel_qsort:start([11,3,2,8,9,4,10,23,45,100,15,0,-1,47,9,32,12,64,5,35,79,77,27,1,6,7],8).
% parallel_qsort:start([11,3,2,8,9,4,33,34,34,10,23,45,100,15,0,-1,47,9,32,12,64,5,35,79,77,27,1,6,7],8).

% 启动线程的工作
% 1.启动 各个执行线程
start (Data ,M) ->
    io:format("Len : ~w~n",[lists:flatlength(Data)]),
    spawn(?MODULE,handle,[Data,M,M,1,self()]).

% 包装parallel_qsort,和合并结果的操作
handle(Data,M,Processnum,Id,Master) -> 
    io:format("Id ~w~n",[Id]),
    {Pids,Res} = parallel_qsort(Data,M,Processnum,Id,Master,[self()]),
    merge_wait(Res,Master,Id,2,Processnum,Pids).

% 通过Id 判断 改发还是改接,Master 是要发给的进程 ,M是递归的轮数
merge_wait(Res,Master,Id,Judge,M,Pids) when M =:= 1 -> 
    io:format("result : ~w :~w ~n",[Res,lists:flatlength(Res)]);
merge_wait(Res,Master,Id,Judge,M,[Hid|Tids]) -> 
    if Id rem Judge =:= 1 ->
            receive
                {res,Hid,OtherRes} -> %不能判断接收的顺序
                    NewRes = lists:append(Res,OtherRes),
                    io:format("receive: ~w ~w ~n",[Id,NewRes]),
                    merge_wait(NewRes,Master,Id,Judge*2,M div 2,Tids)
            end;
        true ->
            io:format("send from ~w ~w ~n",[Id,Res]),
            Master ! {res,self(),Res}
    end.

% 划分 分发任务 
% 直到 列表很小或者M=0(没有单独核来跑进程) 串行排序
% 此时 将自己的结果和Id发回主线程
parallel_qsort(Data,M,Start,Id,Master,Pids) -> 
    Len = lists:flatlength(Data),
    if M =:= 1-> 
            NewData = lists:sort(Data),
            io:format("get ~w ~w ~n",[Id,NewData]),
            {Pids,NewData};
        true ->
            {FrontPart,BehindPart} = partition(Data),
            % io:format("~w:~w ~n",[FrontPart,BehindPart]),
            Pid = spawn(?MODULE,handle,[BehindPart,(M div 2),Start,Id+(M div 2),self()]),
            parallel_qsort(FrontPart,M div 2,Start,Id,Master,[Pid|Pids])
      end.

partition([]) -> {[],[]};
partition([H|T]) when T =:= []-> {[H],[]} ;
partition([H|T]) -> 
    {[X || X <- [H|T] , X =< H],[Y || Y <- T , Y > H]} .   

 
 

                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值