----------------------------------何谓算法--------------------------

算法其实就是:把物理现象数学化,并按照规则求结果(把物理现象抽象成数字符号)。

要不怎么说:一个好的数学家一定是一个好的物理学家来着。

因为他懂得了物理现象到数学的真谛 ,就是:符号化、规律化、数学化。

比如一个简单的拼图游戏:(window7 经典小游戏)

我们小时候玩的拼图板

https://blog.csdn.net/dcrmg/article/details/52069043

里面就用到了很多算法,比如:A=B,B =C,C=D,D=A  替换算法。

还有网上流行的解绳套问题:(其实里面就拓扑学的算法)

-------------------------------------- 常用排序算法----------------------------

废话不多说,进入第一讲: 常用排序算法

参考链接:https://www.jianshu.com/p/77ba54a46ad7

由于链接的帖子中讲的比较详细,我这里仅做补充讲解

常用的排序算法如下:

1. 冒泡排序算法(Bubble Sort)、2. 快速排序算法(quick sort)、3. 选择排序算法(select sort)、4.  插入排序(insert sort)、5. 归并排序(merge sort)、6. 希尔排序(shell sort)、7. 基数排序(radix sort)、8. 计数排序(counting sort)、9. 桶排序(bucket sort)

(关于什么是时间复杂度,可以参考:https://blog.csdn.net/qq_41907991/article/details/97443681

前言,其实目前主流的算法,核心都是我们小学学的“二分法”,不要因为大公司面试啥的老提算法,大家就觉得很高大上啥的,算法应该是融入我们生活中的,应该是很亲民的才对。各位小伙伴,用自己的大脑袋记住,算法的核心就是“二分法”,记不住就写在脸上。。。。

1. 冒泡排序算法(Bubble Sort)

冒泡排序算法应该是程序中很常用的一种排序算法,主要是做相邻两个元素的大小比较,比较后 进行大小数的位置替换。

这个很像上边说的 :拼图板游戏,其实都是 用了一种替换算法。

2. 快速排序算法(quick sort)

快速排序是由东尼·霍尔所发展的一种排序算法。这个老外一定精通二分算法的精髓,知道多数据比较会有次数平方的困扰,所以就用了一个类似开发的方式来抵消: 由于多数据比较带来的比较次数过多的问题。

我们看一下原贴描述

“在平均状况下,排序 n 个项目要 Ο(nlogn) 次比较。在最坏状况下则需要 Ο(n2) 次比较,但这种状况并不常见。事实上,快速排序通常明显比其他 Ο(nlogn) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。

快速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists)。”

所谓分治法,其实说白了就是二分法。把数据划分成不同的区域放进数组,就可以极大提高比较速度。

如果 数据比较是平方,那么二分法就是开方,“平方/开方”,相当于没有平方,这也就是快速排序明显比其他 Ο(nlogn) 算法更快的根本原因。

**说到这里,有小伙伴就会问了:

“既然二分法这么屌,为啥快速排序每次只取一个数做“基准”,不如每次分区后都建立两个数组,每个数组都继续使用二分法,最后把比较好的数据进行排序。相当于对这些数据不断的做2的开方,速度不是更快吗?”

这个问题提的非常好!

但是由于现实物理环境不同于数学环境,物理设备总是有这样那样的限制,比如计算机的内存,如果不够大,在不断建立数组对象的情况下就很难进行二分。

比如:大型数据统计一组数据就有上兆亿个数据,用二分法建立的数组可能就有上万个。此时,就会对计算机造成极大的内存消耗,一般的电脑根本吃不消。。。毕竟抽象的数学环境还是不同于现实的物理环境的,这也是为什么会出现如此多不同算法的

原因,让大家可以选择不同的物理环境进行选择。。。

**这么一说,这位小伙伴可能又要问了:

“既然这样,那为啥不重用某这个数组呢?这样不就行了吗?”

说的非常好,不过你能想到的,人家也能想到,意外不意外,惊喜不惊喜?

下边就让我们进入第三个算法,讲解这个问题!

3. 选择排序算法(select sort)

分为

直接选择排序(straight select sort)

2堆排序(heap sort  这个 涉及到完全二叉树的概念,但 二叉树的本质就是“二分法”,不过在后来的应用中做了很多的延伸和变形来适应不同的问题)

看下边这段代码:

- (void)heapSortWithArray:(NSMutableArray *)array {//循环建立初始堆for (NSInteger i = array.count * 0.5; i >= 0; i--) {[self heapAdjustWithArray:array parentIndex:i length:array.count];}//进行n-1次循环,完成排序for (NSInteger j = array.count - 1; j > 0; j--) {//最后一个元素和第一个元素进行交换[array exchangeObjectAtIndex:j withObjectAtIndex:0];//筛选R[0]结点,得到i-1个结点的堆[self heapAdjustWithArray:array parentIndex:0 length:j];NSLog(@"第%ld趟:", array.count - j);[self printHeapSortResult:array begin:0 end:array.count - 1];}
}- (void)heapAdjustWithArray:(NSMutableArray *)arrayparentIndex:(NSInteger)parentIndexlength:(NSInteger)length {NSInteger temp = [array[parentIndex] integerValue]; //temp保存当前父结点NSInteger child = 2 * parentIndex + 1; //先获得左孩子while (child < length) {//如果有右孩子结点,并且右孩子结点的值大于左孩子结点,则选取右孩子结点if (child + 1 < length && [array[child] integerValue] < [array[child + 1] integerValue]) {child++;}//如果父结点的值已经大于孩子结点的值,则直接结束if (temp >= [array[child] integerValue]) {break;}//把孩子结点的值赋值给父结点array[parentIndex] = array[child];//选取孩子结点的左孩子结点,继续向下筛选parentIndex = child;child = 2 * child + 1;}array[parentIndex] = @(temp);
}- (void)printHeapSortResult:(NSMutableArray *)arraybegin:(NSInteger)beginend:(NSInteger)end {for (NSInteger i = 0; i < begin; i++) {}for (NSInteger i = begin; i <= end; i++) {}//打印堆排序NSLog(@"堆排序升序结果是--->%@",array);
}

第二行代码:这个 heapAdjustWithArray: parentIndex:  length:方法 就是不断的对传入的Array 数组进行重用!

4.  插入排序(insert sort)

说到这里,那么插入排序的核心是不是也是我们上边提到 的“二分法”呢?

恭喜你,答对了!

一般的插入排序其实就是两个数据进行比较,这个和冒泡算法差不多,但是,插入排序和冒泡排序一样,也有一种优化算法,叫做拆半插入。

何谓“ 拆半”?

其实就是二分嘛!

万变不离其宗,其核心还是“二分法”。

可见“你大爷永远是你大爷!”

5. 归并排序(merge sort)

这个算法不用我讲,大家用屁股也能猜到,其核心还是“二分法”!

为啥?

下面我们来看一下帖子对其算法的描述:
“归并排序(Merge sort)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。

作为一种典型的分而治之思想的算法应用,归并排序的实现由两种方法:

  • 自上而下的递归(所有递归的方法都可以用迭代重写,所以就有了第 2 种方法);
  • 自下而上的迭代;

在《数据结构与算法 JavaScript 描述》中,作者给出了自下而上的迭代方法。

和选择排序一样,归并排序的性能不受输入数据的影响,但表现比选择排序好的多,因为始终都是 O(nlogn) 的时间复杂度。代价是需要额外的内存空间。”

分治法(Divide and Conquer)?

这不还是说的“二分法”吗?为啥 需要“需要额外的内存空间”,不就是要多建立数组来存储分区数据吗?这才是其“表现比选择排序好的多”的根本原因!!!

6. 希尔排序(shell sort)

帖子描述:

“希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。但希尔排序是非稳定排序算法。

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

  • 插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率;
  • 但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位;

希尔排序的基本思想是:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。”

怎么样?

这个描述是不是很面熟!

“先将整个待排序的记录序列分割成为若干子序列”不就是“二分法”划分 不同数据区间的意思吗?

然后“二分”比较或者插入比较后,直接进行排序!

7. 基数排序(radix sort) VS 8. 计数排序(counting sort) VS 9. 桶排序(bucket sort)

------这3个算法比较有意思了,我下边重点讲一下---------

这三种排序法,不同于一般的数据“二分法”,或许应该就叫做“0-9 十分法”:

它 不是 对   所有数据进行个数的区间“二分”;而是对每一个数据进行位次上的“二分”!

有小朋友表示看不懂下边这个图,我们来讲解一下哈:大家打起精神,不要“神游天外思佳人,望着学究直愣神”

如果按照“二分法”来讲:

第一次排序:其实是对“个位”为0 或非0的数进行的二分;所以50 和其他数分开了;

第二次排序:是对“十分位”为0或非0进行的二分;这里已经把2、3、4、5换成了“02、03、04、05”来进行比较;

**第三次排序:如果添加一个数:101,进行第三次排序,那么就会在“百分位”进行比较;所有数据就变成了“002、003、004、005、015、019....... 050、 101”,也就只有101 会在非0 位置。

如果按照“0-9 十分法”来讲:

第一次排序:是对“个位”的数进行的“0-9”划分;

第二次排序:是对“十分位”的数进行的“0-9”划分;其实已经把2、3、4、5换成了“02、03、04、05”来进行划分;

**第三次排序:如果添加一个数:101,那么就会在“百分位”进行划分;所有数据就变成了“002、003、004、005、015、019、 050...... 101”。

-----------------------结语----------------------

其实算法并不是很晦涩难懂的问题,我们不要有“望它高楼难下脚”的感觉,谁能想到,这么多高级的算法,本质就是小学学的“二分法”呢?

----------------------引伸----------------

如果说“二分法”是对数据比较的难度进行了开平方处理,那我们就可以想到:是不是还有开 “立方”处理呢?

结合大学学习的“矩阵算法”,我们是不是可以在三维上可以对数据算法进行发展呢?

三维算法可能是“0-9十分法”和“二分法”的组合。。。。

也可能是两个“0-9十分法”的组合。。。。

大家可以让思想飞翔,不拘一格的去研究。。。。

去吧骚年!

iOS 算法的前世今生:算法原理、常用算法(一)排序算法相关推荐

  1. 对以下6种常用的内部排序算法进行比较:起泡排序、直接插入排序、简单选择排序、快速排序、希尔排序、堆排序。

    题目要求: (1)对以下6种常用的内部排序算法进行比较:起泡排序.直接插入排序.简单选择排序.快速排序.希尔排序.堆排序. (2)待排序表的表长不小于100:其中的数据要用伪随机数产生程序产生:至少要 ...

  2. <<算法很美>>——(三)十大排序算法(上)

    目录 前言 冒泡排序 图解冒泡 代码实现 冒泡优化 选择排序 图解选排​ 代码实现 插入排序 图解插入 ​代码实现 希尔排序 图解希尔 ​代码实现: 归并排序 图解归并 ​代码实现 快速排序 图解快排 ...

  3. 《算法不好玩》专题二:基础排序算法

    视频链接:<算法不好玩>专题二 2-1选择排序 无序数组→有序数组 基于排序算法可以学习的话题:「时间复杂度」.「递归」.「循环不变量」 排序算法可以分为:「基于比较的排序算法」.「非比较 ...

  4. 常用的比较排序算法总结

    写在前面 一直很惧怕算法,总是感觉特别伤脑子,因此至今为止,几种基本的排序算法一直都不是很清楚,更别说时间复杂度.空间复杂度什么的了. 今天抽空理了一下,其实感觉还好,并没有那么可怕,虽然代码写出来还 ...

  5. 《算法笔记》第4章常用技巧及排序算法

    文章目录 二. 常用技巧 1. 散列 2. 递归 2.1 全排列问题 2.2 n皇后问题 2.3 回溯法优化n皇后问题 3. 贪心 3.1 简单贪心 3.2 区间贪心 4. 二分 4.1 二分查找 4 ...

  6. 常用七大经典排序算法总结(C语言描述)

    目录 一.交换排序 1.冒泡排序 2.快速排序 二.插入排序 1.直接插入排序 2.希尔(shell)排序 三.选择排序 1.直接选择排序 2.堆(Heap)排序 四.归并排序 正文 简介 其中排序算 ...

  7. php常用算法的时间复杂度,php的几个经典排序算法及时间复杂度和耗时​

    $arr = []; for ($i=0; $i 测试结果:排序用时(秒):5.2821290493011 php排序里的经典算法首先想到的就是冒泡排序法, 排序思想:两两交换小数上浮大数下沉每轮浮出 ...

  8. 常用的八大排序算法时间复杂度和空间复杂度比较

    排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存. 各种内部排序按所采用的基本思想(策略)可分 ...

  9. 数组的常用五种排序算法

    目录 一.排序算法介绍 二.算法代码实现 1.选择法排序 2.冒泡法排序 3.交换法排序 4.插入法排序 5.折半法排序 一.排序算法介绍 1.选择法排序 选择法排序在排序过程中一共需要进行 n(n- ...

  10. 算法设计与分析 自创O(n)排序算法 适用于任何有理数

    受桶排序思想的启发,想到了这个算法.不同之处在于,桶排序是对于每个bucket各自排序,而本算法桶内部不需要排序. 功能 本算法可以在有限空间内,将任意有理数排序,平均时间复杂度为O(n) 输入:需要 ...

最新文章

  1. 深度 | 智慧•城市,基于国际视野下的思考
  2. javadrawstring设置字符大小_LaTex学术写作——编辑文档格式 设置论文标题与摘要...
  3. php钩子的作用,php中的钩子理解及应用实例分析
  4. HDU5853 Jong Hyok and String(二分 + 后缀数组)
  5. 收藏网站制作常用经典css.div.布局.设计实例打包下载(下方有其他链接)
  6. 延长汽车寿命的6个良好习惯
  7. 苹果home键在哪里设置_苹果手机怎样添加辅助触控功能
  8. python对象和类_Python面向对象(一)类与对象
  9. Visual Studio Code如何打开多个tab标签
  10. SCCM 部署操作系统 ,提示权限问题,报错:0xc00000098
  11. 全军出击 iOS和Android,绝地求生全军出击安卓和ios能一起玩吗_绝地求生全军出击安卓ios数据互通吗_玩游戏网...
  12. python之 turtle好例子集锦
  13. 华悦网游器软件介绍及功能介绍
  14. Mac m1 Kettle安装
  15. 对未来国产操作系统的期望
  16. 计算机类核心期刊投稿的一些资料汇总
  17. 系统没有java控制面板,手把手教你解答win7系统打开java控制面板的解决教程
  18. memory prefix hypo,hecto,hyper out1
  19. 什么是数据可视化技术
  20. Firebase报错:Installations Service is unavailable. Please try again later.

热门文章

  1. Sass的安装(windows 10)
  2. C++11之 Move semantics(移动语义)(转)
  3. Linux进程调度原理【转】
  4. hibernate查询list结果集结果都是一样
  5. 贵安新区生物医学大数据中心揭牌成立
  6. B/S架构 Web打印程序(Argox)
  7. 分页SQL语句/存储过程(.net/SQL技术交流群206656202 入群需注明博客园)
  8. 分区工具parted的详解及常用分区使用方法
  9. 简单的Hibernate入门简介
  10. IDEA 新建junit单元测试