我在学院ACM团队训练时学习了《算法竞赛进阶指南》这本书,该书不论是对于致力于研究算法方向的同学,还是对于有一定工作经历的程序员来说,都十分适合阅读。这本书分为八个较为独立的章节领域,我对这本书知识点的了解程度还远远不够,但是算法本身对于我的吸引程度是极大的。
在这本书的数据结构进阶板块讲解了并查集、树状数组、线段树、二叉查找树、平衡树等数据结构,以及分块、点分治等思想,还探讨了基于时间或值域的离线分治算法,以及两种可持久化数据结构。这些数据结构大多是位运算、递归、分治、倍增等基本算法在树上或复杂序列上的进一步应用。在这些算法中,并查集算法是我在接触算法知识前所知道的第一个算法,它是一种可以动态维护若干个不重叠的集合,并支持合并与查询的数据结构,包括两个基本操作:查询一个元素属于哪一个大集合、把两个集合合并成一个大集合。这也算得上是一个经典的算法,在解决问题中也有很强的实用性,后来学习的解决最小生成树问题其中一种算法Kruskal也是基于并查集的基础上衍生出来的。并查集算法N次合并M查找的时间复杂度是O(M Alpha(N)),这里Alpha函数的值可以看成是不大于4的,因此并查集的操作可以看作是线性的。
像这种优秀的算法还有很多。同一种问题可以用很多种不同算法来解决,而一个算法的质量优劣将影响到算法乃至程序的效率。一个算法应该具有的特征是:有穷性、确切性、输入、输出、可行性,而判断一个算法是否是一种优秀的算法应该考虑的是它的时间复杂度、空间复杂度、正确性、可读性和健壮性,其中主要是从时间复杂度和空间复杂度方面考虑。如果一个算法可以将原先时间复杂度为指数级、阶乘级增长优化为增长率更低的级别,这无疑是令人十分振奋的。
之前在网络上也看到有大佬这样来比喻:写程序就像开一辆车,当你不懂太多数据结构跟算法的时候,凭借丰富的实践经验你也可以将这辆车开好;但是,当有一天这辆车出问题跑不起来的时候呢?你不懂它内部的运行机制,你要怎么排除和解决问题?由此可见算法知识的重要性。我认为算法知识的边界是非常广阔的,而自己对它的了解也非常之少,还有更多有趣、耐人寻味的算法等待着我去探寻。