Scala 实现快速排序和归并排序

def quickSort1(array: Array[Int]): Array[Int] = {
  def swap(x: Int, y: Int): Unit = {
    val tmp = array(x)
    array(x) = array(y)
    array(y) = tmp
  }
  def qSort(l: Int, r: Int) {
    if (l < r) {
      var m = l
      for (i <- l + 1 to r) {
        if (array(i) < array(l)) {
          m += 1
          swap(i, m)
        }
      }
      swap(l, m)
      qSort(l, m - 1)
      qSort(m + 1, r)
    }
  }
  qSort(0, array.length - 1)
  array
}

def quickSort2(array: Array[Int]): Array[Int] = {
  if(array.isEmpty) array
  else {
    val m = array(0)
    Array.concat(
      quickSort2(array.filter(_ < m)),
      array.filter(_ == m),
      quickSort2(array.filter(_ > m))
    )
  }
}

def mergeSort(list: List[Int]): List[Int] = {
  def merge(l: List[Int], r: List[Int]): List[Int] =
    (l, r) match {
      case (Nil, _) => r
      case (_, Nil) => l
      case (x :: xl, y :: yr) =>
        if(x < y) x :: merge(xl, r)
        else y :: merge(l, yr)
    }
  val n = list.length / 2
  if(n == 0) list
  else {
    val (l, r) = list splitAt n
    merge(mergeSort(l), mergeSort(r))
  }
}

import java.util.Date
import scala.util.Random

val array = Random.shuffle(1 to 3000).toArray

val list = array.toList

// quickSort1:
val start = new Date().getTime
val array1 = quickSort1(array.clone)
println("quickSort1: " + (new Date().getTime - start) + " ms")

// quickSort2:
val start2 = new Date().getTime
val array2 = quickSort2(array.clone)
println("quickSort2: " + (new Date().getTime - start2) + " ms")

// mergeSort:
val start3 = new Date().getTime
val list3 = mergeSort(list)
println("mergeSort: " + (new Date().getTime - start3) + " ms")
val array3 = list3.toArray

println("Equal? array1 array2   " + array1.sameElements(array2))
println("Equal? array1 array3   " + array1.sameElements(array3))

Output:

quickSort1: 23 ms
quickSort2: 61 ms
mergeSort: 24 ms
Equal? array1 array2   true
Equal? array1 array3   true

可以发现快速排序的第一种实现和归并排序的效率几乎相同。

而快速排序的第二种实现则要稍慢,但是更加简洁和直观。

观察第二种实现可以发现,它没有改变原来的数组,而是通过 \(filter\) 函数直接得到新的数组,再通过 \(concat\) 函数把它们的返回值合并起来。所以算法的效率有所降低。

posted @ 2017-10-04 15:51  ftae  阅读(491)  评论(0编辑  收藏  举报