递归形式的冒泡排序(一),原代码链接:
def bubblesort[A <% Ordered[A]](list: List[A]): List[A] = {
def sort(as: List[A], bs: List[A]): List[A] =
if (as.isEmpty) bs
else bubble(as, Nil, bs)
def bubble(as: List[A], zs: List[A], bs: List[A]): List[A] = as match {
case h1 :: h2 :: t =>
if (h1 > h2) bubble(h1 :: t, h2 :: zs, bs)
else bubble(h2 :: t, h1 :: zs, bs)
case h1 :: Nil => sort(zs, h1 :: bs)
}
sort(list, Nil)
}
示例List(1,3,2)
一、堆栈分析
函数堆栈调用:
1 sort(List(1,3,2),Nil)2 bubble(List(1,3,2),Nil,Nil)
3 bubble(3::2,1::Nil,Nil)
4 bubble(3::Nil,2::1::Nil,Nil)
5 sort(2::1::Nil,3::Nil)//第一次冒泡结束,求出了最大值3::Nil。也是第二次冒泡的开始
6 bubble(2::1::Nil,Nil,3::Nil)
7 bubble(2::Nil,1::Nil,3::Nil)
8 sort(1::Nil,2::3::Nil)
9 bubble(1::Nil,Nil,2::3::Nil)
10 sort(Nil,1::2::3::Nil)
11 1::2::3::Nil
二、冒泡排序的算法在于两次嵌套的遍历
每次遍历可以看做一次递归——求出数列中最大值,用处理过的数列结果拼合数列的最大值。
1.sort函数
第一个参数为需要处理的列表
第二个参数为已处理过的列表
2.bubble函数
参数:
第一个参数为需要处理的列表
第二个参数为作为内部的递归使用,从堆栈中可以看出,在最后一次调用自身(第4,7,9行)的时候,返回了除去最大值以外的其他元素组成的列表
第三个参数,待拼合的列表
最后,退出自身的递归时,将as中的最大值拼合到bs的首部作为sort的已处理过的列表,将剩下的元素作为一个列表,进行一个冒泡处理。
三、递归实现
3.1对sort的理解
一个简单的理解在于:
组成递归的两个函数包含冒泡算法的【核心】:
1.sort函数能够将第一个参数的列表进行<sort冒泡排序>并且拼接到第二个参数中。
2.bubble函数能够找出第一个参数中的最大值和剩下的元素。
两个函数合作可以实现对一个列表的排序:
该代码中,bubble函数主动调用sort方法,把最大值拼合到sort函数的第二个参数(bs:List[A])中,然后只要将剩下的元素列表传给sort函数的第一个参数。
按照【核心】中对sort函数的描述,sort函数对第一个参数进行排序,并拼接到第二参数中。所以,就完成了排序。
上面的描述是建立在bubble函数【核心】能够实现的基础上。
3.2对bubble查找最大值递归行为的解释
bubble函数不仅要表示最大值,还要表示剩下的元素。所以bubble函数在 查找最大值 行为上的描述为:
1)先把bubble函数的第一个参数分成<第一个元素>,<第二个元素>,<剩下的元素>。
2)比较<第一个元素>和<第二个元素>和中较大的一个,把较小值和第二参数拼合为一个列表,把较大值和<剩下的元素>拼合到一起。
3)继续使用<bubble>查找到较小值和第二个参数拼合到一起。把较大值和<剩下的元素>拼合到一起。最后<剩下的元素>会有0个,这时候比较过程中较小的值在bubble的第二个参数中。之后先不管,总之,bubble函数能够找出最大值和剩下的元素。
这样就说明,bubble函数满足【核心】中声明的条件,和3.1结合,能够实现对一个列表进行排序。