scala实现快排,归并,冒泡,二分查找

这篇博客详细介绍了四种经典算法在Scala中的实现:快速排序、归并排序、冒泡排序和二分查找。快速排序和归并排序的时间复杂度为O(nlog(n)),冒泡排序为O(n^2),而二分查找的时间复杂度为O(log2n)。对于每种算法,文章都阐述了其核心思想,并提供了相应的Scala代码示例。

快速排序

思想

快速排序使用分治的思想,选定一个基准点,通过一趟排序将待排序的序列分为左右两个部分,其中左边的部分都比基准点要小,右边的基准点都比基准点要大,之后在分别对左右两边的部分,按照相同的思想继续切分,最终达到一个有序队列的目的

复杂度

时间复杂度:O(nlog(n))
空间复杂度:O(log(n))

scala代码实现

  def quickSort(list: List[Int]): List[Int] = {
    list match {
      case Nil => Nil
      case List() => List()
      case (head :: tail) => {
        val (l, r) = tail.partition(_ < head)
        quickSort(l) ::: head :: quickSort(r)
      }
    }
  }

归并排序

思想

归并排序就是将两个无序的列表合并一个有序列表,通过不断的切分列表知道剩下一个元素,在进行合并,最终形成有序列表

复杂度

时间复杂度:O(nlog(n))
空间复杂度:O(n)

scala代码实现

  def mergedSort[T](less:(T,T)=>Boolean)(list:List[T]):List[T] = {
    def merged(xList: List[T], yList: List[T]): List[T] = {
      (xList,yList) match{
        case (Nil,_) => yList
        case (_,Nil) => xList
        case (x::xTail,y::yTail) =>{
          if(less(x,y)) x::merged(xTail,yList)
          else
            y::merged(xList,yTail)
        }
      }
    }

    val n = list.length/2
    if(n == 0) list
    else {
      val (x,y) = list.splitAt(n)
      merged(mergedSort(less)(x),mergedSort(less)(y))
    }
  }

冒泡排序

思想

冒泡排序是一种交换排序,从无序队列的头部开始,按照指定的排序规则,相邻元素两两比较,满足条件则进行交换位置,达到实现有序队列的目的。

复杂度

时间复杂度:O(n^2)
空间复杂度:O(1)

scala代码实现

  def compute(data: Int, list: List[Int]):List[Int] = {
    list match {
      case List() => List(data)
      case head::tail => if(head < data) head::compute(data,tail) else data::list
    }
  }

  def bubbleSort(list:List[Int]):List[Int] = list match {
    case List() => List()
    case head::tail => compute(head,bubbleSort(tail))
  }

二分查找

思想

二分查找也叫折半查找,实现二分查找是必须建立在已经排好序的数组上,先将要查找的值跟中间值做比较,如果比中间值小,就从左半边的数组继续查找,如果比中间值打就从右半边的数组中查找。

优点

查找次数少,查找速度快,平均性能好

缺点

要求待查找数组必须是已经排好序的列表,且插入删除困难
因此二分查找使用与不经常变动但经常查找的列表

复杂度

时间复杂度:O(log2n)
空间复杂度:O(1)

实现

 def binarySearch2(array: Array[Int], l: Int, r: Int, findVal: Int): ArrayBuffer[Int] = {
    if (r < l) {
      return ArrayBuffer()
    }
    val midIndex = (l + r) / 2
    val midVal = array(midIndex)
    if (midVal > findVal) {
      binarySearch2(array, l, midIndex, findVal)
    } else if (midVal < findVal) {
      binarySearch2(array, midIndex, r, findVal)
    } else {
      println(s"midIndex=${midIndex}")
      val resArr = ArrayBuffer[Int]()
      var temp = midIndex - 1
      Breaks.breakable {
        while (true) {
          if (temp < 0 || array(temp) != findVal) {
            Breaks.break()
          }
          if (array(temp) == findVal) {
            resArr.append(temp)
          }
          temp -= 1
        }
      }
      resArr.append(midIndex)
      temp = midIndex + 1
      Breaks.breakable {
        while (true) {
          if (temp > array.length - 1 || array(temp) != findVal) {
            Breaks.break()
          }
          if (array(temp) == findVal) {
            resArr.append(temp)
          }
          temp += 1
        }
      }
      return resArr
    }

  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值