Scala 快速排序算法实现
Scala Quicksort algorithm implementation
我需要帮助来填补一些空白,以便分区在调用分区(数据、下层、上层)时工作。虽然,我认为 if 语句应该是 if (lower < upper-1) 以避免浪费调用。此外,sortRange 必须对范围 [lower,upper) 进行快速排序。我的问题是,在 def sort[A](data: Array[A])(...): Unit = {} 的 (...) 中必须包含什么才能使其正常工作以及如何交换被实施以使其适用于交换具有一系列整数的 Array[A]?
object Quicksort {
def partition[A](data: Array[A], lower: Int, upper: Int)
(implicit comp: Ordering[A]): Int = {
val pivot = data(upper-1)
var mid = lower-1
for (i <- lower until upper-1) {
if (comp.lteq(data(i),pivot)) {
mid += 1
swap(data,mid,i)
}
}
swap(data,mid+1,upper-1)
mid+1
}
def sort[A](data: Array[A])(...): Unit = {
def sortRange(data: Array[A], lower: Int, upper: Int):
Unit = {
if(lower < upper) {
val pivotIndex = partition(data,lower,upper)
sortRange(data,lower,pivotIndex)
sortRange(data,pivotIndex+1,upper)
}
}
sortRange(data,0,data.length)
}
def main(args: Array[String]) : Unit = {
//Result of partition(data,lower,upper):
//sortRange results in quick-sorting the range: [lower,upper)
}
}
由于 Quicksort 是一种就地排序算法(即它都是关于副作用的),而不是传递要排序的集合,我想将方法“附加”到所述集合。
我还想删除所有那些讨厌的可变变量。
implicit class QSort[A:Ordering](as: Array[A]) {
import Ordering.Implicits._
private def swap(x: Int, y: Int): Unit = {
val hold = as(x)
as(x) = as(y)
as(y) = hold
}
private def partition(lo: Int, hi: Int): Int =
((lo until hi).filter(as(_) < as(hi)) :+ hi)
.zipWithIndex.foldLeft(0){
case (_,(j,x)) => swap(j, lo+x); lo+x
}
private def quicksort(lo:Int, hi:Int): Unit =
if (lo < hi) {
val p = partition(lo, hi)
quicksort(lo, p-1)
quicksort(p+1, hi)
}
def qsort(): Unit = quicksort(0, as.length - 1)
}
测试:
val cs = Array('g','a','t','b','z','h')
cs.qsort() //: Unit
cs //: Array[Char] = Array(a, b, g, h, t, z)
val ns = Array(9,8,7,6,5,4,3,2,1)
ns.qsort() //: Unit
ns //: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9)
我需要帮助来填补一些空白,以便分区在调用分区(数据、下层、上层)时工作。虽然,我认为 if 语句应该是 if (lower < upper-1) 以避免浪费调用。此外,sortRange 必须对范围 [lower,upper) 进行快速排序。我的问题是,在 def sort[A](data: Array[A])(...): Unit = {} 的 (...) 中必须包含什么才能使其正常工作以及如何交换被实施以使其适用于交换具有一系列整数的 Array[A]?
object Quicksort {
def partition[A](data: Array[A], lower: Int, upper: Int)
(implicit comp: Ordering[A]): Int = {
val pivot = data(upper-1)
var mid = lower-1
for (i <- lower until upper-1) {
if (comp.lteq(data(i),pivot)) {
mid += 1
swap(data,mid,i)
}
}
swap(data,mid+1,upper-1)
mid+1
}
def sort[A](data: Array[A])(...): Unit = {
def sortRange(data: Array[A], lower: Int, upper: Int):
Unit = {
if(lower < upper) {
val pivotIndex = partition(data,lower,upper)
sortRange(data,lower,pivotIndex)
sortRange(data,pivotIndex+1,upper)
}
}
sortRange(data,0,data.length)
}
def main(args: Array[String]) : Unit = {
//Result of partition(data,lower,upper):
//sortRange results in quick-sorting the range: [lower,upper)
}
}
由于 Quicksort 是一种就地排序算法(即它都是关于副作用的),而不是传递要排序的集合,我想将方法“附加”到所述集合。
我还想删除所有那些讨厌的可变变量。
implicit class QSort[A:Ordering](as: Array[A]) {
import Ordering.Implicits._
private def swap(x: Int, y: Int): Unit = {
val hold = as(x)
as(x) = as(y)
as(y) = hold
}
private def partition(lo: Int, hi: Int): Int =
((lo until hi).filter(as(_) < as(hi)) :+ hi)
.zipWithIndex.foldLeft(0){
case (_,(j,x)) => swap(j, lo+x); lo+x
}
private def quicksort(lo:Int, hi:Int): Unit =
if (lo < hi) {
val p = partition(lo, hi)
quicksort(lo, p-1)
quicksort(p+1, hi)
}
def qsort(): Unit = quicksort(0, as.length - 1)
}
测试:
val cs = Array('g','a','t','b','z','h')
cs.qsort() //: Unit
cs //: Array[Char] = Array(a, b, g, h, t, z)
val ns = Array(9,8,7,6,5,4,3,2,1)
ns.qsort() //: Unit
ns //: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9)