美文网首页
给一万个士兵排个序---基础排序算法随记

给一万个士兵排个序---基础排序算法随记

作者: 三眼卡夫卡a | 来源:发表于2018-10-24 16:01 被阅读0次

不想当将军的士兵,不是好士兵。不了解算法的程序员也不是好的程序员。

                                                                                    by   尼古拉斯---彦祖

首先给上一张,实验环境下,各个排序算法的时间效率对比。

实验环境下的排序结果

一  简单概念

    算法频率度即一个算法中的语句执行次数称为语句频度或时间频度。记为T(n)

    时间复杂度以大O表示法 常见的有四种:

    O(1)、O(n)、O(logn)、O(n²)分别可以称为常数阶线性阶对数阶平方阶

二  快速排序

    取某一位(一般是首位)作为flag. 分治法排序。

    每一趟的下标都是前后同时进行,比flag小的放到左边,比flag大的放到右边。结束条件为前后下标重合。

    一趟排序可以得到以flag为界限的 两个集合。依次递归,结束条件为不可再分。

    换句话说:  现在要给一万个排成一列的士兵 按照大小个排队。  

    首先取第一个士兵的高度为标准,称其为flag,一趟算法的期望运行结果,就是所有比这个士兵低的人在这个士兵前面,所有比这个士兵高的人都在他后面。

    那么,怎么实现这个效果呢?? 

    找两个将军来,一个站在列首,一个站在列尾。

    列尾的将军,站在第10000个士兵这个位置,看看他比flag高,还是低,如果高那么不管,列尾的将军向前走一步。 走到第9999个士兵处,继续比较,直到走到一个比flag低的士兵位置。比如第9996个士兵比第一个士兵低,那么让 9996和 1 互换位置。     此时的flag的位置变成了9996

    现在列尾的将军先休息,让列首的将军从2这个位置向前走,走到第一个比flag高的位置,比如是第15个。 那就让15 和9996换位置,并且更新flag为15。此时列首将军休息,列尾的将军继续。  以此类推。

直到列首和列尾的将军碰了面,那么本趟快排结束。 

比如此时的位置是6666个士兵处。根据上面的过程推论,此时flag也一定在6666处。两个将军不碰面也正是快速排序的特点

那么本趟排序完成。 整个队列被6666分成了两个A B队列,前面的一定比士兵flag矮小,后面的一定比flag高大。

然后再请四位将军过来对,这AB两个队列进行上述操作。直到队列变成2个人(不可再分割)。以此类推

快排执行效率 快排源码实现

三   选择排序

    与冒泡排序类似,但是区别在于,新建局部变量储存本趟的目标值。

    每次只比较而不交换,直到一趟排序结束之后。才进行转换,提升了部分效率

    还是那一列一万个士兵的队伍。 

    一个将军拿着一个笔记本,

    从第一个开始问,你身高多少? “1.60”   看来你是最低的,于是他将第一个士兵的名字写到了笔记本上。

    第二个 “你身高多高”    “185”     不管,下一个

    第三个问“你身高多少”“158”        将军,划掉了上一个名字,记上了最新的这个人的名字。

    直到问完整个队伍。  将军看到笔记本上写着  最低的那个人的名字   “提利昂-兰尼斯特”  你站到第一个位置。

    这是一趟排序结束。

     接下来,将军从第二个位置开始问。(第一个已经确定了)以此类推,直到最后一个。

    

选择排序比冒泡排序快很多     选择排序实现

四  插入排序

    4.1 简单插入排序

        简单插入排序的核心思想是认为,所有的事情都是基于一个已有序的序列进行的。

        比如下标从第一个元素开始,认为  第一个元素本身是一个有序序列(这是对的,因为只有一个元素。)

        那么下标转移到第二个元素,将第二个元素 去与左边的有序序列(第一个元素)比较,插入到合适的位置。

        下标继续,逻辑依然如此,直到下标行走到最后的位置。整个序列都有序了。

        他的算法逻辑是这样的, 请来两位将军A,B, 

        首先是告诉A将军,你首先管理的是无序的9999个士兵队列。你只管把他们一个个都推出去给B将军就行了。 你可以认为B将军那里的永远是一个有序队列。

        然后告诉B将军,你手下永远是有序的队列。现在你手下有一个人,当然是有序的,接下来再来新人,都让他们和之前的有序队列比较,找到他们合适的位置。  

        第二个人来的时候,和原先的第一个人比较,如果比之前的人高,那么站在他后面,如果比他矮站在他前面 

        第三个人来的时候,从第一个位置开始找,找到第一个比他高的人,插入进队列。后面的士兵,都后退一步。

        以此类推,直到B将军手下 所有的士兵都到了A将军手下为止。

        所以,你可以简单的理解它为插队排序

    4.2  希尔排序

        希尔排序是基于插入排序的以下两点性质而提出改进方法的:

            1     插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率。

            2     但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位。

        希尔排序的意思是现将正序列变成一个基本有序的序列,然后再进行简单插入排序。

        那么如何将一个序列变成基本有序的序列呢。 现在有一个100元素的序列

        第一趟将其拆成50个有序序列。  对这50个有序序列进行简单插入排序

        第二趟将其拆分为25个,每个4元素的序列,对这25个有序序列进行简单插入排序。

        知道最后将其拆分为一个 100元素序列为止。

        希尔排序是在简单插入排序的基础上演进来的,理论的东西,不多赘述。可以这样理解。

        希尔排序的基本思想还是 A ,B两个将军 分别管理一个有序队列和一个无序队列。

        但是差别在于,如果整个队列是接近完全无序的情况下,每次新兵进去 B将军的有序队列,都要进行一次整体的位移。也就是比较的次数为LOG(n2),而且在排序后期,这里的N基本都无限接近一万,这是一个很大的性能消耗。

        而希尔排序,则是先取增量为10,所有的下标向10取余

        先让尾号为0的士兵向前一步, 这样就出现了1000名,位置尾号为0的士兵。 先对这1000名士兵进行插入排序,即便出现插入操作而导致的整体位移,移动成本也比一万名士兵移动好多了。  这样已经有十分之一的士兵有序了

        然后再让尾号为1的士兵向前一步...,尾号为2的士兵向前一步。  以此类推。整体一万个士兵也就基本有序了。

这样我们一趟排序完成,此时我们的增量为10. 接下来我们降低增量为5,

所有士兵的下标向5取余。  我们还是按照刚才的办法,每次对五分之一的士兵,进行插入排序。

虽然两千名士兵整体位移的成本依然很高,但是毕竟比一万小了很多,况且之前已经有过一次十分之一规模的插入排序了。所以发生插入操作的概率不大。

第二趟排序结束。  继续缩小增量。直到为0.。。。。。   

over (真特么的麻烦。。。)

希尔排序执行效果 希尔排序代码实现

五  冒泡排序

    相对原始的方法,对比每一个元素,每趟选出一个最大值出来。时间复杂度为O(n2)

这个算法最简单,也最好理解,和选择排序极为类似。只不过区别不是将军带着笔记本去挨个统计个头了。

而是将军领着当前等待排序的士兵本人,与下一个士兵比个头。  最后跟着将军走到队列尾部的,一定是个头最大的。

    算法实现:

冒泡

附上:源码下载地址:

http://note.youdao.com/noteshare?id=2afb3adfc83d0684ff79deb931c079bb&sub=97381DA724BC4B3DA8EE2D5175176593

相关文章

  • 给一万个士兵排个序---基础排序算法随记

    不想当将军的士兵,不是好士兵。不了解算法的程序员也不是好的程序员。 ...

  • 算法-排序算法总结

    排序类型总结 1 排序算法基础实现 2 排序算法应用 2.1 基础排序 2.2 计数排序应用 2.3 快排应用 2...

  • 排序算法——动图版本

    声明:本文来自马士兵教育 请勿转载 排序算法 1、基本介绍 ​ 排序算法比较基础,但是设计到很多计算机...

  • 十大经典排序算法(js实现)

    参考:十大经典排序算法 0、排序算法说明 0.1排序的定义 对一序列对象根据某个关键字进行排序。 0.2 术语说明...

  • Java实现各种常用的排序算法

    Java实现各种常用的排序算法,包括:冒泡排序、插入排序、二分排序、选择排序、希尔排序、堆排序、快速排序(两种写法...

  • 数据结构与算法-排序/二分查找

    算法中基础中的基础,排序/二分查找 排序 1.快排QuickSort 归并排序 堆排序 1. 二分查找

  • 算法入门:堆排序

    基础概念#### 堆排序是比较基础的排序算法,也是我认为比较难的一种算法,因为它的流程比较多,理解起来不会像冒泡排...

  • 分治策略对数组进行排序(二分排序算法)

    分治策略对数组进行排序(二分排序算法) 今天我来熟悉巩固一下分治算法对数组进行排序,分治问题就是把复杂的大问题拆解...

  • 常用排序算法

    常见排序算法 本文介绍6种常用排序算法,包括冒泡、选择、插入、快排、堆排、希尔排序。下面从排序算法的原理、解题步骤...

  • 开发者应该掌握的几种排序算法

    该篇文章主要介绍了算法基础以及几种常见的排序算法:选择排序、插入排序、冒泡排序、快速排序、堆排序。 一、算法基础 ...

网友评论

      本文标题:给一万个士兵排个序---基础排序算法随记

      本文链接:https://www.haomeiwen.com/subject/wdrttqtx.html