Scala归并排序解析

来源:互联网 发布:python 中英文对照 编辑:程序博客网 时间:2024/05/22 13:03

一、源代码

def msort[T](xs:List[T])(lt: (T,T) => Boolen):List[T]={val n = xs.length  / 2if (  n == 0 ) xselse{def merge(xs: List[T],ys: List[T]):List[T] = (xs, ys) match{case(Nil, ys) => yscase(xs, Nil) => xscase(x:: xs1,y:: ys1)=>if(lt(x,y)) x::merge(xs1,ys)else y:: merge(xs,ys1)}val (fst,snd) = xs splitAt nmerge(msort(fst)(lt),msort(snd)(lt))}}

源代码来自Coursera 《Scala函数式编程原理》

其中,msort函数的第二个参数——lt: (T,T) => Boolen,它是一个自定义的谓词比较方法,用于比较T类型对象的大小,这里不做讨论。

二、示例

List元素:ls : List[Int]={7,4,15,43,9}

msort({7,4,15,43,9})merge(msort({7,4,15}),msort({43,9}))对于msort({7,4,15})的递归=>merge(msort({7,4}),msort({15}))对于msort({7,4})的递归=>merge(msort({7}),msort({4}))=>merge(7,4)对于msort({43,9})的递归=>merge(msort({43}),msort({9}))=>merge(43,9)merge(merge(msort({7,4}),msort({15})),merge(msort({43}),msort({9})))merge(merge(merge(msort({7}),msort({4})),15),merge(43,9))merge(merge(merge(7,4),15),merge(43,9))//这是一系列的拆分过程


拆分的图示:


上面是一个拆分过程,之后进行列表的两两合并:


每次合并后,都会形成有序的列表,所以问题转化成了——对两个有序的列表进行排序。回顾merge函数,它借用msort对参数进行分解。也就是说merge函数的两个列表参数一定是有序的——在merge函数体内,就是对两个列表有序列表进行合并排序的过程。


三、原理

1.将待排序的列表拆分成包含单个元素的列表

2.拆分的列表元素列表两两合并并排序,直到合并成一个列表。


四、递归函数的输入和输出

1. msort函数:传入一个待排序列表,输出一个排序后的列表。

2.merge函数:传入两个有序的列表,输出一个有序的列表。


五、递归的解释

程序中出现的递归有这几处:

1.merge函数的参数使用msort做了拆分的递归操作。

2.merge对两个参数进行排序使用了merge函数。这里的递归更像一种功能的重用——合并两个有序列表的功能。

递归的退出条件:

1.msort函数:待排序的列表只有一个元素或者为空列表

2.merge函数:两个参数中有一个为空列表

递归部分的处理:

msort使用merge函数返回一个有序列表

merge使用merge函数自身将两个有序列表进行合并

很明显,递归交由merge函数处理,也就是说,merge能够达到自身退出递归的条件—— 一直调用merge函数会形成,参数中只有一个列表的情况。所以,这里的msort函数只是提供了一个拆分的功能——辅助merge函数,将一个列表折半成两个列表的功能。

目前为止,重点就是merge函数合并两个有序列表的方法,这里通过提取出最小的一个元素,并merge剩下的元素来缩减,针对{4,7,15}和{9,43}的merge函数的递归合并过程如下图:


这就实现了对两个有序列表进行排序的过程。对于归并排序的总结就是两点:

1.使用msort对待排序的列表进行拆分,直到形成含单个元素的列表。

2.使用merge对两个有序列表进行合并,直到形成一个列表为止。

1 0
原创粉丝点击