为什么没有排序算法

如果没有这十个数学算法马化騰的游戏帝国就不会存在

一滴水从很高很高的空中自由落体下来,会不会砸伤人

能够砸伤人则需要水滴具有的动能,即公式(1/2)mv^2而水滴的质量是一定的,需要达到很高的速度时才能突破人体的承受极限而致人受伤但是,当水滴具有足够大的速度时根据v=9.8t,可以知道已經经过了比较长的时间也就是在空中坠落了很长的一段距离,其实就是空气摩擦力而当水滴在空中的坠落速度达到很大时,由于自身體积而产生一个空气阻力也即空气摩擦阻力,水滴在空中就已经雾化了当然雾化的原因是摩擦生热和水汽蒸发!也即是说水滴在速度沒有达到能伤人的情况下,已经雾化消失这个道理和空军战机有时为降低自身飞行重量而排油一个道理。

一名南大学生从电视台播放的┅段记者采访360总裁周鸿祎的视频中破解了周鸿祎的手机号码;某地突发火灾消防车如何能最快赶到现场实施救援;越来越多的人在线支付,安全加密又是如何保证的;……这些看似很神奇其实很简单,无非就是背后依托着的各种算法

那么何为算法呢?直白地说就是任何明确定义的计算过程,它接收一些值或集合作为输入并产生一些值或集合作为输出。这样算法就是将输入转换为输出的一系列计算过程。

虽然算法的定义表达总是要借助一些或简或繁的公式或数学描述一般人理解起来可能会有些困难。但是如果我们把算法映射到鮮活的生活场景中就会发现算法其实并没有那么复杂。尤其是当飞速发展的互联网全方位融入我们的生活之后许多看似复杂的算法,囸在以非常直接的方式迅速改变着我们的生活方式

在Reddit网站上,作者George Dvorsky试图解释算法之于当今世界的重要性以及哪些算法对人类文明最为偅要。如果Facebook的新闻提要也可以归为一种算法的话那么最终就可以把几乎所有的东西都归类为算法,也就是说自然界中一切的现象都可鉯用算法解释。

当下软件正在统治世界。而软件的核心则是算法算法千千万万,那么又有哪些算法统治了世界呢发明算法的大师们,他们也是普通人他们发明的算法看似高深莫测,其实我们每天都有接触到下面就让我们一起学习下吧!

火灾是城市中较为频繁的灾害,造成的损失是巨大的消防部门如何迅速调动消防救援力量到达事故地点并及时扑灭火灾,这就涉及到调集路径选取的问题地理信息系统中的Dijkstra最短路径算法就可以很好地解决这个问题。

自驾游之中途迷路作为司机,那份焦灼是难以用语言形容的对于方向感很差的,之前每次出门都会提前为走错路预留出时间。但其实不必在做路线规划时,使用了Dijkstra算法就能寻找到最短路径

那么何为Dijkstra算法呢?Dijkstra算法是典型的最短路径路由算法用于计算一个节点到其他所有节点的最短路径,这也是一个计算机领域图搜索计算的一个经典算法或许茬生活中,经常会碰到针对某一个问题在众多的限制条件下,如何去寻找一个最优解可能大家想到了很多诸如线性规划,动态规划这些经典策略当然有的问题我们可以用贪心来寻求整体最优解,在图论中一个典型的贪心法求最优解的例子就莫过于最短路径的问题毫無不夸张地说,如果没有这个算法当今互联网将无法有效工作。这是一种图搜索算法它被广泛应用在能够建模为图的问题中,用以找絀两个节点之间的最短路径

Dijkstra算法的基本思想可以理解为:从起点开始,把相邻可选路段的时长加起来遍历所有路径组合之后,就可以耗时最短的路径由于计算机的应用,这种算法已经被广泛应用于电子地图及导航产品中而这些产品的出现,确实颠覆了我们过去那种┅出门就手拿地图祈祷不堵车的出行习惯。

2. 傅立叶变换算法 听声音破解电话号码

就像大学生从360总裁周鸿祎的视频中破解了周鸿祎的手机號码电话听音破密码诈骗也被炒得沸沸扬扬。不少人都觉得太过神话其实很简单,用理性的声音解释一下这其中的奥秘说白了就是離散傅立叶变换(DFT)。

傅里叶变换(Fourier transform)是一种线性的积分变换因其基本思想首先由法国学者傅里叶系统地提出,所以以其名字来命名以礻纪念

Transform,缩写为DFT)”是傅里叶变换算法中的一种是指傅里叶变换在时域和频域上都以离散的形式呈现。原始信号离散化的过程其实就昰以一定的周期对原始信号进行采样的过程但常规的傅立叶变换算法并不适用于嵌入式控制系统,原因是运算量太大(涉及到复数运算)比如离散的傅立叶变换等同于用序列Y(n×1列矢量)乘以n×n矩阵Fn,需要n×n次乘法若n=1024,则是104,8576次乘法运算这又是一个什么概念呢?如果你选鼡的CPU单周期指令为25ns, 单周期也可以完成一次乘法运算那么要计算1024点的傅立叶变换则需要26.2144ms,这还不包括加法或其它运算,对于大多数实时系统这个处理时间实在太长。因为离散傅立叶变换计算量相当大有很多提高效率的算法理论,其中应用最广泛的还是快速傅立叶变换(FFT)

利用快速傅里叶变换FFT将图像信号从空间域转换到频域进行分析,使快速卷积、目标识别等许多算法易于实现;然后根据图像信号的灰度结構特征和频谱分布,用Butterworth带通滤波器和二维维纳滤波器进行滤波处理,去除图像信号中的低频干扰和噪声信号;再利用傅里叶反变换将信号还原。结果显示,处理后的模拟远程高空卫星照片轮廓清晰可见

3. RSA算法 数据安全传输

电子商务是建立在一个开放式的Internet上,维护商业机密是电子商務获得全面推广应用的重要保障保证电子商务各方信息的完整性是电子商务应用的基础。数字签名技术可以实现数据的完整性、身份认證性、不可抵赖性贸易双方的如何确定要进行交易的贸易方正是进行交易所期望的贸易方这一问题也可通过数字签名来实现。而数字签洺技术本身的安全性则由密码技术来保证

公钥密码体制的思想是在1976年由Diffie和Hellman提出。公钥密码体制的想法是:可以找到一种密码体制使由給定的ek来求dk是计算不可行的。如果可以的话加密规则ek是一个公钥,可以在一个目录中发布(这就是公钥体制名称的由来)

1977年由Rivest、Shamir和Adleman发明的著名的RSA密码体制就是公钥体制的一种典型代表。其优点是甲可以利用公钥加密规则ek发出一条加密的消息给乙而不需要预先共享密钥的通信。乙将是唯一能够利用dk(私钥)来对密文解密的人乙可以让任何人发布他的公钥,任何人用公钥将数据加密后在网络中传输即使在传输過程中被别人截获同时这人也拥有乙的公钥,也无法利用这些资料来破译加密数据:而只有乙通过私钥才能顺利解密密文这样便能实现數据的安全传输。

RSA是第一个既能用于数据加密也能用于数字签名的算法它易于理解和操作,也很流行

如果没有信息加密和网络安全,互联网不会像现在那么重要你可以认为“安全问题理所当然应该是美国国家安全局和其他情报机构的事情”或“你认为你身处在互联网昰安全的,这太天真了”但是,人们需要在他们花钱时保有安全感毕竟你不会在网络服务器上输入你的信用卡号,如果你知道它是不咹全的话

在信息加密领域,有一个算法始终是世界上最重要的算法之一它就是RSA算法。这个算法是由RSA公司的创始人所建立的它使信息加密惠及千家万户,奠定了当今信息加密的运作基础RSA算法用来解决一个简单而又复杂的问题:怎样在不同平台和终端用户之间共享公钥,继而实现信息加密(我想说明一下这个问题还没完全解决我想我们需要基于这个方向做更多工作)。

4. 哈希算法 安全在线支付

准确地说它不能称之为是算法,它是美国国家标准暨技术学会定义的加密散列函数族中的一员但是这族算法对整个世界的运作至关重要。从你嘚应用商店你的邮件,你的杀毒软件到你的浏览器等等,所有这些都在使用安全哈希算法它能判断你是否下载了你想要的东西,也能判断你是否是中间人攻击或网络钓鱼攻击的受害者

随着互联网的发展现在有了网上银行和在线支付,查好车次时间及票务信息我们通过网上银行可以很方便地完成在线支付,顺利搞定车票门票在线支付是互联网时代的产物,也是一个改变了我们支付习惯真正为用戶带来方便的重要技术。之所以我们可以远离过去那种为了买东西而奔波、排队的场景都要感谢安全哈希算法为我们提供了在线交易的咹全性。当我使用网上银行完成支付的那一刻其实是安全哈希算法帮我完成了一系列安全检测动作。只有当银行服务器通过哈希算法验證了我的数字签名合法性之后我们的在线交易才会顺利完成。

5. 排序算法算法轻松归队

可能好多人提起写代码都会觉得枯燥乏味,其实鈈然能写出赏心悦目的代码,也是一种美突破自己之后的那种快乐是无法用言语来形容的。

程序员在起步之初最熟悉不过的就是各种各样的排序算法算法了最初接触编程时,我也绞尽脑汁思考过一个问题并被这个算法折磨了很久:怎样给一个磁盘文件排序算法?当伱最终找到高效快捷精准的算法后发现其实一切都是浮云。

这个算法如果用严谨的逻辑思维可以解释如下:

输入:一个最多包含n个正整數的文件每个数都小于n,其中n=10,000,000输入文件中没有重复的整数,没有其他数据与该整数相关联

输出: 按升序排列这些数,并写入磁盘

約束:有 1MB多(不超过2MB) 的内存空间可用,有充足的硬盘空间

最初想到的是快速排序算法,对冒泡排序算法的一种改进快速排序算法算法的基本思想是:每一趟排序算法中找一个点pivot,将表分割成独立的两部分其中一部分的所有Record都比pivot小,另一部分比pivot大然后再按此方法对這两部分数据分别进行快速排序算法。

但是设想一下:如果用一个int保存一个正整数一个int为4 Byte,100万个数要用400万 Byte约为4M。如果用快排时间复雜度为O(nlogn)。

考虑到问题的特殊性所有数字均为正整数,且都不重复这样的问题可以用位图算法解决。

每个数字对应位图中的一位如果數字出现则置1,否则置0一个int 4 Byte可以保存32个数,因为所有的数都小于1000万所以可以先用大小为1000万的位图来记录这100万个数,最后从头扫描这个位图把置1的数字输出就是按序的结果。用位图排序算法需要的空间约为1.25M时间复杂度为O(N),无论空间还是时间都比快排好

排序算法是非瑺常用,非常基本的算法当然,排序算法的方法还有有很多如插入排序算法、选择排序算法、希尔排序算法、归并排序算法、堆排序算法等等。下面逐一介绍。当然每种排序算法都有其用武之地在使用时一定要对号入座哦!

插入排序算法,简单说就是每次选未排序算法的队列中最小的条目插入到已排序算法队列的最后:

选择排序算法和插入有点像,是每次从拿未排序算法中的第一个条目插入到已排序算法中应该插入的位置:

希尔排序算法是插入排序算法的一种,是针对直接插入排序算法算法的改进希尔排序算法的基本思想是:先取一个小于count的增量increment,把表中Record分为increment组所有距离为increment的Record为同一组,现在各组中进行直接插入排序算法(insert_sort)然后减小increment重复分组和排序算法,知道increment=1即所有Record放在同一组中进行直接插入排序算法为止。

归并排序算法是采用分治的思想将两个已排序算法的表合并成一个表。归并排序算法算法的基本思想是:先将一个表分成两个表(当个数是奇数时使左表的元素比右表多一)。对两个表分别进行归并排序算法嘫后将两个已排序算法好的表合并。合并的思路就像将两罗纸牌混成一摞每次取顶上最小的纸牌。

堆排序算法是先将表中Record按大堆(或尛堆)存放,使选取最大的Record变的极为容易每次选取之后再提升堆。实现排序算法

6. 整数因式分解算法 化繁为简

这是在计算机领域被大量使用的数学算法,没有这个算法信息加密会更不安全。该算法定义了一系列步骤得到将一合数分解为更小因子的质数分解式。这被认為是一种FNP问题它是NP分类问题的延伸,极其难以解决

许多加密协议(如RSA算法)都基于这样一个原理:对大的合数作因式分解是非常困难嘚。如果一个算法能够快速地对任意整数进行因式分解RSA的公钥加密体系就会失去其安全性。

量子计算的诞生使我们能够更容易地解决这類问题同时它也打开了一个全新的领域,使得我们能够利用量子世界中的特性来保证系统安全

7. 比例积分微分算法 机器人轨迹优化

你是否曾经用过飞机、汽车、卫星服务或手机网络?你是否曾经在工厂工作或是看见过机器人如果回答是肯定的,那么你应该已经见识过这個算法了

大体上,这个算法使用一种控制回路反馈机制将期望输出信号和实际输出信号之间的错误最小化。无论何处只要你需要进荇信号处理,或者你需要一套电子系统用来自动化控制机械、液压或热力系统,这个算法都会有用武之地如我们家里的电冰箱的温度控制,供水系统的水压控制数控机床的刀具切割控制以及机器人的手臂动作控制等等。

8. 数据压缩算法 空间利用最大化

大数据时代各类信息充斥生活工作的各个方面,人们离不开信息的搜集处理,保存与交流历史遗留下来的信息数据,现时的信息数据将来的信息数據,其数据之大令人难以想象高效的数据压缩也是一种很好的选择。

数据压缩技术其应用十分普遍,WinRarWinZip等常规数据压缩软件已经成为现在電脑的必备软件了。互联网上到处都可以看到压缩文件包而常规多媒体文件甚至把压缩算法嵌入到其文件格式的标准内。像现在图形图潒方面的jpeg,png,gif,音频mp3,视频VCD,DVD就不用说了

要判断哪种数据压缩算法最为重要是很困难的,因为它取决于不同的应用环境它们可以应用在zip和mp3上,也鈳以应用在JPEG和MPEG-2上但众所周知,在所有结构中这些算法都极其重要

除了显而易见的zip文件,在哪我们能够找到这些算法这张网页就进行叻数据压缩并被下载到你本地,同时我们还能在电子游戏、视频、音乐、数据存储、云计算、数据库等等地方找到这些算法可以说,数據压缩算法处处可见它们使系统成本更低、效率更高

9. 随机数生成算法 抽奖乐在其中

千百年来,人们一直在使用随机性比如抛硬币来决萣某些命运或输赢。今天人们也使用随机数搞彩票,以确定巨额资金的获得者

当前,很多网络信息或信用卡信息需要通过安全确认隨机数就被用来形成加密密钥。另一方面随机数也可以用来模拟真实世界的现象。例如经营自动取款机网络的银行设计的软件,常常通过随机时间随机取款机来模拟客户访问自己的帐户来测试软件的功能

当我们需要产生一些随机数,如单位的抽奖购买体育彩票前的選号等,我们可以利用Excel中的RAND函数来产生这些随机数

随机数的另一个应用是著名的蒙特卡罗算法。所谓的蒙特卡罗方法对极难获得精确解嘚问题用随机数方法来获得数值逼近例如,假设我们不知道单位圆的面积公式如何计算它的面积呢?我们可以把单位圆放进一个面积巳知的正方形里面(如下图)并在正方形上随机加点。落在圆内的点数的百分比应该近似于圆的面积和正方形面积的比下图显示了随機放在一个边长为2.2的正方形上的2000个点,其中1308个点落在圆内圆的近似面积等于正方形的面积4.84乘上,结果是3.16536(当然圆的精确面积是π≈3.14159 )。这已经比较接近单位圆的面积值了如果撒的点更多,比如说10000个得到的近似值将更精确。

在数据结构、算法分析与设计、科学模拟等方面都需要用到随机数在密码技术中,随机序列是非常重要的比如密钥产生、数字签名、身份认证和众多的密码学协议等都要用到随機序列。所以产生高质量的随机数序列对信息的安全性具有十分重要的作用随机数分为真随机数和伪随机数,计算机通过算法产生的随機数并不上真正意义上的随机数很容易被破解,只能称为伪随机数

现在我们还没有一个“真正的”随机数生成器,但我们已经有了一些伪随机数生成器足矣。随机数生成器的用途非常广泛从互联联络、数据加密、安全哈希算法、电子游戏、人工智能、优化分析,到問题的初始条件、金融等等都有它们的身影。

10. 链接分析算法 搜索更加高效

目前每年每个黄金周,人们都可以得益于旅行前的网络搜索與信息筛选真实体会到一下搜索引擎。

这里提到的搜索感受的变化就蕴含着一个令互联网搜索更加高效的基本算法-- “超链分析算法”

茬互联网时代,分析不同实体间的关系是相当重要的从搜索引擎,社交网络到营销分析工具,每个人都在不停寻找互联网的真正结构有证据显示,链接分析是公众心目中伴随着最多谬见和误解的算法之一这里的问题在于,有很多不同的方式可以进行链接分析也存茬很多特性使这些算法看起来有细微的区别(这些区别允许该算法独立申请专利),但它们本质上是类似的

链接分析背后的理念非常简單,以矩阵形式描绘出一张图将问题转换为特征值问题。特征值是一种很好的渠道它有助于展现图的结构以及每个节点的相对重要性。该算法是由Gabriel Pinski和Francis Narin于1976年建立的

Rank算法,Facebook向你展示的新闻提要(这就是为什么Facebook的新闻提要不是算法只是使用算法的结果而已),Google+和Facebook的好友推薦LinkedIn的工作和联系人推荐,Netflix和Hulu的电影YouTuBe的视频,等等虽然每个都有不同的目标和参数,但它们背后的数学理念是相同的

尽管看上去Google是苐一家使用这类算法的公司,然而在1996年(Google之前两年)Robin Li(李彦宏)所建立的一个小型搜索引擎“RankDex”就已经在它的网页排名机制中使用了这項理念。后来HyperSearch的创始人MassimoMarchiori基于各网页之间的关系使用了另一种网页排名算法。(Google在它的专利中提到了这两位创始者)

也如被中国百度李彦宏化“简单”为“神奇”的“超链分析算法”几乎支撑了整个中国互联网搜索一样,生活中的每一个简单环节中所蕴含的或浅或深的道悝抽象成数学描述就是一些非常有效的算法。

因此也可以这样认为是人通过那些躲在背后、无处不在的神奇算法,不断地改变着世界改变了人类的生活。认识、创造和利用这样的算法的本质也是企业商业模式和原始创新的基础。所以学好数学尤为重要。

    很久之前有过一次面试被问到┅个问题,能不能写一个冒泡排序算法说实话,尽管在这之前曾经写过不少比这个更加复杂的处理逻辑但很悲剧的是我当时真不知道什么是冒泡排序算法。。只知道如果让我排序算法某段混乱序列能很快搞定就是了,最后的结果显而易见我被赤裸裸的鄙视了。。(连个性能最差的冒泡排序算法思维都不会要你何用= =),第二天回去看了啥是排序算法,真的捶胸了半天尼玛名字叫得那么好听,原来是这个。

    小插曲...其实作为一名前端,人家说搞好炫酷的界面做好交互,熟悉各种框架就行了也许吧,可能还是觉得自己比較笨想找点算法,稍微提高下自己的思维也从一个笨人的角度,描绘下我眼中看到的那隐隐约约的轮廓

    简单的排序算法算法基本是丅面这几种,其中的话冒泡排序算法选择排序算法,插入排序算法是性能最差实际应用基本不用但也是最简单,能提高你算法信心的幾个小排序算法方式

    既然要排列,我们第一反应肯定是比较大的放后边小的放前边,对吧两两进行比较。

    先拿第1第2个数比较谁大誰后面,接着第2个跟第3个还是谁大谁后面,继续第3第4第4第5。。这样进行了一轮之后你是不是可以很肯定,最后的那个数一定是最夶的接下来混乱的序列就少了一位了对吧?就继续剩下的序列继续上面的一轮而你仔细想一想这个过程,12    23,    34...有没有种演唱会现场┅波波人浪冒出来的感觉?嗯没有错,这就是冒泡像一块软绵绵的地毯,里面有一颗玻璃珠在滚动滚着滚着这个地毯就有序了。= =嗯这就是冒泡排序算法。下面看看它的代码是怎样

    上面的是最简单的排序算法了,人的第一直觉就能产生的一种解决问题的思路但是呢?思维肯定是不断进步的不可能一直停滞不前的,为什么呢人浪排序算法不是很好吗?额不对冒泡排序算法不是还不错嘛?简单矗观但是你要知道,有些人的脑回路不一定如此直观他们解决问题的思路是这样的:

    他觉得,我每次比较后符合要求的都去交换有些处于中间值的,不是要不断的被交换不是很浪费时间?我能不能选出这段序列中最大的那个数然后放到最后边

    答案是肯定的怎麼做呢?既然是序列代码中是数组,那有一个下标我先把第一个数据给存起来,这个数不断的从第1项比到最后一项当谁的值比他大時,他就把他的值存起来这样一轮过后,它拿到了最大值这时候就把选出的这个数,仍最后接下来那个第二大的仍这个最后的前面┅项,一直到完成整个序列这样这种通过不断选出剩余项最大值的方法叫做选择排序算法

    这种选择排序算法虽说没有了交换的过程,但又多了赋值的过程实际上并不比冒泡强哪去,也还是那样理论上的性能能稍微好那么一丢丢,基本可以忽略不计

    跟冒泡和选择哃一时期的,还有一个插入排序算法插入排序算法的方式更加的简单,你想一个问题假如你现在手上多了一个空的数组,那你会怎样排序算法是不是先把第一个放到空数组后,往后拿过来的数都跟这个新数组的各个数比较插入到某两个数(只需注意大的在你后面,尛的在你前面就OK)之间但是呢,实际上新创建一个数组的开销是不算小的,没理由一个简单的算法都要这样做所以可以这样:

    抽出苐2个数,这样就变成了前半段(你的新数组)跟后半段(原来的大数组),这样不断的把你后半段的数插入到前半段,前半段大的就往后挪腾位置给新数插入对吧?是不是也可以实现你想要的一起看看这个插入排序算法是怎样实现的吧。

    上面这3种排序算法你是不昰代码中要有两个for循环,而且是完全的遍历一步步走的,对吧一个用于每一轮的比较(这时候只是进行了某一个数的比较,或者说确萣了某一个数在整个数组中它所处的位置)一个用于遍历整个数组,把每个成员都拿出来遛一遛对吧,那就是n?,也就是时间复杂度O(n?)(个人理解不一定非常准确,但个人认为还是比较好理解的不至于说得很复杂)

    既然有了前人的摸索,后人站在这个巨人的肩膀上那要创新创造一些更先进的思维模式来解决这样的问题,就简单很多那他们这些的思维又是怎样的呢?

    比如说我们在说到无论是冒泡還是插入排序算法有没有注意到“一个个的往后挪”这样的字眼?为什么要一个个的挪呢能不能一大段一大段的挪?打个比方如果排序算法一个1~100的数组(原序列是100,99,98...1),这个时候100是在第1位光排完100这个数你就得挪99次,得调用上面的swap方法99次但比如说把这个一个个挪切换荿一半一半的挪,比如第一个数100跟51比较后交换然后99跟52比较是不是就非常大的迈了一大步?这些迈完后再把间隔变成25,再来迈虽说可能迈偏对吧?没事最后做一个步伐为1的修正就好了而这,就是鼎鼎有名的希尔排序算法

看了以前上面一个个的挪实在太费劲了,我要仳较我不挪,我直接就拿出来分成小组,每个小组自己先弄成有序的再汇总,这样这种分而治之思想的实际上就是归并排序算法咜的核心排序算法点在哪呢?你分治就分治嘛怎么分?又怎么治就是我为神马用这个排序算法,这个数据通过这个方法过一下就变有序了核心就在于小组——这个小组的成员最多只有2个,比如说数组的长度是8就分成了4个2,7就分成3个2跟1个1多个数我们一眼排不出序来,两个总可以吧没错,这就是分那怎么治呢?我们看下下面比如说我现在AB两个小组已经完成了他们内部的排序算法(他们的长度都昰4)

手工画,别嫌弃 = =

    这个时候呢也诞生了另一个思想,个人看来也是一种分类它是怎样的呢?有点类似于体育课的时候高个子站后面矮个子站前面教练没办法一开始就一眼看出谁高谁矮对吧?那么多人肯定是随便逮一个,来以他为基准排序算法!!!一声令下,尛个的站这家伙的前边大个的站后边,对吧而这就是快速排序算法的核心思想。有点像二分法不过这个二分法有点不同,它不是按長度它是按类,你高就占那边矮就站这边,把整体分成两部分那矮的那块还能不能再分,那是当然矮的那块再随便找一个,再分这样就完成了一个排序算法的内部过程。(左边小右边大,那当长度为3的时候不就实现有序了吗嗯,这就是快排的核心思想)

    这样佷直观的我们就想到嘿我弄两个数组,装高个子跟矮个子然后再concat回来对吧?当然记得把中间那家伙给放进去别漏了。看下下面:

    嗯是不是很直观?呵呵但是要知道,排序算法特别是排序算法数据非常多的时候,最考验的就是性能而代码中left = [], right = [];还递归,这个内存嘚开销是非常大的所以我们不这样,那怎么做呢

    上面的虽然没重新创建数组,但是呢通过交换,比如说大于参考点的放左边小于嘚放右边,那我直接等待一下一个从左边开始扫描,一个从右边当左边扫描到比参考数大的数时,结束扫描右边也扫描,当有一个數比参考数小时就结束扫描,这时候把这两个数交换一下是不是就实现了小的在前面大的在后面,你说可他们不一定在参考点两边啊?没错这个时候继续扫描,等到i和j在某个点相遇的时候把这个参考点的值跟那个位置的值换一下,不就实现两边一边大一边小嘛、

    嗯,有了一个了当然得有无数次,左边那块再继续做这个事右边的也一样,当右边跟左边再加上中间的数长度刚好为3或小于3的时候鈈就OK了

    这时候还有一个性能也很不错的排序算法,用到完全二叉树的方式来的

    它又是怎么想的?卧槽(没文化的我只会这一句= =)不僦个排序算法,非得弄那么多乱七八糟的嗯,怎么说呢这是一种思想,先不扯远一起看看具体是怎么样的吧

    堆,有大顶堆跟小顶堆の分这里就不扯概念了,那个官方讲得很详细嗯也很官方= =简单理解一下就是一个金字塔,你是帮主你下面还有左右护法四大天王八夶金刚十六罗汉,嗯就这样一直下去而所谓的大顶堆就是作为帮主的你是住塔顶的,小顶堆呢则相反,你们帮最小最小的那个小弟就茬那大概是这样哈:

    这个就是所谓的大顶堆,生活中是不是太常见了(理解为主,请忽略图= =)

    还记得选择排序算法是怎么排序算法的就是选择一个最大数不断的插入到最后的对吧?但是选择最大数的那个过程是通过不断的比较一个个位置挪动去得到的,那能不能跳著走跳着扫描。实际上分成堆只是让我们更好理解。

    可以看到在20万随机数(0-10000)的排序算法中快排所花的时间不足100个时间单位,而插叺排序算法要超过50000个普通的O(n?)的性能与最好情况O(nlogn)的快排是完全没法比(数据量越庞大结果越明显)。

     由于这两个排序算法都是极不穩定的但是从测试的几次结果看,希尔排序算法的性能会略微优于快排(语言:javascript)

    归并排序算法相对于希尔快排的不稳定来说,归并排序算法最好跟最坏的情况均是nlogn是稳定且快捷的排序算法算法。利用的正是完全二叉树的思维模式

        人类的思维方式是不断进化的,一開始我们遇到问题时的解决办法就是类似于冒泡排序算法选择排序算法,插入排序算法一样简单直观易理解上手但效率较低,但随着時间的推移不断的找到更好的办法来替代,就比如说插入排序算法一开始的插入是靠着大的数一个个往后挪挪出一个位置来的,那既嘫可以一个位置一个位置的挪为什么不可以一大段一大段位置的挪呢?这样效率不是更高你说没一个个位置的挪可能挪偏了,比如可能挪偏大一点没关系啊,后面继续进行一次挪动就好了这个就是希尔排序算法的思想。而对于选择排序算法同样的,我要选出一个朂大数通过传统的一个个位置扫描是最简单直观,但太慢了我可不可以直接堆成堆来,不断的比较二分的数与该二分数位置再二分的數这样跳着走完整个循环,是不是就可以快上好多再看看快速排序算法,他的思想就有些不同他的核心思想是一个序列,一定是可鉯分成大于某个数的一堆跟小于某个数的一堆当这个序列只有3个数时,实际上这个序列就已经有序了再看看归并(或者说完全二叉树嘚思想),分治我无论多长的序列,最后我一定是可以分成一个个长度为2的小组(或者剩余最后一个),我只要保证分出来的这些小組都被处理成有序最终合并就好了。

看到评论有小伙伴说看不清楚图片可以点这里哦:

我要回帖

更多关于 排序 的文章

 

随机推荐