算法专栏 (一):构建自己的算法体系
为什么要写这个算法专栏的文章呢? 因为自己一直在断断续续的学习算法但发现一旦在很忙时放下了一段时间,很多知识点就会遗忘,我本来天真的以为如果完全理解就会完全掌握甚至融汇贯通,现在看来是自己 too young 了。
所有的知识都需要构建自己的体系这样才能记得牢固。所以这个专栏就是通过一些市面上我认为不错的算法资料进行自己的算法体系构建及知识记录。
这个专栏是基于 极客时间中 王争老师 的《算法与数据结构之美》写下的,其中我把代码的用例都换成了Go语言,以及添加了Go语言对应数据机构算法的一些说明,还有Go语言对应算法的习题讲解
体系
什么是体系
体系就是在规定范围内,不同单位个体依照某种规律或秩序联系在一起的整体,是不同却又在某范围内的独立个体因为他们之间的联系而组成的一个系统。
为什么要建立体系
其实从小到大我们总会发现有些人就是神一般的存在着,让我们感觉无法超越,他们知识广博且又深入。以前我觉得是天赋,但在我认为不是。他们是有一套建立知识体系的学习方法。当你建立起了某个知识的自己的体系的时候这个知识就很难忘记了。为什么?因为类型相似的知识之间建立起了联系,人类其实最不擅长的就是背诵,人类擅长的是理解和构建联系。当碎片化的知识点之间又了联系有了根茎叶,那么当一个知识点被记起来所有知识点也都唤起了回忆。
算法与数据结构的根基
好了知道什么是体系我们就可以构建它。首先我们要知道算法和数据结构也只是整个计算机科学体系的一部份,相当于整个大体系的根基部分。
这个专栏里我们只是去构建算法与数据结构的体系。
其实算法和数据结构的的根基非常简单,故名思义就是算法和数据结构。这个体系的所有枝叶都发散与这两部分根基。
什么是数据结构?什么是算法?
大部分数据结构和算法教材,在开篇都会给这两个概念下一个明确的定义。但是,这些定义都很抽象,对理解这两个概念并没有实质性的帮助,反倒会让你陷入死抠定义的误区。毕竟,我们现在学习,并不是为了考试,所以,概念背得再牢,不会用也就没什么用。
虽然我们说没必要深挖严格的定义,但是这并不等于不需要理解概念。 下面我就从广义和狭义两个层面,来帮你理解数据结构与算法这两个概念。
从广义上讲,数据结构就是指一组数据的存储结构。算法就是操作数据的一组方法。
图书馆储藏书籍你肯定见过吧?为了方便查找,图书管理员一般会将书籍分门别类进行“存储”。按照一定规律编号,就是书籍这种“数据”的存储结构。
那我们如何来查找一本书呢?有很多种办法,你当然可以一本一本地找,也可以先根据书籍类别的编号,是人文,还是科学、计算机,来定位书架,然后再依次查找。笼统地说,这些查找方法都是算法。
从狭义上讲,也就是我们专栏要讲的,是指某些著名的数据结构和算法,比如队列、栈、堆、二分查找、动态规划等。这些都是前人智慧的结晶,我们可以直接拿来用。我们要讲的这些经典数据结构和算法,都是前人从很多实际操作场景中抽象出来的,经过非常多的求证和检验,可以高效地帮助我们解决很多实际的开发问题。
那数据结构和算法有什么关系呢?为什么大部分书都把这两个东西放到一块儿来讲呢?
这是因为,数据结构和算法是相辅相成的。数据结构是为算法服务的,算法要作用在特定的数据结构之上。 因此,我们无法孤立数据结构来讲算法,也无法孤立算法来讲数据结构。
比如,因为数组具有随机访问的特点,常用的二分查找算法需要用数组来存储数据。但如果我们选择链表这种数据结构,二分查找算法就无法工作了,因为链表并不支持随机访问。
数据结构是静态的,它只是组织数据的一种方式。如果不在它的基础上操作、构建算法,孤立存在的数据结构就是没用的。
算法与数据结构的枝叶
学习算法与数据结构的意义就在于优化程序节省空间和时间,所以算法与数据结构最重要的分支就是 复杂度分析 。
在复杂度之后的分支是 20 个最常用的、最基础数据结构与算法,不管是应付面试还是工作需要,只要集中精力逐一攻克这 20 个知识点就足够了。
10 个数据结构 :数组、链表、栈、队列、散列表、二叉树、堆、跳表、图、Trie 树;
10 个算法:递归、排序、二分查找、搜索、哈希算法、贪心算法、分治算法、回溯算法、动态规划、字符串匹配算法。
好了我们的算法与数据结构的枝干算是建立好了,剩下的叶片需要我们变学习边往上添加了,下面我画了一个算法与数据结构的体系图,再之后的学习记录中回严格按照该体系去进行反刍与知识间的连接建立,希望可以形成牢固的数据结构与算法的体系框架。
掌握了这些基础的数据结构和算法体系,再学更加复杂的数据结构和算法,相信就是在此基础上添加上层枝叶,就会非常容易、非常快。
在学习数据结构和算法的过程中,也要注意,不要只是死记硬背,不要为了学习而学习,而是要学习它的“来历”“自身的特点”“适合解决的问题”以及“实际的应用场景”。
方法
边学边练,适度刷题
当你学了某个算法和数据结构时一定要及时做题,不做题你永远也不知道自己到底是否掌握了它,但是我个人的观点是可以“适度”刷题,但一定不要浪费太多时间在刷题上。我们学习的目的还是掌握,然后应用。
多思考
避免一知半解,要想尽一切办法去搞懂每个知识点内容。
打怪升级学习法
学习的过程中,我们碰到最大的问题就是,坚持不下来。 是的,很多基础课程学起来都非常枯燥。为此,我自己总结了一套“打怪升级学习法”。
游戏你肯定玩过吧?为什么很多看起来非常简单又没有乐趣的游戏,你会玩得不亦乐乎呢?这是因为,当你努力打到一定级别之后,每天看着自己的经验值、战斗力在慢慢提高,那种每天都在一点一点成长的成就感就不由自主地产生了。
所以,我们在枯燥的学习过程中,也可以给自己设立一个切实可行的目标,就像打怪升级一样。
知识需要沉淀,不要想试图一下子掌握所有
在学习的过程中,一定会碰到“拦路虎”。如果哪个知识点没有怎么学懂,不要着急,这是正常的。因为,想听一遍、看一遍就把所有知识掌握,这肯定是不可能的。学习知识的过程是反复迭代、不断沉淀的过程。