vlambda博客
学习文章列表

利用Scala深入剖析经典排序算法之选择排序

上一期,我们详解了,冒泡排序,今天我们用Scala来拆解一下经典排序算法中的选择排序,老规矩,记住了排序最主要的就是位置的交换,所以先来个交换位置的方法:

def swap(array: Array[Int], i: Int, j:Int): Unit ={
val tmp = array(i)
array(i) = array(j)
array(j) = tmp
}

另外我们还是以一个实际存在的无序数组来举例:

val array = Array(2,3,5,4,6,1,9,7,8)

选择排序的核心要义,就和冒泡不同了,冒泡是先找最大的,而选择排序相反,它的主要原则是:先找最小的。话不多说,先放上一段选择排序实现的代码块儿:

def choiceSort(array: Array[Int]):Array[Int] = {
val arr = array
for (i <- 0 until arr.length){
var min = i
for (j <- i+1 until arr.length){
if (arr(j) < arr(min)){
min = j
}
}
if (i != min){
swap(arr,i,min)
}
}
arr
}

解释一下,我们这里是传入一个数组,返回一个数组。也要记住for循环的要义,外层跑1,内层跑一圈。第一层for循环,以我们给定的具体数组举例,同样是从0到8,until 数组的长度9,最后的9是不会被循环到的,就只有0到8,一共呢,也是9遍循环,内层跑圈呢是从i+1跑,就不像冒泡内层跑的圈数是固定的,因为它每一次都是找到最小的放前面,所以每次找到最小的了之后,就没有必要再从之前的位置跑,所以内层跑的最大的一圈是8次,接下来就是7次,6次........1次(此时对应外层i==7,下一轮将不会进入内层,已经排序完成不将换位)8+7+6+5+4+3+2+1=36,(但记住外面循环还是跑的9次)。每一圈内层循环的结束,都标志着一个剩下的所有数中最小数的产生,再来比较一下,这个最小数的序号是否等于咱之前选定的当前最小序号i,不等就交换,让最小值匹配当前的最小序号。这样循环下去,有序就产生了

完整测试代码实现:

object TestScalaChoice {
def main(args: Array[String]): Unit = {
val array = Array(2,3,5,4,6,1,9,7,8)
def swap(array: Array[Int], i: Int, j:Int): Unit ={
val tmp = array(i)
array(i) = array(j)
array(j) = tmp
}
def choiceSort(array: Array[Int]):Array[Int] = {
val arr = array
for (i <- 0 until arr.length){
var min = i
for (j <- i+1 until arr.length){
if (arr(j) < arr(min)){
min = j
}
}
if (i != min){
swap(arr,i,min)
}
}
arr
}
println(choiceSort(array).toList)
}
}

注:原创文章,仅供参考,如有错误,希望大家批评指正,谢谢