「读书笔记」算法是什么
这次因为疫情,在家办公了好一段时间,目前来看还要在家一周。在家办公不好的是,总给人感觉是 24 小时 on call,经常晚上了也要继续加班…另外是需要自己做饭洗碗,而办公的桌子椅子坐着也很不舒服。当然啦,也有好的地方,不用通勤,睡的时间更多了,也更方便抽空看书。
今年第一本看完的技术书是薄薄的《算法图解》,看完后自觉对算法有了更加系统、体系的认识,也更加明白自己在哪方面需要补强。例如数据结构上的树、图,对原理,操作,使用都不甚了解。而基础的散列表,栈,队列,也需要加强实践。
这篇文章是在自己总结的脑图的基础上写成的,说了一下自己对算法的认识。
算法是什么
算法是一组完成任务的指令,能够解决问题,体现了一种思想。这样讲比较模糊,让我来打个比喻。
桌子上横放了几本书,我想要拿出《算法图解》时,我是这么打算的:
先拿最上面第一本书,不是我想要的,放一边,再拿一本,还不是,继续拿吧,直至拿到《算法图解》。
这个过程便是算法的体现。我的问题是需要拿出一堆书中的《算法图解》,而我的方法是一本一本地拿,直到拿到的书为我想要的。
转换为程序时,我们可能会有这些东西:由一堆书组成的数据,以及,可能是由数组这一结构存储着书籍数据,然后,编写代码遍历这个数组,直至获取到的元素为《算法图解》。
算法需要了解什么
继续以上面的例子为例,在程序中,我认为算法需要了解的事情有三样:数据,数据结构,及算法的思想。
- 数据:书籍
- 数据结构:数组
- 算法的思想:遍历数组元素,判断是否为《算法图解》
所以,对算法的学习,归根结底,是学习
- 如何组织数据——使用什么数据结构,各种数据结构的操作方式与优缺点
- 如何操作数据——体现了算法的思想,如何更快的解决问题,如何更让人易懂地解决问题
没错,解决问题的思路不会只有一种,因此,我们会追求更快、更易懂的解决思路,这里便引申出一个问题:如何评价算法?
从两个维度:时间,空间。
时间指的是算法执行的时间,但一般不是直接使用秒或其他时间单位来衡量一种算法快慢的,因为,随着数据量的增大,不同算法的快慢程度,变化是不一样的。我们一般使用算法对数据的操作次数来衡量算法的时间(大 O 表示法)。
空间指的是,算法编写成程序,运行时占用的内存大小,因为内存资源并不是无限大,因此就要求在有效的资源内,编写更高效的算法。而算法空间的衡量,也同样使用大 O 表示法。
数据结构是什么
接着讲数据结构。数据结构是组织数据的方式,例如,上面的书是横着放的,这是一个组织书的方式,但当我要拿《算法图解》的时候,便会发觉有些麻烦,因为它在最底下,需要把上面的书先拿起来才能拿到。当然了,我们可以换种整理书的方式:竖着排
好了,现在无论是那本书,我们都可以很容易地立刻拿到。这种竖着排的方式,是另一种组织书的方式,因此它是另一种数据结构。
细看这两种数据结构,我们发现,横着排的书,想拿底下的书就显得很麻烦,而竖着排,无论是那本书都很方便拿到。
回到程序的世界,不同的数据结构也是如此,都是组织数据的不同方式,而组织的方式不同,各有不同的优缺点。在程序中,一般会有这几种不同的数据结构:
数组,链表,散列表,队列,栈,树,图。
这些数据结构各有特点,适用于不同的场景,这就是要求学习算法需掌握的地方。目前而言,我对于树跟图还不够熟悉,其他几个数据结构都了解其原理与应用,欠缺的是更多的实践。
算法的应用
一些算法思想
处理数据的过程,有时候可归为某类问题,而这些问题,经过人们不断地实践,总结了许多解决的思路,例如
- 递归:调用自身来解决问题
- 分而治之:把问题划分为同类的小问题,通过解决小问题最终解决整个问题
- 贪婪策略:总是做出在当前看来是最好的选择
- 动态规划:使用网格推演子问题解决过程来解决整个问题
- 特征抽取:将事务转换为计算机能理解的数据(多元组)
等等。
算法应用分类
在程序中,算法要处理的对象是数据,而这些处理,大致可划分为几大方面:
- 查找
- 搜索
- 排序
- 分类
- 预测
在这些分类中,要面对的问题就具体很多,对于具体的问题,更容易沉淀出通用的解决方法,所以,这里会有很多解决问题的算法。例如,查找可以使用二分查找,搜索可以使用广度优先搜索,排序可以使用快速排序,等等。
而这些,也正是一般接触算法时听得比较多的名词,我想正是因为他们解决的问题都是最具体,特定的问题。
《算法图解》笔记脑图
这里是我总结的脑图,读完这本书,解决了我对算法比较模糊的理解,对算法有了更加系统的认识,当然,认识还不算深入,需要继续掌握树、图等数据结构,以及各种复杂的算法思想。
END