Day04 选择排序(概念篇)

179 阅读3分钟

《算法零基础》选择排序(概念篇)

一、引言

​ 选择排序(Selection Sort)是一种简单直观的排序算法。它首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

二、算法思想

​ 第一步、在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。

​ 第二步、再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。

​ 重复第二步,直到所有元素均排序完毕。

三、动图演示

​ 我们发现,首先从「第一个元素」到「最后一个元素」中选择出一个「最小的元素」,和「第一个元素」进行「交换」;

  然后,从「第二个元素」到「最后一个元素」中选择出一个「最小的元素」,和「第二个元素」进行「交换」。

​ 重复上述过程,从 「第 i 个元素」到「最后一个元素」中选择出一个「最小的元素」,和「第 i 个元素」进行「交换」。最后,一定可以保证所有元素都是「升序」排列的。

四、算法分析

1、时间复杂度

​ 选择排序中有两个嵌套循环。当有 n 个元素时,外循环正好运行n−1次迭代。 但内部循环运行变得越来越短:

  当i=0,内层循环n−1次「比较」操作。

  当i=1,内层循环n−2次「比较」操作。

  当i=2,内层循环n−3次「比较」操作。

  ……

  当i=n−3,内层循环2次「比较」操作。

  当i=n−2,内层循环1次「比较」操作。

​ 「比较」操作是公差为 -1 的等差数列,求和:(首项+尾项) (项数) / 2 = (n-1+1)(n-1)/2

​ 因此,总「比较」次数如下:(n−1)+...+2+1=n(n−1)/2,总的时间复杂度为:O(n2)O(n^2)

首项为 a1a_1, 末项为 ana_n, 项数为 nn, 公差为 dd, 前项和为 SnS_n

等差数列通项公式:

  • an=a1+(n1)da_n=a_1+(n-1)d

等差数列求和公式:

  • Sn=(a1+an)n2S_n = \frac {(a_1+a_n)n}{2}
  • Sn=na1+n(n1)2dS_n = na_1 + \frac {n(n-1)}{2}d
  • Sn=[2a1+(n1)d]n2S_n = \frac {[2a_1+(n-1)d]n}{2}

2、空间复杂度

​ 选择排序的空间复杂度为 O(1)O(1)。它只使用了固定的额外空间来存储交换操作,并不依赖于输入数组的大小。

五、算法的优点

  1. 简单易懂:选择排序是一种简单直观的排序算法,容易理解和实现。
  2. 原地排序:选择排序不需要额外的存储空间,只使用原始数组进行排序。
  3. 适用于小型数组:对于小型数组,选择排序的性能表现较好。

六、算法的缺点

  1. 时间复杂度高:在处理大规模数据时效率较低。
  2. 不稳定:选择排序在排序过程中可能会改变相同元素的相对顺序,因此它是一种不稳定的排序算法。

七、优化方案

​ 「 选择排序 」在众多排序算法中效率较低,时间复杂度为 O(n2)O(n^2)

  想象一下,当有n=100000个数字。 即使我们的计算机速度超快,并且可以在 1 秒内计算10^8次操作,但选择排序仍需要大约一百秒才能完成。

  考虑一下,每一个内层循环是从一个区间中找到一个最小值,并且更新这个最小值。是一个「 动态区间最值 」问题,所以这一步,我们是可以通过「 线段树 」来优化的。这样就能将内层循环的时间复杂度优化成 O(log2n)O(log2n) 了,总的时间复杂度就变成了 O(nlog2n)O(nlog2n)

​ 当然,常见的选择排序优化是采用堆排序来进行优化的,后续我们会学到。