Scala冒泡排序解析

递归形式的冒泡排序(一),原代码链接

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结合,能够实现对一个列表进行排序。







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值