排序算法系列之选择排序

Posted 编程异思坊

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了排序算法系列之选择排序相关的知识,希望对你有一定的参考价值。

写在前面

十大排序算法一直以来都是面试考擦的重点,本文将以简单、易懂的文字来讲清楚十大排序算法之一的选择排序。

下面我将从原理、代码、优化、复杂度分析、稳定性分析和应用场景这几个方面来剖析选择排序,读者朋友一看就懂,一写就会。


基本原理

选择排序突出“选择”二字,实际上就是从待排序数据中“选择”出符合条件的元素按顺序放到序列头部。

官方定义是这样的:第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。

以此类推,直到全部待排序的数据元素的个数为零。

如果文字解释不理解也没关系,直接看图形演示就清楚了。

排序算法系列之选择排序(一)


实现代码

代码实现起来也简单,直接上代码。这里以升序排序为例。

 1template<typename T>
2void selectionSort(vector<T> &arr)
3
{
4    int len = arr.size();
5    if(len==0)  //数组为空直接返回
6        return;
7    for (int i = 0; i < len;++i)
8    {
9        int min = i; //存储数组最小值下标
10        for (int j = i + 1; j < len; ++j)
11        {
12            //如果是降序排序则改为大于号
13            if(arr[j]<arr[min])
14            {
15                min = j; //更新数组最小值下标
16            }
17        }
18        swap(arr[i], arr[min]);
19    }
20}

时间复杂度为 O(N^2),空间复杂度为 O(1)。


算法优化

上面代码一次遍历只是找出排列数据中的最小值,其实我们可以在遍历过程中同时找出最大值,并把每次找出的最大值按顺序放到每次排列数据的末尾。

不好理解直接上图。

排序算法系列之选择排序(一)


优化代码

 1template<typename T>
2void selectionSort(vector<T>& arr)
3
{
4    int len = arr.size();
5    if (len==0//数组为空直接返回
6        return;
7    int left = 0;
8    int right = len - 1;
9    int min = left; //存储最小值的下标
10    int max = left; //存储最大值的下标
11    while(left <= right)
12    {
13        min = left; //每次遍历前都将最小值下标更新为待排序列的首元素下标
14        max = left; //每次遍历前都将最大值下标更新为待排序列的首元素下标
15        for(int i = left; i <= right; ++i)
16        {
17            if(arr[i] < arr[min])
18            {
19                min = i;
20            }
21            if(arr[i] > arr[max])
22            {
23                max = i;
24            }
25        }
26        swap(arr[left],arr[min]);
27        //前面将 max 更新为 left,如果遍历完后 max 没有更新,说明待排序列的首元素就是最大值
28        if(left == max) 
29            max = min; //前面 min 与 left 的数据已经交换,所以此时 min 的数据就是之前 left 的数据
30        swap(arr[right],arr[max]);
31
32        ++left;
33        --right;
34    }
35}
时间复杂度为 O((N/2)^2),空间复杂度为 O(1)。
时间复杂度还是 O(N^2) 级别,只是相对前面的减少了一半遍历次数,这种方式也仅仅提供一个思路,让面试官知道自己的思维还是比较发散的。

稳定性分析

选择排序是不稳定排序。什么是不稳定排序呢?
不稳定排序就是在有相同元素的情况下,不能保证排序后相同元素的相对顺序不会改变。
来看一张图就明白了。

在心里实现一般上图的排序序列,会发现相同元素的相对位置确实发生了改变。

应用场景

当数据规模较小 (N<=50) 时,O(N^2) 排序算法的复杂度不会呈现快速增长,选择排序性能较好,实现起来也比较简单。

总结

最后一句话总结一下,选择排序是一种时间复杂度 O(N^2),空间复杂度 O(1),不稳定的排序算法。

如果这篇内容对你有帮助,可以点个在看支持一下。同时,欢迎关注下方微信公众号『编程异思坊』,更多精彩内容等你探索!

以上是关于排序算法系列之选择排序的主要内容,如果未能解决你的问题,请参考以下文章

图解算法系列之选择排序

排序算法之快速选择排序

JavaScript ,Python,java,Go系列算法之选择排序

JavaScript ,Python,java,Go系列算法之选择排序

算法系列之选择排序

JavaScriptPythonjavaGo算法系列之快速排序篇