十大基础排序算法-scala编写

1、前言

最近补了一下《数据结构与算法》的相关知识,这里记录一下常见的十大排序算法。因为最近自己在学习scala,所以下面都是使用的scala进行编程,其与java语法有很多类似,保留了java的面向对象编程,同时拥有函数式编程。
(用什么语言都一样,算法思路对就行。)

2、排序

2.1、排序分类

根据在排序的过程中待排序的记录是否全部被放置在内存中,排序分为:内排序和外排序

其中,内排序是在排序的整个过程中,待排序的所有记录全部被放置在内存中。外排序是由于排序的次数个数太多,不能同时放置在内存中,整个排序过程需要在内外存之间多次交换数据才能进行。

根据内排序过程中借助的主要操作,我们把内排序分为:插入排序、交换排序、选择排序、归并排序。

常见的内排序有:

  • 冒泡排序

  • 选择排序

  • 插入排序

  • 希尔排序

  • 归并排序

  • 快速排序

  • 堆排序

  • 计数排序

  • 桶排序

  • 基数排序

2.2、影响因素

对于内排序来说,排序算法的性能主要是受3个方面影响:

  1. 时间性能
    排序是数据处理中经常执行的一种操作,往往属于系统的核心部分,因此排序算法的时间开销是衡量其好坏的最重要的标志。在内排序中,主要进行两种操作:比较和移动。比较是指关键字之间的比较,这是要做排序最起码的操作。移动是指记录从一个位置移动到另外一个位置,事实上,移动也可以通过改变记录的存储方式来予以避免。总之,高效率的内排序算法应该是具有尽可能少的关键字比较次数和尽可能少的记录移动次数。

  2. 辅助空间
    评价排序算法的另外一个主要的标准是执行算法所需要的辅助存储空间。辅助存储空间使除了存放待排序所占有的存储空间之外,执行算法所需要的其他的存储空间。

  3. 算法的复杂性
    这里指的是算法本身的复杂度,而不是指算法的时间复杂度。显然算法过于复杂也会影响排序的性能。

3、冒泡排序

冒泡排序是一种简单直观的排序算法。其是一种交换排序,它的基本思想是:两两比较相邻记录的关键字,如果反序则交换,直到没有反序的记录为止。

  • 冒泡排序算法
import com.zhangyue.impls.IArraySort

import scala.util.Random

/**
  * 冒泡排序:
  * 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
  * 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
  * 针对所有的元素重复以上的步骤,除了最后一个。
  * 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
  */
class BubbleSort extends IArraySort {
  override def sort(sourceArray: Array[Integer]): Array[Integer] = {
    var flag : Boolean = true //此处的flag主要是优化代码,防止某次循环发现数组中都已经排好序,而再次进行没必要的循环
    for (i <- 1 until sourceArray.length if !flag) {
      flag = false
      for (j <- sourceArray.length until i) {  //此处从后往前,也可以从前往后,方式很多
        if (sourceArray(j) < sourceArray(j-1)) {
          val temp : Integer = sourceArray(j)
          sourceArray(j) = sourceArray(j-1)
          sourceArray(j-1) = temp
          flag = true
        }
      }
    }
    sourceArray  //此处等同于return sourceArray
  }
}
object BubbleSort {
  def main(args: Array[String]): Unit = {
    val array = new Array[Integer](10)
    val random = new Random()
    for (i <- 0 to 9) {
      array(i) = random.nextInt(100)
    }
    val bubbleSort = new BubbleSort
    val resultArray : Array[Integer] = bubbleSort.sort(array)
    resultArray.map(println)
  }
}

补充:

  1. 当然,上面这个,也可以设置一个指针,指向数组最后已经排好序的下标,这样可以省去已经排好序的再重复比较。
  2. 也可以内循环从后往前比较,将小的数字往前放。只要思想对,方式很多种。

4、选择排序

选择排序是一种简单直观的排序算法,无论什么数据进去都是O(n2)的时间复杂度。它的基本思想是:通过 n-1 次的关键字间的比较,从 n-i+1 个记录中选出关键字最小的记录,并和第 i 个记录交换之。

  • 选择排序
import com.zhangyue.impls.IArraySort

import scala.util.Random

/**
  * 选择排序:
  * 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
  * 再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
  * 重复第二步,直到所有元素均排序完毕。
  */
class SelectionSort extends IArraySort {
   override def sort(sourceArray: Array[Integer]): Array[Integer] = {
    //n-1次循环
    for (i <- 0 until (sourceArray.length - 1 )) {
      //设置最小的数的下标为min,初始为i
      var min : Integer = i
      for (j <- i until sourceArray.length ) {
        if (sourceArray(j) < sourceArray(min)) {
          //当下标为j的数值比min的数值大时候,将min变成j
          min = j
        }
      }
      //此处当min 不等于 i 的时候,说明 最小的数 不是 i,故将 i 与min 对应的数值交换
      if (min != i) {
        val temp : Integer = sourceArray(min)
        sourceArray(min) = sourceArray(i)
        sourceArray(i) = temp
      }
    }
    sourceArray
  }
}
object SelectionSort {
  def main(args: Array[String]): Unit = {
    val array = new Array[Integer](10)
    val random = new Random()
    for (i <- 0 to 9) {
      array(i) = random.nextInt(100)
    }
    val selectionSort = new SelectionSort
    val resultArray : Array[Integer] = selectionSort.sort(array)
    resultArray.map(println)
  }
}

5、插入排序

插入排序是一种最简单直观的排序算法,它的工作原理:通过构建有序序列,对于未排序数据,在已经排好序的序列从后往前扫描,找到相应的位置,将此位置与后面位置上面的数值往后移动一位,将此数值插入到序列中。

  • 插入排序
import scala.util.Random

/**
  * 插入排序:
  * 将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。
  * 从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。
  * (如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。)
  */
class InsertionSort extends IArraySort{
  override def sort(sourceArray: Array[Integer]): Array[Integer] = {
    // 从下标为1的元素开始选择合适的位置插入,因为下标为0的只有一个元素,默认是有序的
    for (i <- 1 until sourceArray.length) {

      //记录要插入的数据
      var temp : Integer =
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值