作为人类高质量程序员,必须掌握哪些算法?

  • 回答 (36)
  • 关注 (5)
  • 查看 (957)

数据结构、算法、计算机原理是编程和实践的根基,看似枯燥和基础,却具有最长久的生命力。

作为人类高质量程序员,写代码精髓就是领略数学之美

算法:

  • 排序算法:快速排序、归并排序、计数排序
  • 搜索算法:回溯、递归、剪枝
  • 图论:最短路径、最小生成树、网络流建模

.......

数据结构:

  • 数组和链表
  • 栈与队列
  • 树和图

.......

作为程序员的你,认为编程必须掌握哪些算法?快来分享你的见解吧!

内容要求

● 围绕算法,发表见解 50 字以上(需原创,禁止转载)

奖励

回答赞同数 TOP10 的用户将有机会获得精美定制小礼品一份

评选标准

  • 回答需符合活动中所提及的要求,符合社区规范
  • 请遵守社区规范,如有违规行为,一经发现即取消参与资格

评选结果 & 公示

云+社区小助手 9 月 10 日在获奖评论下通知答主,奖品将于30日内发放

更多精彩问答与定制好礼,尽请关注 【云+有奖问答专题】 \( ̄▽ ̄)/

云加社区云加社区

腾讯云 · 产品运营 (已认证)

修改于
IT小马哥

北京天谱同盛教育科技有限公司 · JAVA高级研发经理 (已认证)

想做个有钱人,却误入程序世界的一个小码农。回答于
推荐

程序 = 数据结构 + 算法 。数据是程序的中心。数据结构和算法两个概念间的逻辑关系贯穿了整个程序世界,首先二者表现为不可分割的关系。没有数据间的有机关系,程序根本无法设计。换言之数据结构是底层,算法就是高层。数据结构为算法提供服务。算法围绕数据结构操作。可以说没有算法的程序是没有灵魂的。

数据接口一般分为线性数据结构和非线性数据结构

  • 线性数据结构:常见的有一维数组,线性表,栈,队列,双队列,串。
  • 非线性数据结构:常见的有:多维数组,集合,树,图,散列表(hash).

大家知道了数据结构,还必须要掌握一些常见的基本算法。

理解算法之前必须要先理解的几个算法的概念:

  • 空间复杂度:一句来理解就是,此算法在规模为n的情况下额外消耗的储存空间。
  • 时间复杂度:一句来理解就是,此算法在规模为n的情况下,一个算法中的语句执行次数称为语句频度或时间频度。
  • 稳定性:主要是来描述算法,每次执行完,得到的结果都是一样的,但是可以不同的顺序输入,可能消耗的时间复杂度和空间复杂度不一样。

一般常见的算法有二分查找算法,递归算法,还有八大排序算法直接插入排序,希尔排序,选择排序,堆排序,冒泡排序,快速排序,归并排序,基数排序基数排序

一个程序员算法能力如何可以能够准确辨别一个程序员的技术功底是否扎实,可以判断出 学习能力与成长潜力和分析并解决问题的能力如何。这也是为什么面试官都喜欢问一些算法和数据结构的原因。

其实算法没有好与坏只有适合自己业务的算法才是最优算法,深入了解每个算法的特性 和自己的业务适配起来

举个例子一些算法的最后往往是一个时空转换的问题

  • 时间换空间

用时间换空间的策略,出发点是内存和存储这样的“空间”资源,有时会成为最稀缺的资源,所以需要尽量减少占用的空间。比如,一个系统的最大性能瓶颈如果是内存使用量,那么减少内存的使用就是最重要的性能优化。

  • 用空间换时间

“用空间换时间”就是对“用时间换空间”策略反其道而行之。有些场景下,时间和速度更加重要,但是空间尚有富余,这时我们就可以考虑用空间来换时间。

其实我们部署的任何大规模系统,都或多或少地采用了用空间换时间的策略,比如在集群和服务器间进行负载均衡,就是同时用很多个服务器(空间)来换取延迟的减少(时间)。

优化策略中的最后一个大类就是“更先进算法和数据结构”。这两个策略是紧密配合的,比如先进的算法有时候会需要先进的数据结构;而且它们往往和程序的设计代码直接相关,所以放在一起。同一个问题,肯定会有不同的算法实现,进而就会有不同的性能。比如各种排序算法,就是各有千秋。有的实现可能是时间换空间,有的实现可能是空间换时间,那么就需要根据你自己的实际情况做权衡。

对每一种具体的场景,总会有一种算法是最适合的。我们需要考虑实际情况,来选择这一最优的算法。

MintimateMintimate's Blog的作者嗷回答于
推荐

确实挺看个人的,但是我觉得,最少基本的数据结构需要知道吧。比如:红黑树、深度优先还是广度优先。在日常使用时候,一些语言封装的算法需要了解,比如:Java的sort()排序算法。


排序算法

说到排序算法,这个我觉得是一定要了解的,使用频率和算法优化也最为明显。还是java的sort()方法。平时使用,可能就是一个数组或链表(如:Arraylist),调用sort()方法:

int[] list={9,2,3,1,5,6,9,8};
// Java Sort方法
Arrays.sort(list);
for (int temp:list) {
    System.out.print(temp+" ");

或:

List <Integer> list=new ArrayList<>();
list.add(3);
list.add(2);
list.add(5);
// Java Sort方法
list.sort(Comparator.naturalOrder());
for (int temp:list) {
    System.out.print(temp+" ");
}

但是,真的每个人都要看Arrays的sort排序底层么?这个算法,是使用快排或双轴快速排序等多种排序方法,以int类型排序为例,使用的是双轴快速排序(DualPivotQuicksort):

JDK11 Arrays的sort方法

DualPivotQuicksort我认为已经是非常好的排序算法了,能看懂的话,也算入门的高质量程序员了吧╮( ̄▽ ̄"")╭。算法的解析,可以参考:https://rerun.me:

Array sort

小结

总之,我认为程序员,必须掌握的算法一定要掌握最基本的数据结构,其次是能理解许多使用广泛的排序算法(比如:java Arrays sort)。

以上,纯属个人观点嗷(*≧ω≦)

三掌柜

佰钧成技术有限责任公司 · 架构师 (已认证)

一名合格的、二把刀的、科班的程序猿回答于

作为人类高质量程序员,必须掌握的算法技能不单纯局限于算法这个词汇本身,还要包括数据结构,结合数学知识,以及开发者自身沉淀的逻辑思维。

单纯从算法知识点来说,高质量程序员必备知识点有:递推法、贪心法、列举法、递归法、分治法和模拟法等等,掌握这些核心的知识点就够了。

从数据结构来讲的话,高质量程序员必备知识点有:数组与链表、栈与队列,图与树,哈希表、堆、字符串等等。

从数学知识来说的话,高质量程序员必备知识点有:组合数学、高等数学、计算方法、几何学、概率论等等。

从开发者自身来讲,高质量程序员必备知识点有:在工作和学习中沉淀的下来的编程思想,自身的逻辑思维体系,发散思维,以及丰富的开发经验等等。

以上就是通过4个方面来概括总结作为人类高质量程序员,必须掌握的“算法”技能。

LittleU

南京尚哲智能科技 · unity开发工程师 (已认证)

一位脱离了高级趣味的人.回答于

首先

并不是所有的程序员都需要知道算法是什么的,现在的程序员,大部分都是表面开发,学会了某一个框架的使用就沾沾自喜,大多数时间编程估计连二叉树都不用,满满的数组,列表,年限稍微高一点的,可能用字典。

其次

真正关心算法的人,很大一部分时间都在想我怎么快,花最少的时间,做最快的查找。而这部分程序员,大多是架构师或者底层开发了,说实话,中国的程序员大多还停留在代码堆砌,说的难听一点,有点像装修人员,没有底层架构师算法的精妙,你到不了那么高的地方做你的裱糊匠。

最后

我作为一个unity前端开发,也不关心算法怎么样,但我知道算法是怎么回事,算法对于我唯一作用就是在面试地 时候可以去问问面试者,如果他不懂,我就有理由压价,如果他懂了,那么我就问的细一点,最终把我自己学懂了。

最后的最后

如果硬要说要掌握什么算法,那么我觉得二分查找,那是必须要掌握的,,,,,,,哈哈哈哈

如果说你想在学的深一点,想去大厂,最起码二叉树能写吧,再升一点,八叉树,知道怎么回事,即使手写有点难度,那么遇到问题也应该知道怎么去搜索吧,。。。。做到这样,就可以了。

猜猜这些都是什么人??
用户8970551回答于
青年码农

晨讯科技 · web前端开发高级工程师 (已认证)

公众号【青年码农】:有趣、有料,有深度、有广度、有热度。回答于

我觉得作为程序员还是要学习下算法的,掌握哪些,就要看从事的哪种工作,虽然现在部分人员开发只接触表面工作,底层不需要接触,但是学习算法,对个人还是很有必要性的,学习算法可以培养个人的逻辑思维,编程是个注重逻辑的过程,如果逻辑思维没有,肯定是处处bug。学习算法,可以写出更高效的代码。

Regan Yue回答于

菜鸟一枚 我就说说我见过的算法与数据结构的名字:

字符串匹配

枚举

桶排序

计数排序

基数排序

动态规划

深度优先搜索

广度优先搜索

贪心

二分查找

回溯

递归

分治

记忆化搜索

快速选择

归并排序

哈希表

树 二叉树 二叉搜索树

链表

单调栈

队列

有序集合

拓扑排序

最短路

双向链表

单调队列

最小生成树

强连通分量

欧拉回路

双连通分量

并查集

字典树

幻影龙王沉迷于在代码海洋里回答于

搜索算法是利用计算机的高性能来有目的的穷举一个问题解空间的部分或所有的可能情况,从而求出问题解的一种方法。 现阶段常用的搜索算法有:枚举算法、深度优先搜索、广度优先搜索、剪枝算法、回溯算法等

blueflyming退役程序员回答于

一般来说,我们需要掌握的算法不多,像

排序算法:插入排序、冒泡排序、选择排序、快速排序等

搜索算法:深度优先、广度优先

贪心算法、动态规划算法等。

如果你是做数据科学的,那么你可能会接触到更多的算法,比如

决策树、逻辑回归、神经网络等。

算法本质上其实是九成的数学,加上一成的奇思妙想,再经过不断的测试、修改,最终简化运行逻辑,提供相对较优的解。

用户8527335回答于
小胡哼╯^╰回答于

看你自己的工作岗位以及自己目前需要什么

用户1636960回答于

作为人类高质量回答,什么都掌握点就好

Tz一号回答于
  1. 排序算法
  2. 搜索算法
  3. 图算法
  4. 快速取幂算法
  5. 贪心算法
  6. 动态规划算法
  7. 基于字符串的算法
  8. 几何算法
  9. 位算法

我觉得学习算法就像用工具填满你的工具箱。每个人都需要一些更常用的工具,尤其是在求职面试中展示的工具。

阿策小和尚回答于

和尚简单介绍一下算法的认知变化;刚开始工作时,觉得算法是一件很高深的东西,而且一般移动端开发用处不大,可有可无;但是工作了一段时间之后发现,算法真的很有用,你觉得没用,只是你了解的不够,你还不会用,真正了解算法之后,在方法的设计以及其他地方应用很密切,而且对于很多源码的阅读也有非常大的促进作用;和尚目前依旧是一个算法小白,希望以后可以有机会多多学习算法;常用的算法包括:a. 排序算法:快速排序、归并排序、计数排序 b. 搜索算法:回溯、递归、剪枝 c. 图论:最短路径、最小生成树、网络流建 d. 动态规划:背包问题、最长子序列、计数问题 e. 基础技巧:分治、倍增、二分法、贪心算法

滚神大人回答于

写了30年的程序,见过云起云落

对于大多数业务,实际上一个哈希表就够了

大道至简

西门呀在吹雪非典型性程序员回答于

算法一:快速排序算法

算法二:堆排序算法

算法三:归并排序

算法四:二分查找算法

算法五:BFPRT(线性查找算法)

算法六:DFS(深度优先搜索)

算法七:BFS(广度优先搜索)

算法八:Dijkstra算法

算法九:动态规划算法

算法十:朴素贝叶斯分类算法

lingchen 凌晨回答于

1、十大排序算法

2、图论算法

3、线性表

4、栈与队列

5、哈希表(必学)

在代码中如果没有算法,就没有灵魂,就像人没了灵魂就成了一具尸体,常用算法是是科学家经过推理推算出来解决某一特定问题的有效解决方案,因此在代码使用算法,可以大大提高代码运行效率。

用户8980547回答于

纯路人,高质量程序员那留一头乌黑头发,熟练摸鱼,阳光点时尚点少熬点吃早点,bug少点…………

用户7580783回答于
Ch_ZaqdtShow me the code.回答于
用户5957375回答于
CharlesMa回答于

十大排序算法

  • 简单排序:插入排序、选择排序、冒泡排序(必学)
  • 分治排序:快速排序、归并排序(必学,快速排序还要关注中轴的选取方式)
  • 分配排序:桶排序、基数排序
  • 树状排序:堆排序(必学)
  • 其他:计数排序(必学)、希尔排序
liuzhen007

百家云 · 流媒体研发工程师 (已认证)

本人一直从事音视频相关工作,拥有在传统广电巨头和互联网音视频公司工作的经历,具有丰富的音视频直播和点播相关经验,对WebRTC、FFmpeg和Electron有非常深入的了解。在CSDN上推出了很多音视频相关的技术专栏,累计产出了500余篇原创作品。同时,荣获了CSDN 2020年博客专家荣誉勋章和CSDN 2020年博客之星Top39荣誉称号。回答于

因为刚从菜市场买菜回来,因此从最贴近生活的角度出发,别的算法先不说,我认为必须要掌握的就是贪心算法。

我为什么这么说呢,因为生活中到处充满了贪心算法,就比如我刚才买菜,两根黄瓜6块6毛钱,我给了老板7块(手机没电了),他找我5毛。

注意:这里有两层贪心算法。

第一层,我从钱包里找出了7块钱,而不是8块,也不是5块,这就是贪心算法的最优解方案。

第二层,老板找我5毛,不是为了让我再给他1毛钱。而是他算出了最优的优惠比例(便宜1毛钱,而不是2毛、3毛)和我真正的“贪心”心理(我可能下次还来他家买菜)。

XDM,不知道解释的是不是够清楚,我尽力了。。。

用户8987842回答于
用户8990413回答于
用户5858364回答于
皮了那个皮-就问你皮不皮

腾云先锋 · 腾云先锋(TDP)成员 (已认证)

代码是谁?长什么样?修改于

1、A* 搜索算法——图形搜索算法,从给定起点到给定终点计算出路径。其中使用了一种启发式的估算,为每个节点估算通过该节点的最佳路径,并以之为各个地点排定次序。算法以得到的次序访问这些节点。因此,A*搜索算法是最佳优先搜索的范例。

2、集束搜索(又名定向搜索,Beam Search)——最佳优先搜索算法的优化。使用启发式函数评估它检查的每个节点的能力。不过,集束搜索只能在每个深度中发现最前面的m个最符合条件的节点,m是固定数字——集束的宽度。

3、二分查找(Binary Search)——在线性数组中找特定值的算法,每个步骤去掉一半不符合要求的数据。

4、分支界定算法(Branch and Bound)——在多种最优化问题中寻找特定最优化解决方案的算法,特别是针对离散、组合的最优化。

5、Buchberger算法——一种数学算法,可将其视为针对单变量最大公约数求解的欧几里得算法和线性系统中高斯消元法的泛化。

6、数据压缩——采取特定编码方案,使用更少的字节数(或是其他信息承载单元)对信息编码的过程,又叫来源编码。

7、Diffie-Hellman密钥交换算法——一种加密协议,允许双方在事先不了解对方的情况下,在不安全的通信信道中,共同建立共享密钥。该密钥以后可与一个对称密码一起,加密后续通讯。

8、Dijkstra算法——针对没有负值权重边的有向图,计算其中的单一起点最短算法。

9、离散微分算法(Discrete differentiation)

10、动态规划算法(Dynamic Programming)——展示互相覆盖的子问题和最优子架构算法

11、欧几里得算法(Euclidean algorithm)——计算两个整数的最大公约数。最古老的算法之一,出现在公元前300前欧几里得的《几何原本》。

12、 期望-最大算法(Expectation-maximization algorithm,又名EM-Training)——在统计计算中,期望-最大算法在概率模型中寻找可能性最大的参数估算值,其中模型依赖于未发现的潜 在变量。EM在两个步骤中交替计算,第一步是计算期望,利用对隐藏变量的现有估计值,计算其最大可能估计值;第二步是最大化,最大化在第一步上求得的最大 可能值来计算参数的值。

13、快速傅里叶变换(Fast Fourier transform,FFT)——计算离散的傅里叶变换(DFT)及其反转。该算法应用范围很广,从数字信号处理到解决偏微分方程,到快速计算大整数乘积。

14、梯度下降(Gradient descent)——一种数学上的最优化算法。

15、哈希算法(Hashing)

16、堆排序(Heaps)

17、Karatsuba乘法——需要完成上千位整数的乘法的系统中使用,比如计算机代数系统和大数程序库,如果使用长乘法,速度太慢。该算法发现于1962年。

18、 LLL算法(Lenstra-Lenstra-Lovasz lattice reduction)——以格规约(lattice)基数为输入,输出短正交向量基数。LLL算法在以下公共密钥加密方法中有大量使用:背包加密系统 (knapsack)、有特定设置的RSA加密等等。

19、 最大流量算法(Maximum flow)——该算法试图从一个流量网络中找到最大的流。它优势被定义为找到这样一个流的值。最大流问题可以看作更复杂的网络流问题的特定情况。最大流与 网络中的界面有关,这就是最大流-最小截定理(Max-flow min-cut theorem)。Ford-Fulkerson 能找到一个流网络中的最大流。

20、合并排序(Merge Sort)

21、牛顿法(Newton's method)——求非线性方程(组)零点的一种重要的迭代法。

22、 Q-learning学习算法——这是一种通过学习动作值函数(action-value function)完成的强化学习算法,函数采取在给定状态的给定动作,并计算出期望的效用价值,在此后遵循固定的策略。Q-leanring的优势是, 在不需要环境模型的情况下,可以对比可采纳行动的期望效用。

23、两次筛法(Quadratic Sieve)——现代整数因子分解算法,在实践中,是目前已知第二快的此类算法(仅次于数域筛法Number Field Sieve)。对于110位以下的十位整数,它仍是最快的,而且都认为它比数域筛法更简单。

24、 RANSAC——是“RANdom SAmple Consensus”的缩写。该算法根据一系列观察得到的数据,数据中包含异常值,估算一个数学模型的参数值。其基本假设是:数据包含非异化值,也就是能 够通过某些模型参数解释的值,异化值就是那些不符合模型的数据点。

25、RSA——公钥加密算法。首个适用于以签名作为加密的算法。RSA在电商行业中仍大规模使用,大家也相信它有足够安全长度的公钥。

26、Schönhage-Strassen算法——在数学中,Schönhage-Strassen算法是用来完成大整数的乘法的快速渐近算法。其算法复杂度为:O(N log(N) log(log(N))),该算法使用了傅里叶变换。

27、单纯型算法(Simplex Algorithm)——在数学的优化理论中,单纯型算法是常用的技术,用来找到线性规划问题的数值解。线性规划问题包括在一组实变量上的一系列线性不等式组,以及一个等待最大化(或最小化)的固定线性函数。

28、 奇异值分解(Singular value decomposition,简称SVD)——在线性代数中,SVD是重要的实数或复数矩阵的分解方法,在信号处理和统计中有多种应用,比如计算矩阵的伪 逆矩阵(以求解最小二乘法问题)、解决超定线性系统(overdetermined linear systems)、矩阵逼近、数值天气预报等等。

29、 求解线性方程组(Solving a system of linear equations)——线性方程组是数学中最古老的问题,它们有很多应用,比如在数字信号处理、线性规划中的估算和预测、数值分析中的非线性问题逼近等 等。求解线性方程组,可以使用高斯—约当消去法(Gauss-Jordan elimination),或是柯列斯基分解( Cholesky decomposition)。

30、Strukturtensor算法——应用于模式识别领域,为所有像素找出一种计算方法,看看该像素是否处于同质区域( homogenous region),看看它是否属于边缘,还是是一个顶点。

31、合并查找算法(Union-find)——给定一组元素,该算法常常用来把这些元素分为多个分离的、彼此不重合的组。不相交集(disjoint-set)的数据结构可以跟踪这样的切分方法。合并查找算法可以在此种数据结构上完成两个有用的操作:

查找:判断某特定元素属于哪个组。

合并:联合或合并两个组为一个组。

32、维特比算法(Viterbi algorithm)——寻找隐藏状态最有可能序列的动态规划算法,这种序列被称为维特比路径,其结果是一系列可以观察到的事件,特别是在隐藏的Markov模型中。

用户5588126回答于
用户8503658回答于

排序算法:插入排序、冒泡排序、选择排序、快速排序等

搜索算法:深度优先、广度优先

依旧廖凯回答于

算法:

1、排序算法:快速排序、归并排序、计数排序

2、搜索算法:回溯、递归、剪枝

3、图论:最短路径、最小生成树、网络流建模

4、动态规划:背包问题、最长子序列、计数问题

5、基础技巧:分治、倍增、二分法、贪心算法

数据结构:

1、数组和链表

2、栈与队列

3、树和图

4、哈希表

5、大/小跟堆,可并堆

6、字符串:字典树、后缀树

扫码关注云+社区

领取腾讯云代金券