如何高效地学习数据结构与算法?
1. 什么是数据结构?什么是算法?
从广义上讲,数据结构就是指一组数据的存储结构。算法就是操作数据的一组方法。
从狭义上讲,是指某些著名的数据结构和算法,比如队列、栈、堆、二分查找、动态规划等。这些都是前人智慧的结晶,我们可以直接拿来用。这些经典数据结构和算法,都是前人从很多实际操作场景中抽象出来的,经过非常多的求证和检验,可以高效地帮助我们解决很多实际的开发问题。
数据结构和算法有什么关系呢?数据结构是为算法服务的,算法要作用在特定的数据结构之上。
2.学习的重点在什么地方?学习的顺序?
2.1 想要学习数据结构与算法,首先要掌握一个数据结构与算法中最重要的概念——复杂度分析。
这个概念究竟有多重要呢?可以这么说,它几乎占了数据结构和算法这门课的半壁江山,是数据结构和算法学习的精髓。
数据结构和算法解决的是如何更省、更快地存储和处理数据的问题,因此,我们就需要一个考量效率和资源消耗的方法,这就是复杂度分析方法。所以,如果你只掌握了数据结构和算法的特点、用法,但是没有学会复杂度分析,那就相当于只知道操作口诀,而没掌握心法。只有把心法了然于胸,才能做到无招胜有招!所以,复杂度分析这个内容一定要花大力气来啃,必须要拿下,并且要搞得非常熟练。否则,后面的数据结构和算法也很难学好。
2.2 搞定复杂度分析,下面就要进入数据结构与算法的正文内容了。
下图里面几乎涵盖了所有数据结构和算法书籍中都会讲到的知识点:
但是,作为初学者,或者一个非算法工程师来说,你并不需要掌握图里面的所有知识点。很多高级的数据结构与算法,比如二分图、最大流等,这些在我们平常的开发中很少会用到。所以,你暂时可以不用看。我还是那句话,咱们学习要学会找重点。如果不分重点地学习,眉毛胡子一把抓,学起来肯定会比较吃力。
重点掌握:20 个最常用的、最基础数据结构与算法,不管是应付面试还是工作需要,只要集中精力逐一攻克这 20 个知识点就足够了。
这20个知识点是:这里面有 10 个数据结构:数组、链表、栈、队列、散列表、二叉树、堆、跳表、图、Trie
树;10 个算法:递归、排序、二分查找、搜索、哈希算法、贪心算法、分治算法、回溯算法、动态规划、字符串匹配算法。
在学习数据结构和算法的过程中,你也要注意,不要只是死记硬背,不要为了学习而学习,而是要学习它的“来历”“自身的特点”“适合解决的问题”以及“实际的应用场景”。对于每一种数据结构或算法,我都会从这几个方面进行详细讲解。只要你掌握了我每节课里讲的内容,就能在开发中灵活应用。学习数据结构和算法的过程,是非常好的思维训练的过程,所以,千万不要被动地记忆,要多辩证地思考,多问为什么。如果你一直这么坚持做,你会发现,等你学完之后,写代码的时候就会不由自主地考虑到很多性能方面的事情,时间复杂度、空间复杂度非常高的垃圾代码出现的次数就会越来越少。你的编程内功就真正得到了修炼。
3.一些可以让你事半功倍的学习技巧
3.1 边学边练,适度刷题
“边学边练”这一招非常有用。建议你每周花 1~2
个小时的时间,集中把这周的三节内容涉及的数据结构和算法,全都自己写出来,用代码实现一遍。这样一定会比单纯地看或者听的效果要好很多!
有面试需求的同学,可能会问了,那我还要不要去刷题呢?
我个人的观点是可以“适度”刷题,但一定不要浪费太多时间在刷题上。我们学习的目的还是掌握,然后应用。除非你要面试 Google
、Facebook
这样的公司,它们的算法题目非常非常难,必须大量刷题,才能在短期内提升应试正确率。如果是应对国内公司的技术面试,即便是 BAT
这样的公司,足以应对。
3.2 多问、多思考、多互动
学习最好的方法是,找到几个人一起学习,一块儿讨论切磋,有问题及时寻求老师答疑。 但是,离开大学之后,既没有同学也没有老师,这个条件就比较难具备了。
要担心问的问题太小白。因为我初学的时候,也常常会被一些小白问题困扰。不懂一点都不丢人,只要你勇敢提出来,一起解决了就可以了。
3.3 打怪升级学习法
学习的过程中,我们碰到最大的问题就是,坚持不下来。 是的,很多基础课程学起来都非常枯燥。为此,我自己总结了一套“打怪升级学习法”。
游戏你肯定玩过吧?为什么很多看起来非常简单又没有乐趣的游戏,你会玩得不亦乐乎呢?这是因为,当你努力打到一定级别之后,每天看着自己的经验值、战斗力在慢慢提高,那种每天都在一点一点成长的成就感就不由自主地产生了。所以,我们在枯燥的学习过程中,也可以给自己设立一个切实可行的目标,就像打怪升级一样。
比如,将每次学习的内容总结成博客进行输出。
3.4. 知识需要沉淀,不要想试图一下子掌握所有
在学习的过程中,一定会碰到“拦路虎”。如果哪个知识点没有怎么学懂,不要着急,这是正常的。因为,想听一遍、看一遍就把所有知识掌握,这肯定是不可能的。学习知识的过程是反复迭代、不断沉淀的过程。
所谓,书读百遍其义自见,我觉得是很有道理的!
4. 数据结构与算法学习书单:
4.1 针对入门的趣味书:
入门的同学,我建议你不要过度追求上去就看经典书。像《算法导论》《算法》这些书,虽然比较经典、比较权威,但是非常厚。初学就去啃这些书肯定会很费劲。而一旦啃不下来,挫败感就会很强。所以,入门的同学,我建议你找一些比较容易看的书来看,比如《大话数据结构》和《算法图解》。不要太在意书写得深浅,重要的是能不能坚持看完。
《大话数据结构》 这本书最大的特点是,它把理论讲得很有趣,不枯燥。而且每个数据结构和算法,作者都结合生活中的例子进行了讲解, 能让你有非常直观的感受。虽然这本书有 400 多页,但是花两天时间读完,应该是没问题的。如果你之前完全不懂数据结构和算法,可以先从这本书看起。
《算法图解》 跟《大话数据结构》走的是同样的路线,就像这本书副标题写的那样,“像小说一样有趣的算法入门书”,主打“图解”,通俗易懂。它只有不到 200 页,所以内容比较少。作为入门,看看这本书,能让你对数据结构和算法有个大概的认识。
这些入门书共同的问题是,缺少细节,不够系统,也不够严谨。所以,如果你想要系统地学数据结构和算法,看这两本书肯定是不够的。
4.2 针对特定编程语言的教科书:
讲数据结构和算法,肯定会跟代码实现挂钩。所以,很多人就很关心,某某书籍是用什么语言实现的,是不是自己熟悉的语言。市面大部分数据结构和算法书籍都是用 C、C++、Java 语言实现的,还有些是用伪代码。而使用 Python、Go、PHP、JavaScript、Objective-C 这些编程语言实现的就更少了。
我这里推荐《数据结构和算法分析》。国内外很多大学都拿这本书当作教材。这本书非常系统、全面、严谨,而且又不是特别难,适合对数据结构和算法有些了解,并且掌握了至少一门编程语言的同学。而且,这个作者也很用心。他用了三种语言,写了三个版本,分别是:《数据结构与算法分析 :C 语言描述》《数据结构与算法分析:C++ 描述》《数据结构与算法分析:Java 语言描述》。
如果你熟悉的是 Python 或者 JavaScript,可以参考《数据结构与算法 JavaScript 描述》《数据结构与算法:Python 语言描述》 。至于其他语言的算法书籍,确实比较少。如果你有推荐,可以在留言区补充一下。
4.3 面试必刷的宝典算法:
对面试很重要,很多人也很关心。我这里推荐几本有益于面试的书籍,分别是:《剑指 offer》《编程珠玑》《编程之美》。
从《剑指 offer》这本书的名字就可以看出,作者的写作目的非常明确,就是为了面试。这本书几乎包含了所有常见的、经典的面试题。如果能搞懂这本书里的内容,应付一般公司的面试应该不成问题。
《编程珠玑》这本书的豆瓣评分非常高,有 9 分。这本书最大的特色就是讲了很多针对海量数据的处理技巧。这个可能是其他算法书籍很少涉及的。面试的时候,海量数据处理的问题也是经常会问的,特别是校招面试。不管是开拓眼界,还是应付面试,这本书都很值得一看。
《编程之美》这本书有多位作者,其中绝大部分是微软的工程师,所以书的质量很有保证。不过,这里面的算法题目稍微有点难,也不是很系统,这也是我把它归到面试这一部分的原因。如果你有一定基础,也喜欢钻研些算法问题,或者要面试 Google、Facebook 这样的公司,可以拿这本书里的题,先来自测一下。
4.4 经典大部头:
很多人一提到算法书就会搬出《算法导论》和《算法》。这两本确实非常经典,但是都太厚了,看起来比较费劲,我估计很少有人能坚持全部看下来。如果你想更加深入地学一学数据结构和算法,我还是强烈建议你看看。
我个人觉得,《算法导论》这本书的章节安排不是循序渐进的,里面充斥着各种算法的正确性、复杂度的证明、推导,数学公式比较多,一般人看起来会比较吃力。所以,作为入门书籍,并不是很推荐。
《算法》这本书也是一本经典大部头,不过它比起《算法导论》来要友好很多,更容易看懂,更适合初学者入门。但是这本书的缺点也很明显,就是内容不够全面,比如动态规划这么重要的知识点,这本书就没有讲。对于数据结构的东西,它讲的也不多,基本就是偏重讲算法。
4.5 殿堂级经典:
说到殿堂级经典书,如果《计算机程序设计艺术》称第二,我想没人敢称第一。这本书包括很多卷。说实话,我也只看过比较简单的几卷,比如《基本算法》《排序和查找》。
这套书的深度、广度、系统性、全面性是其他所有数据结构和算法书籍都无法相比的。但是,如果你对算法和数据结构不是特别感兴趣,没有很好的数学、算法、计算机基础,想要把这套书读完、读懂是比较难的。你可以把它当作你算法学习的终极挑战。
4.6 闲暇阅读:
算法无处不在。我这里再推荐几本适合闲暇时间阅读的书:《算法帝国》《数学之美》《算法之美》。
这些书共同的特点是,都列举了大量的例子,非常通俗易懂。夸张点说,像《算法帝国》,文科生都能读懂。当你看这些书的时候,你常常会深深感受到算法的力量,被算法的优美之处折服。即便不是从事 IT 工作的,看完这几本书也可以开拓眼界。
注意:每个人的基础、学习能力都不一样,掌握程度取决于你的努力程度。除了你之外,没有人能百分之百保证你能掌握什么知识。
除了听、看之外,遇到不懂的会自己去查资料、看参考书籍,还把我讲的数据结构和算法都认真地实现一遍,这样的学习效果自然就比只听一遍、看一遍要好很多。
4.7 其他推荐:
- 清华 邓俊辉 《数据结构(c++语言版)(第3版)》,豆瓣评分9.3,这本书是我目前遇到的唯一一本能有兴趣翻开的数据结构的书,可以坚持粗略地翻一遍,其他的书一翻开,密密麻麻的文字和代码,直接想睡觉,而这本书看起来就很舒服,而且是少有的彩色印刷。
非常重要的是,邓俊辉老师还替这本书录制了配套的视频公开课,非常受欢迎,里面有各种形象生动的动画,可以在 edx 或者 学堂在线 上免费观看学习。 - 严蔚敏老师 《数据结构》学习的代码书。高一凡的《数据结构与算法解析》,西电的高老师,用C 把严的伪代码全部实现,并能运行,非常生猛。
1:《算法第四版》Java语言写的,不过动态规划(没记错的话)没有涉及、很厚!这本书挺推荐的、特别是javaer!
2:《剑指offer》个人觉得题目经典都是老题!但是难度好像很一般啊(还是学生 不太清楚面试内容)、然后里面确实讲了一些很细的东西值得学习!还有本书所有题目作者都提供了C代码和大量的测试案例!nice;
3:编程珠玑:国外作者,这本书我看了不多 但是初步觉得好像是对超大量数据处理的算法!
4:编程之美:微软的书、难度较高、题目很深!这本书里面的题 代码不超过2页的估计作者都不会选上!!!!书不厚 、一般般
5:数据结构和算法分析:我们大学教材!我们老师教的书里都有、代码是伪代码!
6:算法导论:这本书我用来垫电脑!很厚 很无聊0.0!!!
5. 学习态度:(羁绊前行的,不是肆虐的狂风,而是内心的迷茫)
没有捷径,没有杀手锏,更没有一招致胜的“葵花宝典”。
不要浮躁,不要丧失思考能力,不要丧失学习能力。
只有做好打硬仗的心理准备,遇到困难才能心态平和。一个 4000 多字的文章、10 分钟的音频,反复看了、听了 2 个小时都没怎么看懂”。我给他的回复是:“如果之前没有基础或者基础不好的话,看 2 个小时还不懂,很正常,看一个礼拜试试。”
“一个礼拜”的说法,我一点都不是夸张。虽然专栏的每篇文章都只有三四千字,10 分钟左右的音频,但是知识点的密度还是很高的。如果你潜意识里觉得应该一下子就能看懂,就会出现这样的情况:看了一遍不懂,又看了一遍还是不怎么懂,然后就放弃了。
数据结和算法就是一个非常难啃的硬骨头,可以说是计算机学科中最难学的学科之一了。我当时学习也费了老大的劲,能做到讲给你听,我靠的也是十年如一的积累和坚持。如果没有基础、或者基础不好,你怎能期望看 2 个小时就能完全掌握呢?
面对这种硬骨头,我觉得我们要有打硬仗、打持久战的心理准备。只有这样,在学习的过程中遇到困难的时候,心态才能更加平和,才能沉下心来有条不紊地去解决一个个的疑难问题。这样,碰到问题,你可能还会“窃喜”,我又遇到了一个之前不怎么懂的知识点了,看懂它我又进步了一点。甚至你还会“坏坏地”想,又多了一个拉开我跟其他人距离的地方了。跨过这些点,我就能比别人更厉害。
一口吃不成胖子,如果你基础不好,那就从长计议吧,给自己定一个长一点的“死磕”计划,比如一年。面对不懂的知识点,沉下心来逐个突破,这样你的信心慢慢也就建立了。
“放弃”的念头像是一个心魔,它会一直围绕着你。
我分享一个我最近思考比较多的事情。前一段时间,我在研究多线程方面的东西,它涉及一块比较复杂的内容,“Java 内存模型”。虽然看懂并不难,但是要透彻、无盲点地理解并不容易。本来以为半天就能看懂的东西,结果我从周一一直看到周五下午,断断续续花了 5 天的时间才把它彻底搞懂。回忆起这 5 天,我有不下 10 次都想放弃,每次心里都在想:“算了,先放一放,以后再说吧”“太难了,啃不下来,算了。”“就这样吧,反正也用不到,没必要浪费时间”等等。这种放弃的念头就像一个邪恶的魔鬼一样,一直围绕着我这 5 天的研究中。
现在回想起来,我很庆幸我当时没有放弃,多坚持了几天。如果当时我放弃了,那之后再遇到技术难题时,“放弃”的心魔还会再来拜访我,潜意识里我还是会认输。
之所以没有放弃,我自己总结了两点原因。
第一,我对学习这件事情认识得比较清楚,我一直觉得,没有学不会的东西,没有攻克不了的技术难题,如果有,那就说明时间花得还不够多。
第二,我之前遇到卡壳的时候,几乎从来没有放弃过,即便短暂地停歇,我也会继续拎起来再死磕,而且每次都能搞定,正是这种正向的激励,给了我信心,让我再遇到困难的时候,都能坚信自己能搞定它。
入门是一个非常漫长和煎熬的过程,谁都逃不过。
文章写得再通俗易懂,对于之前没有任何基础的人来说,看起来还是挺费劲的。
第一,数据结构和算法这门课程本身的难度摆在那里,想要轻松看懂,本身就不太现实。
第二,对于任何新知识的学习,入门都是一个非常漫长和煎熬的的过程。但是这个过程都是要经历的,谁都逃不过。只要你挺过去,入了门,再学习更深的知识就简单多了。
我大学里的第一堂课是 C 语言,现在回想起来,当时对我来说,简直就是听天书。因为之前没有接触过计算机,更别说编程语言,对我来说,C 语言就像另一个世界的东西。从完全看不懂,到慢慢有点看懂,再到完全看懂,不夸张地讲,我花了好几年的时间,但是当掌握了之后,我发现这个东西其实也不难。但是如果没有度过漫长和煎熬的入门的过程,如果没有一点韧性,没有一点点信念,那可能也没有现在的我了。
其实我一直觉得情商比智商更重要。对于很多学科的学习,智商并不是瓶颈,最终能够决定你能达到的高度的,还是情商,而情商中最重要的,我觉得就是逆商(逆境商数,Adversity Quotient),也就是,当你遇到困难时,你会如何去面对,这将会决定你的人生最终能够走多远。
6.学习路线:
参考链接:
中文版的算法与数据结构可视化网站
数据结构和算法必知必会的50个代码实现
数据结构与算法之美—王争老师