为什么要学习排序算法?

根据统计,早起大型机CPU资源的四分之一都花在了数据排序上面。排序算法作为最基础的算法,各种操作系统、编程语言都提供了内置的实现。既然排序实现随处可见,我们为什么还要自己动手实现呢?虽然经典算法要动手写写加深印象的道理都懂,但直到最近才发现,每种排序算法里都“暗藏玄机”。排序算法看似简单,其实不同的算法中蕴涵着经典的算法策略。通过熟练掌握排序算法,就可以掌握基本的算法设计思想,包括暴力枚举法、时间空间置换、子问题的分治以及随机化。


1.选择排序:暴力搜索

1.1 “暴力”的定义

按照Wikipedia的定义,暴力搜索也叫穷举法。它是一种常用的解决问题策略或者算法范式,通过系统化产生所有可能解来找到最终答案:

In computer science, brute-force search or exhaustive search, also known as generate and test, is a very general problem-solving technique and algorithmic paradigm that consists of systematically enumerating all possible candidates for the solution and checking whether each candidate satisfies the problem’s statement.

所谓“暴力”是指“Just do it”。需要注意的是所有解空间是来自问题定义,而非来自输入数据的所有排列组合。按照《The Design & Analysis of Algorithms》一书的定义,暴力搜索就是一种基于问题定义的、最直接的解决问题方法(“usually directly based on the problem’s statement and definitions of the concepts involved”)。

1.2 例子

比如来自Leetcode经典的2 Sum问题,问题定义里说要找到两数之和等于某值,此处暴力搜索即为穷举输入数据中所有两个数可能的组合,然后找到符合条件的一对或者多对。所以,假设输入数据规模为N(比如长度为N的数组),搜索空间只是从N个数里取出两个数的组合。类似地,线性查找最小值、查找子字符串、查找平面上最近的两个点,都可以根据问题的定义直接得到算法实现。


2.堆排序:时间空间trade-off

2.1 简介

时间和空间置换(Time and space trade-off),即用额外的空间(通常是一种高效的数据结构)来换取之后更快的处理。 其实本质上,堆排序=选择排序+堆数据结构,通过花费额外的空间,来优化“选择”这个动作。这样每次选择剩余数据中最小值的操作,其时间复杂度就从原来的线性N降低到LogN。

2.2 预处理 vs 即时维护

除了像上面堆排序,数据结构预先初始化,将解题步骤分为两阶段,也可以在执行过程中,一边执行一边维护,只要保证当前所需的数据都在结构里即可。比如,还是这个经典的2 Sum问题。如果数组未排序的话,我们可以用哈希表来记录其他元素,从而省去暴力搜索时的内层循环。哈希表可以预先初始化,也可以一边遍历数组一边维护。


3.插入排序:减而治之

所谓的减而治之(Decrease-and-Conquer),也就是增量法。要解决输入规模为N的问题,我们先解决规模为N-1的子问题,然后思考如何利用N-1的解和当前数据得到N的解。在这个过程,其实我们一直在维护一个不变量(Invariant),从而保证了所有数据处理结束后结果的正确性。根据问题规模缩减的速度,可以分为常量递减和变量递减两种方式

3.1 常量递减

常量递减(Decrease-by-a-constant-factor)即问题规模以固定的速度缩减,比如:

  • 插入排序
  • 产生排列组合:同插入排序一样
  • 二分查找:每次减半

3.2 变量递减

变量递减(Decrease-by-a-variable-factor)每次问题规模缩减的程度可变:

  • 找中位数:递减程度由选取的分区元素决定。
  • 插值查找(Interpolation search):二分查找不考虑查找值的特点,每次都折半。而插值排序根据分区的第一个、最后一个值以及要查找的值,选取一个更靠前或者靠后的值来比较。这种思想类似于在电话簿里查找一个人的电话,假如名字是A开头,则更高效的方式不是翻到中间,而是电话薄的前面。

4.归并排序:分而治之

4.1 简介

与减而治之类似,分而治之(Divide-and-Conquer)将问题一分为二,解决两个子问题后再考虑如何合并得到最终结果。

4.2 “分”和“治”

分而治之两个最重要的例子就是归并排序和快速排序。有趣的是,两者在“分”和“治”上有着完全相反的实现比重。前者重在合并,划分几乎没有额外逻辑;而后者则重在划分,合并时没有额外动作。


5.快速排序:随机化

平均情况下,快速排序的时间复杂度很不错。然后最坏情况下,它却可能恶化到与插入排序差不多的N平方。算法设计里另一种重要的思想就是利用随机化,从概率上保证最坏的情况不会发生。比如对于快速排序来说,可以随机选取,或者采样后决定要用哪个值来做划分。

为什么要学习排序算法?相关推荐

  1. 【排序算法】插入、选择、堆排、快排、归并、计数

    一.插入排序 insertSort 1.实现 2.性能分析 3.折半插入排序(了解) 二.希尔排序 ShellSort 1.原理 2.实现 3.性能分析 三.选择排序 selectSort 1.原理 ...

  2. 作为程序员,你一定要知道的十大经典排序算法!(详细解析)

    十大排序算法可以说是每个程序员都必须得掌握的了,花了一天的时间把代码实现且整理了一下,为了方便大家学习,我把它整理成一篇文章,每种算法会有简单的算法思想描述,为了方便大家理解,我还找来了动图演示:这还 ...

  3. 数据结构的六大排序算法详解

    文章目录 一.简单排序 1.Comparable接口介绍 2.冒泡排序 3.选择排序 4.插入排序 二.高级排序 1.希尔排序 2.归并排序 3.快速排序 4.排序的稳定性 一.简单排序 在我们的程序 ...

  4. 【C语言】八大排序算法

    文章目录 1.排序的概念及其应用 1.1排序的概念 1.2排序的应用 1.3常见的排序算法 1.4时间性能的测试(测试排序算法的好坏) 2.常见排序算法的实现 2.1直接插入排序 2.2希尔排序 2. ...

  5. 【js排序算法】--基础排序算法

    前言 前端的代码运行环境本来就不善于处理大量的数据计算,前端也有很多东西比算法重要.那我们为什么要学习算法? 明确学习和使用算法的目的. 一个排序功能,用冒泡排序法,归并排序法,快速排序法?who t ...

  6. 《数据结构与算法》(二十五)- 排序算法:快速排序

    目录 前言 1. 快速排序 1.1 快速排序算法 1.2 快速排序算法复杂度分析 1.3 快速排序优化 2. 总结 原文地址:https://program-park.github.io/2021/1 ...

  7. 基于使用学习排序算法的Web服务学习的个性化的决策战略

    摘要----为了从类似的服务列表中进行功能上的选择,用户往往需要根据多个QoS准则做出他们的决定,它们需要对目标服务.在这个过程中,不同的用户可能遵循不同的决策策略,有些是补偿性的,在这个补偿中在所有 ...

  8. 伍六七带你学算法 进阶篇-排序算法

    给定一个整数数组 nums,将该数组升序排列. 示例 1: 输入:[5,2,3,1] 输出:[1,2,3,5] 示例 2: 输入:[5,1,1,2,0,0] 输出:[0,0,1,1,2,5] 各排序算 ...

  9. C++排序算法实现(更新中)

    比较排序法:如冒泡排序.简单选择排序.合并排序.快速排序.其最优的时间复杂度为O(nlogn). 其他排序法:如桶排序.基数排序等.时间复杂度可以达到O(n).但试用范围有要求. 桶排序:排序的数组元 ...

最新文章

  1. Linux SVN命令详解
  2. 南云等PNAS研究论文:揭示儿童音乐学习向语言领域迁移的脑机制
  3. 用Google App Engine做个人代理服务器
  4. vs code打开新的文件后旧的文件被顶掉
  5. 2017.3.14 不重复数字 思考记录
  6. Linux查看CPU信息机器型号等硬件信息
  7. QQ认证空间已升级QQ公众空间,申请地址是?
  8. exchange批量创建用户邮箱
  9. 庞加莱猜想的证明过程
  10. 企业微信周末加班怎么打卡?
  11. 软件测试使用linux做什么?
  12. 程序员面试前只因为做了这几件事,成功征服了一系列大厂面试官。
  13. Java工具-根据出生年月日计算出年龄
  14. vue-cli热更新 失效
  15. 服务器厂商对VMware vSphere的驱动支持
  16. Android QQ空间(Apad)项目总结(三)---应用UI框架的搭建!!!
  17. 万字长文,会员体系拆解
  18. SpringBoot-quartz配置页面可视化任务调度
  19. python led屏控制_【教程】简易Python上位机之LED控制
  20. YUV YPbPr YCbCr CCIR 601 CCIR 656

热门文章

  1. 《嫌疑犯x的献身》看完了。。。
  2. 铟镓砷探测器-主要厂商产品特点、产品规格、价格、销量、销售收入及市场现状
  3. polygon java_JAVA Polygon 在配送区域超区校验的实践
  4. 面向未来,我们来聊一聊什么是现代化数据架构
  5. 主要视频压缩技术在中国内地市场发展分析
  6. 联想ThinkPad安装windows7系统详细图文教程
  7. Little Red Riding Hood(动态规划)
  8. centos7 qemu -- 03 使用KVM虚拟机遇到的问题
  9. 移动端 - Android客户端性能测试常见指标
  10. 创新易死需要勇气 需要抵御“抄袭”心魔