“选择”排序

简介: “选择”排序

  何为选择排序?其实选择排序是最好理解的排序,就是每次遍历数组,从中选出一个最大的和一个最小的数,把最小的数放到数组的最左边,最大的数放到数组的最右边,两边缩小一个位置(因为最大和最小的数已经排好了),再遍历剩下的数找出最小的和最大的数放到第二个位置和倒数第二个位置,以此类推,最终就能使数组有序。


动图如下:


     但是这里的动图演示的是每次找出数组中的一个最小值放到左边,其实遍历一遍是可以同时找到最大值和最小值的,这样的话效率会高一倍。这个看个人喜好吧,想一次选最大和最小或者一次就选一个最小都是可以的。



  毫无疑问,选择排序需要执行的次数是:第一次遍历数组选最小值需要n次,第二次遍历数组找最小值需要n-1次,以此类推,最后递减到1次,这是一个等差数列的求和,所以时间复杂度为经典的O(N^2), 而且选择排序对数据敏感性不高,就是无论是什么情况的数据它的时间复杂度都是O(N^2),因为即使数组本来就是有序的,但是每一次仍然需要遍历剩下的所有数才能选出最小的。所以选择排序是最“稳定”的排序,但是这个“稳定”是一个调侃的词。由于选择排序的效率是非常稳定的慢,所以在实际中很少被使用。


参考代码如下:


//这里的代码是每一次同时选出一个最大值和最小值的,
//参数n代表数组的元素个数
void SelectSort(int* a, int n)
{
  assert(a);
  //左下标
  int left = 0;
  //右下标
  int right = n - 1;
  int i = 0;
  //只要左右下标还没有相遇,就说明两个下标之间
  // 还有没排好的数据,一直循环到left==right
  while (left < right)
  {
    //可以设待排序的数组中的任意一个数的下标作为最大值或者最小者
    // 的下标,因为后面比较的时候会被真正的最大最小值换掉,但是不
    //能用不是数组内的值作为基准
    int mini = left;
    int maxi = left;
    //遍历一遍选出最大值和最小值的下标,由于left作为基准了,所以
    //i可以直接从left+1开始,不用跟自己比较了
    for (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可能就是最大值的下标
    //所以在把最小值换到左边的时候可能把最大值从左边
    //换到了最小值的位置,所以如果找到的最大值的下标是
    //left,即left==maxi的话,经过了上面的交换,最大
    //值就被交换了,需要修正一下最大值的下标,此时它应该
    //在原来最小值的位置mini上,所以maxi=mini修正一下。
    //如果每次只找一个最小值的话就不会出现这种需要修正的
    //情况咯
    if (left == maxi)
    {
      maxi = mini;
    }
    //最大值换到右边
    Swap(&a[right], &a[maxi]);
    //左边最小,右边最大之后下一次就不用对这两个数排序了
    //所以两边缩小一个位置,即left++,right--,再从剩
    //下的数中遍历找最大和最小值,迭代走下去,直到left和right相遇
    ++left;
    --right;
  }
}


相关文章
|
计算机视觉 Python
OpenCV形态学运算中梯度运算、顶帽、黑帽运算讲解与实战应用(附Python源码)
OpenCV形态学运算中梯度运算、顶帽、黑帽运算讲解与实战应用(附Python源码)
489 0
|
8月前
|
存储 前端开发 Java
Harry技术添加存储(minio、aliyun oss)、短信sms(aliyun、模拟)、邮件发送等功能
### SpringBoot3 + Vue3 前后端分离的Java快速开发框架更新 本次更新主要包含以下内容: 1. **端口修改**:为避免与Minio存储服务冲突,后端启动端口从9000改为9999。 2. **添加存储支持**:集成Minio和阿里云OSS对象存储服务,详细配置请参考相关文档。 3. **短信服务**:接入阿里云短信服务,并增加模拟发送功能,方便本地测试。 4. **邮件发送**:引入邮件发送功能,支持简单文本邮件和带附件邮件。 5. **完善个人中心**:优化个人中心页面,提升用户体验。
323 85
Harry技术添加存储(minio、aliyun oss)、短信sms(aliyun、模拟)、邮件发送等功能
|
Java 开发者
Java中的并发编程:深入理解synchronized关键字
在Java并发编程的领域中,synchronized关键字是实现线程同步的基础工具之一。本文将深入剖析synchronized的作用机制,探讨其在多线程环境下确保数据一致性的重要性,并通过实际案例展示其应用。同时,文章还将比较synchronized与Lock接口的不同之处,以助于开发者更好地选择适合自己场景的同步策略。
142 29
|
7月前
|
JavaScript 前端开发 算法
🚀【程序员必备】Qwerty Learner:打造英语输入与单词记忆的神器
Qwerty Learner 是一款专为键盘工作者设计的开源软件,结合单词记忆与英语输入练习,提升英语水平和打字速度。内置丰富词库(如 CET-4/6、GRE、编程API等),提供音标发音、默写模式、速度正确率统计等功能,适合学生、职场人士及程序员使用。
3659 17
|
11月前
|
JavaScript 前端开发 程序员
动态语言、静态语言、强类型语言、弱类型语言的区别
动态语言、静态语言、强类型语言、弱类型语言的区别
|
机器学习/深度学习 监控 自动驾驶
基于深度学习的动态场景理解
基于深度学习的动态场景理解是一种通过计算机视觉技术自动分析和解释动态环境中物体、事件和交互的能力。该技术在自动驾驶、智能监控、机器人导航、增强现实等领域有着广泛应用。
302 1
|
存储 数据库 监控
|
微服务
阿里云微服务引擎 MSE 2023 年11 月产品动态
阿里云微服务引擎 MSE 2023 年11 月产品动态
522 81
|
分布式计算 资源调度 监控
Hadoop性能优化优化元数据管理
【6月更文挑战第6天】
138 2
|
存储 分布式计算 运维
hadoop HA高可用集群实战
大数据实战:hadoop HA高可用集群
hadoop HA高可用集群实战