js 算法 - 选择排序

1,698 阅读3分钟

这是我参与8月更文挑战的第7天,活动详情查看:8月更文挑战

选择排序

选择排序和插入排序有一点相似,它也分为有序区间和无序区间,但是它并不像插入排序那样需要拿出无序区间的一个数据依次与有序区间的各个数据作比较,它的核心操作是每次都从无序区间找到区间内的最小值,然后将最小值插入到有序区间的末尾,以此达到有序。

算法描述

假设是从小到大排序

  1. 将一组数据划分为有序区间和无序区间,初始有序区间为空,无序区间则包含所有数据
  2. 从无序区间找到区间内的最小值
  3. 将该最小值插入到有序区间的末尾
  4. 重复 2 和 3 操作,直到无序区间只有一个数据

算法图解

假设一组数据里有:3、1、2。

“第一次选择”步骤,3、1、2 组成无序区间,有序区间为空。“最小值”指向无序区间的首个数据 3,“最小值”与 1 对比,1 比 3 小,因此“最小值”指向 1。“最小值”与 2 对比,“最小值”比 2 大,不做改动。将“最小值”插入到有序区间。

1629875226(1).png

“第二次选择”步骤,“最小值”依旧指向无序区间的首个数据 3,“最小值”与 2 对比,2 更小,因此“最小值”指向 2。将“最小值”插入到有序区间的末尾位置。

1629875367(1).jpg

经过上面几次“选择”后,无序区间只有一个数据,这个数据必定是这组数据里的最大值,因此将该数据放到有序区间的末尾即可。

1629875591(1).jpg

代码实现

注意:虽然说需要将数据分为有序区间和无序区间,但是在实现时并不需要申请两个数组(有序数组和无序数组),只需要在原数组进行抽象划分。

// 选择排序
function selectionSort(arr) {
  var minIndex = 0
  for (var i = 0; i < arr.length-1; i++) { // 长度-1,是因为剩下最后一个数时不用做判断
    minIndex = i
    for (var j = i + 1; j < arr.length; j++) { // j = i + 1 是因为自身不需要做比较
      if (arr[j] < arr[minIndex]) {
        minIndex = j
      }
    }
    var temp = arr[i]
    arr[i] = arr[minIndex]
    arr[minIndex] = temp
  }
  return arr
}
原地排序稳定性最好时间复杂度最坏时间复杂度平均时间复杂度
选择排序不稳定O(n²)O(n²)O(n²)

选择排序大概是所有排序算法里最差的一种算法了,它的最好、最坏、平均时间复杂度都为 O(n²),因为不管原来数据顺序怎么样,都要在无序区间找最小值,找最小值的过程中,无序区间的每一个数据都要进行作对比。而且它不具备稳定性,也即是说如果一组数据中有两个 2,经过选择排序后,这两个 2 的前后顺序可能会被打乱。因此该算法大概不会在开发中应用到。

js 算法系列文章推荐