选择排序( selection sort )是一种简单直观的排序算法。它的工作原理分为两步:
- 从未排序序列中找到最小元素(如果希望降序排序,则找最大元素);
- 将最小元素交换到未排序序列的起始位置;
排序过程需要不断重复上述两个步骤,直到序列完全有序。
由于寻找最小元素需要遍历整个序列,时间复杂度是 $O(n)$ ;选择排序需要执行 $n-1$ 次选择,因此时间复杂度是 $O(n^2)$ 。由此可见,选择排序表现并不出色,但胜在简单,多用于 小规模 排序场景。
查找最小元素
从无序序列中查找最小元素,需要遍历整个序列:
- 用临时变量 $min$ 记录当前看到的最小元素,刚开始时指向第一个元素;
- 遍历余下元素,逐一与 $min$ 比较,如果当前元素更小,则更新 $min$ 指向当前元素;
搜索过程如以下动画所示,应该不难理解:
寻找最小元素示例代码如下,结合注释和上述动画应该很好理解:
选择排序
选择排序需要执行 $n-1$ 次循环,每次从未排序序列中找出最小元素,并将它交换到序列头部:
选择排序示例代码如下:
/*
* selection_sort - 对给定数组进行选择排序
*
* 参数说明:
* - array: 数组首地址;
* - n: 数组长度,即数组元素个数;
*
* 返回值:无
*/
int selection_sort(int *array, int n) {
// 如果元素不足两个,已天然有序,无需处理
if (n < 2) {
return;
}
// 选择排序需要执行 n-1 次循环
// 每次都从余下序列中找出最小元素,并交换到序列头部
// 第i次循环时,i以前的元素已经排好顺序,未排序序列从i开始
for (int i=0; i
/*
* SelectionSort - 对给定数组进行选择排序
*
* 参数说明:
* - array: 待排序数组(切片);
*
* 返回值:无
*/
func SelectionSort(array []int) {
// 如果元素不足两个,已天然有序,无需处理
n := len(array)
if n < 2 {
return
}
// 选择排序需要执行 n-1 次循环
// 每次都从余下序列中找出最小元素,并交换到序列头部
// 第i次循环时,i以前的元素已经排好顺序,未排序序列从i开始
for i := 0; i < n-1; i++ {
// 调用 FindMinimum 找出最小值
min := FindMinimum(array, i, n)
if min != i {
// 将最小元素交换到未排序序列头部,即下标为i的位置
array[i], array[min] = array[min], array[i]
}
}
}
/*
* selectionSort - 对给定数组进行选择排序
*
* 参数说明:
* - array: 待排序数组;
*
* 返回值:无
*/
function selectionSort(array) {
// 计算数组长度
const n = array.length;
// 选择排序需要执行 n-1 次循环
// 每次都从余下序列中找出最小元素,并交换到序列头部
// 第i次循环时,i以前的元素已经排好顺序,未排序序列从i开始
for (let i=0; i
def selection_sort(array):
''' 对给定数组(list对象)进行选择排序
参数说明:
- array: 给定数组,应该是一个list对象。
返回值:无
'''
# 计算数组长度
n = len(array)
# 选择排序需要执行 n-1 次循环
# 每次都从余下序列中找出最小元素,并交换到序列头部
# 第i次循环时,i以前的元素已经排好顺序,未排序序列从i开始
for i in range(0, n-1):
# 调用 find_minimum 找出最小值
_min = find_minimum(array, i, n)
if _min != i:
# 将最小元素交换到未排序序列头部,即下标为i的位置
array[i], array[_min] = array[_min], array[i]
【小菜学算法】系列文章首发于公众号【小菜学编程】,敬请关注: