上接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(排序)方法源码解析(二)的更多相关文章
-
erlang下lists模块sort(排序)方法源码解析(一)
排序算法一直是各种语言最简单也是最复杂的算法,例如十大经典排序算法(动图演示)里面讲的那样 第一次看lists的sort方法的时候,蒙了,几百行的代码,我心想要这么复杂么(因为C语言的冒泡排序我记得不 ...
-
Mybatis源码解析(二) —— 加载 Configuration
Mybatis源码解析(二) -- 加载 Configuration 正如上文所看到的 Configuration 对象保存了所有Mybatis的配置信息,也就是说mybatis-config. ...
-
RxJava2源码解析(二)
title: RxJava2源码解析(二) categories: 源码解析 tags: 源码解析 rxJava2 前言 本篇主要解析RxJava的线程切换的原理实现 subscribeOn 首先, ...
-
Sentinel源码解析二(Slot总览)
写在前面 本文继续来分析Sentinel的源码,上篇文章对Sentinel的调用过程做了深入分析,主要涉及到了两个概念:插槽链和Node节点.那么接下来我们就根据插槽链的调用关系来依次分析每个插槽(s ...
-
TreeSet集合的add()方法源码解析(01.Integer自然排序)
>TreeSet集合使用实例 >TreeSet集合的红黑树 存储与取出(图) >TreeSet的add()方法源码 TreeSet集合使用实例 package cn.itca ...
-
jQuery 源码解析二:jQuery.fn.extend=jQuery.extend 方法探究
终于动笔开始 jQuery 源码解析第二篇,写文章还真是有难度,要把自已懂的表述清楚,要让别人听懂真的不是一见易事. 在 jQuery 源码解析一:jQuery 类库整体架构设计解析 一文,大致描述了 ...
-
解析jQuery中extend方法--源码解析以及递归的过程《二》
源码解析 在解析代码之前,首先要了解extend函数要解决什么问题,以及传入不同的参数,会达到怎样的效果.extend函数内部处理传入的不同参数,返回处理后的对象. extend函数用来扩展对象,增加 ...
-
Spring源码解析二:IOC容器初始化过程详解
IOC容器初始化分为三个步骤,分别是: 1.Resource定位,即BeanDefinition的资源定位. 2.BeanDefinition的载入 3.向IOC容器注册BeanDefinition ...
-
ArrayList源码解析(二)
欢迎转载,转载烦请注明出处,谢谢. https://www.cnblogs.com/sx-wuyj/p/11177257.html 自己学习ArrayList源码的一些心得记录. 继续上一篇,Arra ...
随机推荐
-
MySQL 主主复制
200 ? "200px" : this.width)!important;} --> 介绍 环境 OS:CentOS 6.7,MySQL 5.6 Master:192.16 ...
-
AD认证
这两天接触到一个新的知识点,AD验证.什么是AD验证?Active Directory——活动目录,活动目录只是LDAP的一个实现,提供LDAP认证.Radius认证和NTML认证,都是标准认证方式 ...
-
uva 10061 How many zero&#39;s and how many digits ?
How many zeros and how many digits? Input: standard input Output: standard output Given a decimal in ...
-
JVM学习之堆和栈
Java栈与堆 1. 栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方.与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆. 2. 栈的优势是,存取速度比堆要快, ...
-
css3选择器总结--强大如jquery
最近发现,阿里的笔试考了许多css3的知识,像query media.box-flex等等.主要是移动浏览器的开发,让html5和css3如虎添翼,再也不用担心兼容了.so总结一下css3的选择器: ...
-
VMware workstation批量创建虚拟机和自动化安装操作系统(一)
一. 简述 作为从事IT行业运维工作的Linuxer,大多情况下需要在测试环境中部署业务系统并进行测试,在没有足够的计算存储网络条件下,使用虚拟机进行虚拟集群的创建和使用,是一种不错的学习和实践方式. ...
-
servlet文件上传及下载
servlet3.0中提供了对文件上传的直接支持,不需要借助任何第三方上传组件,直接使用Servlet3.0提供的API就能够实现文件上传功能. servlet 代码: package ni.jun. ...
-
python-基于tcp协议的套接字(加强版)及粘包问题
一.基于tcp协议的套接字(通信循环+链接循环) 服务端应该遵循: 1.绑定一个固定的ip和port 2.一直对外提供服务,稳定运行 3.能够支持并发 基础版套接字: from socket impo ...
-
论文笔记:Improving Deep Visual Representation for Person Re-identification by Global and Local Image-language Association
Improving Deep Visual Representation for Person Re-identification by Global and Local Image-language ...
-
Dell Technology Summit(2018.10.17)
时间:2018.10.17地点:北京国家会议中心