时刻提醒自己,技术之路修远兮,予以自勉。

作者 |  菜鸟奋斗史

责编 | 胡巍巍

算法主要衡量标准

时间复杂度(运行时间)

在算法时间复杂度维度,我们主要对比较和交换的次数做对比,其他不交换元素的算法,主要会以访问数组的次数的维度做对比。

其实有很多同学对于算法的时间复杂度有点模糊,分不清什么所谓的O(n),O(nlogn),O(logn)......等,也许下图对一些人有一些更直观的认识。

空间复杂度(额外的内存使用)

排序算法的额外内存开销和运行时间同等重要。就算一个算法时间复杂度比较优秀,空间复杂度非常差,使用的额外内存非常大,笔者认为它也算不上一个优秀的算法。

结果的正确性

这个指标是笔者自己加上的,我始终认为一个优秀的算法最终得到的结果必须是正确的。就算一个算法拥有非常优秀的时间和空间复杂度,但是结果不正确,又有什么意义呢?

原理

在起始位置右侧(或左侧)找出最小的那个元素,然后和起始位置的元素交换。选择排序是一个不稳定的排序算法。

具体步骤如下:

  • 在一个数据列表中找到最小的那个元素,将它和列表的第一个元素交换位置。

  • 在第二个元素位置开始再次寻找最小的那个元素,然后和列表的第二个位置的元素交换。

  • 在第三个元素位置开始再次寻找最小的那个元素,然后和列表的第三个位置的元素交换

  • 如此反复,直到开始查找起始位置到达列表末尾。

如果查找过程中最小的元素就是起止位置的元素,那么它就和它自己交换。

因为这种算法总是在不断的选择剩余元素中最小者,因此得名选择排序。

复杂度

时间复杂度

1.比较次数

对于长度为N的列表,选择排序需要大约n² /2次比较.即:O(n²)平方级别。

2.交换次数

对于长度为N的列表,选择排序需要大约N次交换.即:O(N) 线性级别。

性能和特点

总体来说,选择排序是一种比较简单的排序算法,很容易理解也很好用代码实现,当然他的特点也很明显:

运行时间和数据初始状态无关

为什么这么说呢?算法进行中为了查找最小的元素而遍历列表并不能为下次遍历带来任何信息,这个特性在大部分情况下是缺点。

如果一个数据列表初始状态是有序的或者部分有序的,选择排序仍然需要全部扫描一次和交换。因此和一个完全无序的列表排序所花的时间相差不大。

数据移动次数是最少的

每次交换只会改变两个列表元素,因此长度为N的列表只会发生N次交换,交换次数和列表的长度是线性关系,其他算法都不具备这个特性。

适用场景

由于选择排序的对比次数在平方级别,但是移动次数在线性级别,所以当N比较小的时候比较适用。

其他

为什么选择排序不稳定呢?

首先我们要明白算法稳定是什么意思呢?

在待排序的数据中,存在多个相同的数据,经过排序之后,他们的相对顺序依旧保持不变,实际上就是说array[i]=array[j],i<j.就是array[i]在array[j]之前。

那么经过排序之后array[i]依旧在array[j]之前,那么这个排序算法稳定,否则,这个排序算法不稳定。

根据以上定义很容易可以得出这样的结论:

我们举出一个实例,序列5 8 5 2 9, 这个在执行选择排序的时候,第一遍,肯定会将array[0]=5,交换到2所在的位置,也就是 2 8 5 5 9。

那么很显然,之后的排序我们就会发现,array[2]中的5会出现在原先的array[0]之前,所以选择排序不是一个稳定的排序。

实现案例

c#

static void Main(string[] args)

{

List<int> data = new List<int>() ;

for (int i = 0; i < 10; i++)

{

data.Add(new Random(Guid.NewGuid().GetHashCode()).Next(1, 100));

}

//打印原始数组值

Console.WriteLine($"原始数据: {string.Join(",", data)}");

int n = data.Count;

//此处可以直接从第二个元素开始

for (int i = 1; i < n; i++)

{

//查找最小的元素的索引

for (int j = i; j>0  ; j--)

{

if (data[j] < data[j - 1])

{

//异或法 交换两个变量,不用临时变量

data[j] = data[j] ^ data[j-1];

data[j-1] = data[j] ^ data[j - 1];

data[j ] = data[j] ^ data[j - 1];

}

}

}

//打印排序后的数组

Console.WriteLine($"排序数据: {string.Join(",", data)}");

Console.Read();

}

运行结果:

  • 原始数据:97,85,61,22,62,12,67,22,68,42

  • 排序数据:12,22,22,42,61,62,67,68,85,97

作者简介:一个奔走在通往互联网更高之路的工程师,热衷于互联网技术。目前就职于某互联网教育公司,应用服务端主要负责人。拥有10年+互联网开发经验。热衷于高性能、高并发、分布式技术领域的研究。 主要工作语言为C#和Golang 。

推荐阅读:

  • 程序员是否应该创造面向 IDE 而非人类的编程语言?

  • 红黑树真的没你想的那么难!

  • 老大难的 Java ClassLoader,到了该彻底理解它的时候了

  • 老码农冒死揭开行业黑幕:如何编写无法维护的代码

  • 2018最后一战:25天编程PK赛!

  • 想让马云成为你的老大?揭秘阿里面试情景

  • 通证简史|从日进斗金到夹缝求存, 细数Token的前世今生

  • 如何用 Python 实现选择排序?

不懂算法的程序员不是好工程师!相关推荐

  1. 未来五年,不懂人工智能的程序员会被淘汰吗?

    前提摘要: 从PC到互联网.移动互联网.云计算.大数据,再到现在的人工智能.区块链,半个多世纪以来,人类科技正以前所未有的速度飞速迭代.紧跟潮流.看对方向的幸运者大多数都成为新时代的弄潮儿,而默守陈规 ...

  2. 未来五年,不懂人工智能的程序员不会被淘汰

    1. 话题背景 最近人工智能很火,区块链很火.都吹的上天的,工资非常高.空口无凭,来看看相关的数据. 薪资高,人才缺口大. 2.程序员的分类 程序员有很多工种,前端,后台,Android,java,c ...

  3. java metronic_不懂前端的程序员不是好美工——UI框架metronic使用教程——程序员视角...

    本着不懂前端的程序员不是好美工的观点,所以作为一个仅懂一点前端的程序员,为了成为一个好美工,所以只能用些取巧的方法伪装一下. metronic一个基于bootstrap的响应式的后台管理平台的UI框架 ...

  4. 【数据结构与算法】程序员们常用的10个关键数据结构,包括它们的原理和C语言实现代码

    [数据结构与算法]程序员们常用的10个关键数据结构,包括它们的原理和C语言实现代码 文章目录 [数据结构与算法]程序员们常用的10个关键数据结构,包括它们的原理和C语言实现代码 1. 数组 (Arra ...

  5. 老程序员告诉你人工智能工程师与Python工程师有什么区别?

    学习Python就等于学习人工智能吗?当然不!千万不要混淆它们的概念!Python工程师并不等同于人工智能工程师. Python工程师与人工智能工程师最根本的区别是什么? Python和JAVA.C语 ...

  6. 人工智能选go还是python_老程序员告诉你人工智能工程师与Python工程师有什么区别?-Go语言中文社区...

    学习Python就等于学习人工智能吗?当然不!千万不要混淆它们的概念!Python工程师并不等同于人工智能工程师. Python工程师与人工智能工程师最根本的区别是什么? Python和JAVA.C语 ...

  7. 纯软件程序员向嵌入式系统工程师转型时需注意的问题

    纯软件程序员向嵌入式系统工程师转型时需注意的问题 在中国,PC(主要是Windows-Intel体系)软件开发程序员,也就是"纯软件程序员"的"黄金年龄段"较短 ...

  8. 为什么“不懂数据结构与算法”的程序员一定走不远?

    踏上了编程之路,也就意味着你选择了一种终身学习的生活方式.每一个程序员都要练就十八般武艺,而掌握数据结构与算法就像修炼了九阳神功.换句话说,掌握了数据结构与算法,你的内功修炼速度就会有质的飞跃. &q ...

  9. 十大编程算法助程序员走上大神路

    概述:编程算法,是完成程序逻辑的主要途径.本文推荐十大编程算法,有利于程序员的编程逻辑. 算法一:快速排序算法 快速排序是由东尼·霍尔所发展的一种排序算法.在平均状况下,排序 n 个项目要Ο(n lo ...

最新文章

  1. java update set_mybatis update set 多个字段实例
  2. 在iOS的XCode工程配置中为什么要用-all_load-ObjC
  3. oracle主键跟踪,Oracle根据主键查找外键
  4. 反汇编最基础知识(段寄存器和寄存器的说明)
  5. 计算机硬件统的构成,计算机硬件统的构成部件.ppt
  6. python学习之数据类型(int,bool,str)
  7. 无法检索文件服务器,无服务器快速无法检索pdf文件(base64编码)
  8. Windows域环境下部署ISA Server 2006防火墙(二)
  9. OpenCV 2.4.8 or OpenCV 2.4.9组件结构全解析
  10. axure rp10安装教程,axurerp10安装步骤
  11. 数学建模2-美国人口增长模型的确定
  12. 金融风控建模评分卡系列:机器学习特征选择方法
  13. 让机器人更安全——(5.总结与展望)
  14. 360快捷方式右上角的软件更新图标实现
  15. android浏览器全屏设置分辨率,小屏幕大世界 傲游云浏览器Android全屏模式
  16. 关于家用路由器下挂多个设备包括下挂路由器的操作
  17. 软件开发详细设计说明书(转载)
  18. 玩转基因组浏览器之利用IGV查找motif结合位点
  19. C#,.net使用特性类,将json转为实体时验证字段
  20. 寒假总结 2020.02

热门文章

  1. 力扣--125验证回文串/680验证回文字符串II
  2. mysql 转int_MySQL索引凭什么能让查询效率提高这么多?
  3. yolo-tensorrt 运行 make报错 error: ‘int nvinfer1::MishPlugin marked ‘override’, but does not override
  4. rust笔记10 泛型处理
  5. QtCreator格式化代码---Beautifier插件使用方式
  6. Ubuntu18.04 命令行安装PyCharm
  7. 2021年中国动态内容交付市场趋势报告、技术动态创新及2027年市场预测
  8. android获取sd的大小,Android实现获取SD卡总容量,可用大小,机身内存总容量及可用大小的方法...
  9. 面向对象编程启思录——读《OOD启思录》有感
  10. 微软推出 Microsoft Build of OpenJDK 预览版!