上接erlang下lists模块sort(排序)方法源码解析(一),到目前为止,list列表已经被分割成N个列表,而且每个列表的元素是有序的(从大到小)

下面我们重点来看看mergel和rmergel模块,因为我们先前主要分析的split_1_*对应的是rmergel,我们先从rmergel查看,如下

.......................................................

split_1(X, Y, [], R, Rs) ->
   rmergel([[Y, X | R] | Rs], []).

.......................................................
split_1_1(X, Y, [], R, Rs, S) ->
rmergel([[S], [Y, X | R] | Rs], []).
.............................................................

rmergel的代码比较多,看一下发现其实思路非常清晰,

 rmergel([[H3 | T3], [H2 | T2], T1 | L], Acc) ->
rmergel(L, [rmerge3_1(T1, [], H2, T2, H3, T3) | Acc]);
rmergel([[H2 | T2], T1], Acc) ->
mergel([rmerge2_1(T1, H2, T2, []) | Acc], []);
rmergel([L], Acc) ->
mergel([lists:reverse(L, []) | Acc], []);
rmergel([], Acc) ->
mergel(Acc, []).

当列表的个数>=3超过就用拿3个进行比较合并rmerge3_1实现,把这3个列表拼成1个有序的列表(拼完成了从小到大);剩下的按照这个逻辑

当然列表=2就拿2个进行比较合并rmerge2_1实现,把这2个列表拼成1个有序的列表(拼完成了从小到大)

当列表只有1个的时候,这个列表就是有序的了

整个逻辑是这样的,当列表大于等于2个,先调用rmerge3_1,如果H1>=H2就调用rmerge3_21,否则就调用rmerge3_12,然后rmerge3_21如果H3>=H1就说明H3最大,然后继续比较

总得来说,就是把3个列表的第一个元素拿出来,比较,最大的放变量M里面,根据比较的顺序不同,使用不同的函数。

按照这个理解,复杂程度应该是log3n*n不是先前理解的n,

可是这里不能理解的是为什么要拿3个来比较,

我按照一次拿2个的逻辑来写,代码就简单很多,可是运行的时间差不多是原作者的的1.5-2倍,实在不能理解

附上我一次拿2个列表的逻辑代码

my_rmerge([H1,H2|T], R) ->
my_rmerge(T, [my_rmerge2(H1, H2, [])|R]);
my_rmerge([H1], R) ->
my_merge([lists:reverse(H1)|R], []);
my_rmerge([], [R]) ->
R;
my_rmerge([], R) ->
my_merge(R, []). my_rmerge2([H1|T1],[H2|T2], List) when H2 >= H1 ->
([H1|T1], T2, [H2|List]);
my_rmerge2([H1|T1],[H2|T2], List) ->
my_rmerge2(T1, [H2|T2], [H1|List]);
my_rmerge2([], L2, List) ->
lists:reverse(L2, List);
my_rmerge2(L1, [], List) ->
lists:reverse(L1, List). my_merge([H1,H2|T], R) ->
my_merge(T, [my_merge2(H1, H2, [])|R]);
my_merge([H1], R) ->
my_rmerge([lists:reverse(H1)|R], []);
my_merge([], [R]) ->
lists:reverse(R);
my_merge([], R) ->
my_rmerge(R, []). my_merge2([H1|T1],[H2|T2], List) when H2 < H1 ->
my_merge2([H1|T1], T2, [H2|List]);
my_merge2([H1|T1],[H2|T2], List) ->
my_merge2(T1, [H2|T2], [H1|List]);
my_merge2([], L2, List) ->
lists:reverse(L2, List);
my_merge2(L1, [], List) ->
lists:reverse(L1, List).

查看对比结果

 > timer:tc(tt1, mysort, [B2]).
{,
[,,,,,,,,,,,,,,,,,,,,,,
,,,,|...]}
> timer:tc(tt1, mysort, [B2]).
{,
[,,,,,,,,,,,,,,,,,,,,,,
,,,,|...]}
> timer:tc(lists, sort, [B2]).
{,
[,,,,,,,,,,,,,,,,,,,,,,
,,,,|...]}
> timer:tc(lists, sort, [B2]).
{,
[,,,,,,,,,,,,,,,,,,,,,,
,,,,|...]}

B2是一个1到100000的乱序列表,为什么差别会这么大,

有没有大神解释一下,按这样的逻辑,如果一次拿4个是不是更块,代码当然更多~~~

erlang下lists模块sort(排序)方法源码解析(二)的更多相关文章

  1. erlang下lists模块sort(排序)方法源码解析(一)

    排序算法一直是各种语言最简单也是最复杂的算法,例如十大经典排序算法(动图演示)里面讲的那样 第一次看lists的sort方法的时候,蒙了,几百行的代码,我心想要这么复杂么(因为C语言的冒泡排序我记得不 ...

  2. Mybatis源码解析(二) —— 加载 Configuration

    Mybatis源码解析(二) -- 加载 Configuration    正如上文所看到的 Configuration 对象保存了所有Mybatis的配置信息,也就是说mybatis-config. ...

  3. RxJava2源码解析(二)

    title: RxJava2源码解析(二) categories: 源码解析 tags: 源码解析 rxJava2 前言 本篇主要解析RxJava的线程切换的原理实现 subscribeOn 首先, ...

  4. Sentinel源码解析二(Slot总览)

    写在前面 本文继续来分析Sentinel的源码,上篇文章对Sentinel的调用过程做了深入分析,主要涉及到了两个概念:插槽链和Node节点.那么接下来我们就根据插槽链的调用关系来依次分析每个插槽(s ...

  5. TreeSet集合的add()方法源码解析(01.Integer自然排序)

    >TreeSet集合使用实例 >TreeSet集合的红黑树 存储与取出(图) >TreeSet的add()方法源码     TreeSet集合使用实例 package cn.itca ...

  6. jQuery 源码解析二:jQuery.fn.extend=jQuery.extend 方法探究

    终于动笔开始 jQuery 源码解析第二篇,写文章还真是有难度,要把自已懂的表述清楚,要让别人听懂真的不是一见易事. 在 jQuery 源码解析一:jQuery 类库整体架构设计解析 一文,大致描述了 ...

  7. 解析jQuery中extend方法--源码解析以及递归的过程《二》

    源码解析 在解析代码之前,首先要了解extend函数要解决什么问题,以及传入不同的参数,会达到怎样的效果.extend函数内部处理传入的不同参数,返回处理后的对象. extend函数用来扩展对象,增加 ...

  8. Spring源码解析二:IOC容器初始化过程详解

    IOC容器初始化分为三个步骤,分别是: 1.Resource定位,即BeanDefinition的资源定位. 2.BeanDefinition的载入 3.向IOC容器注册BeanDefinition ...

  9. ArrayList源码解析(二)

    欢迎转载,转载烦请注明出处,谢谢. https://www.cnblogs.com/sx-wuyj/p/11177257.html 自己学习ArrayList源码的一些心得记录. 继续上一篇,Arra ...

随机推荐

  1. 工具方法: jQuery.方法() $.extend (小计)

    $.extend(布尔值,目标对象,合并对象,……)                布尔值 : true,深拷贝(递归拷贝)   false,浅拷贝(非递归拷贝)                   ...

  2. CASE WHEN 及 SELECT CASE WHEN的用法

    CASE WHEN 及 SELECT CASE WHEN的用法 Case具有两种格式.简单Case函数和Case搜索函数. 简单Case函数 CASE sex WHEN '1' THEN '男' WH ...

  3. Docker 共有 13 个管理命令和 41 个通用命令,以下是常用 Docker 命令列表

    开发人员一直在努力提高 Docker 的使用率和性能,命令也在不停变化.Docker 命令经常被弃用,或被替换为更新且更有效的命令,本文总结了近年来资深专家最常用的命令列表并给出部分使用方法. 目前, ...

  4. linux 邮件服务器—Extmail

    环境: Centos 6.5 :172.16.9.13 (DNS 服务器) Centos 6.5: 172.16.9.11 (postfix 邮件服务器) 安装软件: yum -y install p ...

  5. oracle 11g 安装步骤

    指定安装路径 输入数据库名(cwbpm),(按照自己要求输入,可以直接用默认库名) 输入密码(自定义):123456 (自定义密码) 下一步 选择“是” 点击完成,开始安装数据库 安装完成后会弹出页面 ...

  6. Python 字符串操作 starswitch() find() re.IGNORECASE replace() join()

    检测开头&结尾开头:startswith()url = 'http://www.python.org' url.startswith('http') >>>True 结尾:e ...

  7. Hadoop Mapreduce中wordcount 过程解析

    将文件split 文件1:                                                                   分割结果: hello  world   ...

  8. 关于eric4和pyqt的入门学习(转)

    在Eric4下用PyQt4编写Python的图形界面程序 转载请注明作者RunningOn 本文是PyQt4的入门教程.网上能搜到其它教程,但我觉得讲得不是很清楚,希望这篇文章对入门者更加有帮助. 先 ...

  9. sql 与 mysql 链接数据库

  10. 按下回车默认提交form表单问题

    最近开发中碰到一个问题,项目中有几个列表展示页面,允许用户通过查询条件模糊查询数据.用户录入关键字后点击回车会调用查询方法根据关键字查询,原先功能没有问题,但是最近发现在查询输入框中按下回车会直接刷新 ...