本系列的文章列表和相关说明,请查看序言。具体列表以下:
【一块儿学习排序算法】0 序言
【一块儿学习排序算法】1 算法特性及大O记法
【一块儿学习排序算法】2 冒泡排序javascript
也能够直接到github上查看完整的文章和源码!html
本篇为此系列第三篇。java
先看看Wikipedia的定义:git
The Selection sort algorithm divides the input list into two parts: the sublist of items already sorted and the sublist of items remaining to be sorted that occupy the rest of the list. Initially, the sorted sublist is empty and the unsorted sublist is the entire input list. The algorithm proceeds by finding the smallest element in the unsorted sublist, exchanging it with the leftmost unsorted element, and moving the sublist boundaries one element to the right. .github
因此选择排序的思路就是:算法
能够经过动画演示理解, 如下网上找的动画。若是你想操做不一样的参数来演示,能够上这个网站visualgo.net动手试试。数组
关于代码,README中代码只有实现算法的函数,具体运行的代码,请查看该目录下的文件。bash
代码以下:数据结构
const selectSort = (array) => {
// 不修改原数组
const originValues = array.slice();
const length = originValues.length;
// 迭代次数 数组长度-1, 由于前n个元素有序,则所有有序
for (let i = 0; i < length - 1; i++) {
// 把当前无序子列的第一个元素当作最小值
let minIndex = i;
// 找出最小值的索引
for (let j = i+1; j < length; j++) {
if (originValues[j] < originValues[minIndex]) {
minIndex = j;
}
}
// 若是最小值不为当前值,交换
if (minIndex !== i) {
const tmp = originValues[i];
originValues[i] = originValues[minIndex];
originValues[minIndex] = tmp;
}
}
return originValues;
};
复制代码
选择排序仍是比较简单的,基本知道原理,看了注释就很明白了。有一点要说的是,就是在找最小值这个步骤。不少文章的实现,在发现当前值小于当前最小值时,就交换元素。这种交换仍是不必的,只要先记住最小值得下标minIndex
就能够,最后一步来作交换。这样就减小了不少没必要要的交换要素,后来发现和wikipedia的实现如出一辙(第一次也是惟一一次,哈哈)。ide
时间复杂度
选择排序,无论数组正序仍是逆序,都是同样的操做。最优复杂度和最差复杂度都是O(n2)。
稳定性
由于可能存在和最小值元素交换是,把数值相同的元素顺序调换,因此,选择排序是不稳定的排序。
举个例子吧:
[3] 5 2 (3) 1
复制代码
因为最小的元素1在最后一个,须要和[3]
元素交换,此时[3]
就到(3)
后面了。
有文章说选择排序是稳定的,其实看具体的实现。在《算法》第四版217页上做者已经说了,有不少办法能够将任意排序算法变成稳定的,可是,每每须要额外的时间或者空间。摘自知乎
本章节介绍了几种选择排序的实现。选择排序应该是最简单的排序了,不过效率也是很低,复杂度仍是O(n2)。
[1] 动画演示
[2] tutorials point 教程
[3] 选择排序究竟属于稳定排序仍是不稳定排序?
[4] Sorting Algorithms
[5] 凯耐基梅隆大学数据结构与算法-排序算法
[6] CMU algorithm complexity