【数据结构】八大排序之简单选择排序算法

简介: 【数据结构】八大排序之简单选择排序算法

一.简单选择排序简介及思路

简单选择排序算法(Simple Selection Sort)是一种简单直观的选择排序算法.

它的基本操作是:

  • 每一次通过n-i次关键字间的比较,从n-i+1个数据中选出关键字最小(大)的数据,并和第i(1≤i≤n)个数据交换
  • 重复n-1次上述操作,直到全部待排序的数据元素排完.

算法动图演示如下:


二.简单选择排序的代码实现

算法实现步骤:(以升序为例)

  1. 在元素集合arr[i]~arr[n-1]中选择关键码最小(大)的数据元素.
  2. 若它不是这组元素中的第一个(最后一个)元素,则将它与这组元素中的第一个(最后一个)元素交换.
  3. 在剩余的arr[i+1]~arr[n-1](arr[i]~arr[n-2])集合中,重复上述步骤,直到集合剩余一个元素.

清楚了实现步骤后,代码的实现就比较简单了,代码如下:

//交换函数
void Swap(int* a, int* b)
{
  int tmp = *a;
  *a = *b;
  *b = tmp;
}
 
//直接选则排序(升序
void SelectSort(int* a, int n)
{
  int left = 0;
 
  while (left < n - 1)
  {
    int mini = left;
    for (int i = left + 1; i <= n - 1; i++)
    {
      if (a[i] < a[mini])
      {
        mini = i;
      }
    }
    Swap(&a[left], &a[mini]);
    left++;
  }
}

三.简单选择排序的优化

我们在设计简单选择排序时,思路往往都是每趟循环选出一个最大最小的将其放在相应位置上,那么其实我们可不可以一趟直接将最大和最小的两个元素选出来呢?

依照这个思路,我们对简单选择排序进行优化,使其一趟就可以将最大的元素和最小的元素都选出来交换到相应的位置上,综上,代码实现如下:

//交换
void Swap(int* a, int* b)
{
  int tmp = *a;
  *a = *b;
  *b = tmp;
}
 
//选择排序(直接选择排序)
void SelectSort(int* a, int n)
{
  //优化:一趟选出最大和最小的
  int left = 0;
  int right = n - 1;
 
  while (left < right)
  {
    int mini = left, maxi = left;
    for (int i = left + 1; i <= right; i++)
    {
      if (a[i] < a[mini])
      {
        mini = i;
      }
      if (a[i] > a[maxi])
      {
        maxi = i;
      }
    }
    Swap(&a[left], &a[mini]);
 
    //如果left和maxi重叠,交换后需要修正一下再交换right和maxi
    if (left == maxi)
    {
      maxi = mini;
    }
 
    Swap(&a[right], &a[maxi]);
 
    left++;
    right--;
  }
}

注意:

       当我们在一趟比较结束后选出mini和maxi并做交换的时候,要小心如果left记录的位置恰好存放的是maxi,则第一步交换left和mini后我们就要重新对maxi的位置做一个修正,如图:


四.简单选择排序的时间复杂度分析

我们可以发现,简单选择排序的特点是:

        元素挪动交换次数很少,但是元素比较次数很多,并且无论是数组天生顺序的情况还是天生逆序的情况,元素比较次数都是一样的,都是:T(n)=(n-1)+(n-2)+...+2+1=n(n-1) / 2 次.

         而对于交换次数而言,最好的时候,交换次数为0次,最坏的时候,交换次数为n-1次.

         基于最终的排序时间交换次数和比较次数的总和,因此,总的时间复杂度依然是O(n^2).


结语

希望这篇简单选择排序算法详解能对大家有所帮助,欢迎大佬们留言或私信与我交流.

有关更多排序相关知识可以移步:

https://blog.csdn.net/weixin_72357342/article/details/135038495?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22135038495%22%2C%22source%22%3A%22weixin_72357342%22%7D&fromshare=blogdetail

学海漫浩浩,我亦苦作舟!关注我,大家一起学习,一起进步!


数据结构排序算法篇思维导图:


相关文章
|
6天前
|
存储 监控 NoSQL
Redis处理大量数据主要依赖于其内存存储结构、高效的数据结构和算法,以及一系列的优化策略
【5月更文挑战第15天】Redis处理大量数据依赖内存存储、高效数据结构和优化策略。选择合适的数据结构、利用批量操作减少网络开销、控制批量大小、使用Redis Cluster进行分布式存储、优化内存使用及监控调优是关键。通过这些方法,Redis能有效处理大量数据并保持高性能。
27 0
|
1天前
|
存储 算法 搜索推荐
数据结构与算法⑰(第五章_八大排序)(完整代码+动图+详解+对比)(下)
数据结构与算法⑰(第五章_八大排序)(完整代码+动图+详解+对比)
20 1
|
1天前
|
算法 编译器
数据结构与算法⑰(第五章_八大排序)(完整代码+动图+详解+对比)(中)
数据结构与算法⑰(第五章_八大排序)(完整代码+动图+详解+对比)
15 4
|
1天前
|
存储 算法 搜索推荐
数据结构与算法⑰(第五章_八大排序)(完整代码+动图+详解+对比)(上)
数据结构与算法⑰(第五章_八大排序)(完整代码+动图+详解+对比)
20 6
|
5天前
|
缓存 算法 Java
数据结构~缓存淘汰算法--LRU算法(Java的俩种实现方式,万字解析
数据结构~缓存淘汰算法--LRU算法(Java的俩种实现方式,万字解析
|
6天前
|
存储 算法 搜索推荐
【Java高阶数据结构】图补充-拓扑排序
【Java高阶数据结构】图补充-拓扑排序
7 1
|
6天前
|
机器学习/深度学习 算法 数据可视化
Python 数据结构和算法实用指南(四)(4)
Python 数据结构和算法实用指南(四)
14 1
|
6天前
|
机器学习/深度学习 存储 算法
Python 数据结构和算法实用指南(四)(3)
Python 数据结构和算法实用指南(四)
15 1
|
6天前
|
算法 数据安全/隐私保护 计算机视觉
基于二维CS-SCHT变换和LABS方法的水印嵌入和提取算法matlab仿真
该内容包括一个算法的运行展示和详细步骤,使用了MATLAB2022a。算法涉及水印嵌入和提取,利用LAB色彩空间可能用于隐藏水印。水印通过二维CS-SCHT变换、低频系数处理和特定解码策略来提取。代码段展示了水印置乱、图像处理(如噪声、旋转、剪切等攻击)以及水印的逆置乱和提取过程。最后,计算并保存了比特率,用于评估水印的稳健性。
|
3天前
|
算法
m基于BP译码算法的LDPC编译码matlab误码率仿真,对比不同的码长
MATLAB 2022a仿真实现了LDPC码的性能分析,展示了不同码长对纠错能力的影响。短码长LDPC码收敛快但纠错能力有限,长码长则提供更强纠错能力但易陷入局部最优。核心代码通过循环进行误码率仿真,根据EsN0计算误比特率,并保存不同码长(12-768)的结果数据。
21 9
m基于BP译码算法的LDPC编译码matlab误码率仿真,对比不同的码长