排序算法系列之选择排序
Posted 编程异思坊
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了排序算法系列之选择排序相关的知识,希望对你有一定的参考价值。
写在前面
十大排序算法一直以来都是面试考擦的重点,本文将以简单、易懂的文字来讲清楚十大排序算法之一的选择排序。
下面我将从原理、代码、优化、复杂度分析、稳定性分析和应用场景这几个方面来剖析选择排序,读者朋友一看就懂,一写就会。
基本原理
选择排序突出“选择”二字,实际上就是从待排序数据中“选择”出符合条件的元素按顺序放到序列头部。
官方定义是这样的:第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。
以此类推,直到全部待排序的数据元素的个数为零。
如果文字解释不理解也没关系,直接看图形演示就清楚了。
![排序算法系列之选择排序(一)](https://image.cha138.com/20210415/49d2ee193e3c43bfa5b433f5c7903d1d.jpg)
实现代码
代码实现起来也简单,直接上代码。这里以升序排序为例。
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)。
算法优化
上面代码一次遍历只是找出排列数据中的最小值,其实我们可以在遍历过程中同时找出最大值,并把每次找出的最大值按顺序放到每次排列数据的末尾。
不好理解直接上图。
![排序算法系列之选择排序(一)](https://image.cha138.com/20210415/892be7e1ce12460c8189422835140276.jpg)
优化代码
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}
稳定性分析
应用场景
总结
以上是关于排序算法系列之选择排序的主要内容,如果未能解决你的问题,请参考以下文章
JavaScript ,Python,java,Go系列算法之选择排序