有同学在学习图论算法的时候,发现这里有个 tarjan 算法,那里有个 tarjan 算法,而似乎 tarjan 算法解决的问题并不一样,于是非常迷惑:tarjan 算法到底是指什么?
这是一个很好的问题。tarjan 是计算机领域的大牛,发明了很多现在大家耳熟能详的算法或者数据结构,所以有同学会觉得冠他名字的算法有些多。
但如果我们仔细梳理一下,其实并不复杂。
在这篇文章中,我会带领大家梳理一下 tarjan 发明的算法都有哪些,整体脉络是怎样的。
注意:在这篇文章中,我不会具体讲解某个算法的原理。但是,我会给出很多具体的关键字,并且标红。如果大家对某个算法想深入了解,可以以此为引,在互联网上搜索学习。
我相信,互联网上关于某个具体算法的资料是非常多的,反而是这样按照某个脉络做总结的文章很少。
首先,tarjan 是一名美国的计算机科学家和数学家,全名 robert endre tarjan。
先来一个 tarjan 大神的名言镇楼:
一般提起 tarjan 算法,通常是指 tarjan 发明的求解有向图的强联通分量算法,全称是 tarjan’s strongly connected components algorithm.
为什么这么叫?因为求解有向图的强联通分量还有一个著名算法:kosaraju 算法。kosaraju 算法也是以他的发明者的名字命名的。
我在算法比赛中,或者需要求解 scc(强连通分量的缩写:strongly connected components) 问题的时候,喜欢写 kosaraju 算法。因为 kosaraju 算法的实现非常简单,复杂度和 tarjan 算法是一样的,都是 o(v + e) 的。
但实际上,kosaraju 算法需要遍历两次图,而 tarjan 算法只需要遍历一次图。所以,tarjan 算法的性能更高,一般可以高 30% - 40% 左右。
而 tarjan 算法之所以有名,关键在于使用 tarjan 算法的思想,不仅仅可以求解 scc 问题,还可以求无向图中的桥或者割点。
这就是为什么,很多同学看到 tarjan 算法,做的事情不一样,但都叫 tarjan 算法的原因。我们可以把 tarjan 算法理解成是一种思想,基于这种思想,可以求解桥,割点,和 scc 问题。
所谓的 tarjan 算法思想,就是在遍历整个图的过程中,对每一个遍历的节点记录一个时间戳,通常被称为是 dfn;同时,记录通过这个节点,不经过父亲节点,最早能回到的时间戳,通常被称为是 low。通过这些信息,就能判断一个图的桥,割点,和强连通分量。
然而,tarjan 的贡献远不止于此。以tarjan命名的另外一个非常著名的算法,叫 tarjan‘s off-line least common ancestors algorithm。
这个算法本质是借助并查集,求解 lca(最近公共祖先的缩写:least common ancestors)问题。
实际上,离线的 lca 问题,是计算机科学领域非常著名的问题,深究下去,和 binary lifting,rmq 等非常著名的算法思想都有联系。
说到并查集,tarjan 也和这种数据结构有不解之缘。并查集虽然不是 tarjan 发明的,但是并查集的复杂度是 tarjan 首先分析清楚的:也就是 ackerman 函数的反函数。
如果对此感兴趣的同学,可以翻看《算法导论》,《算法导论》对这部分内容介绍得很清楚。
实际上,这也是《算法导论》这本教材的意义:稍微深入一些的算法分析问题,一般的算法教材都不会涉及。而《算法导论》所覆盖的深度和广度,比大多数教材都高太多。
当然,这也是《算法导论》不适合入门的原因。
说到数据结构,tarjan 确实发明过数据结构。最有名的两个,一个是斐波那契堆,一个是 splay 树。
splay 树虽然不保证一定平衡,但各个操作的均摊复杂度是 o(logn) 级别的。
splay 树最大的优势是实现简单,比红黑树简单不知道多少倍。所以,如果我们需要调用更加底层的树操作,需要自己实现一个自平衡的二分搜索树时,通常 splay 树是首选。
也正因为如此,很多搞竞赛的同学,都是能手写 splay 树的。
tarjan 还是非常著名的算法:bfprt 的作者之一。其实 bfprt 这个算法的名字,是其五个作者首字母的缩写。其中的 t,就是 tarjan。
bfprt 这个名字听起来非常拗口,同时也难记,但是它的另一个名字就很简单直接了,就是 median of medians。
这个算法整体并不难理解,是快排思想的一种更稳定的优化,每次近乎可以保证选取所处理的数组的中位数作为标定点(pivot),使得快速排序的最差时间复杂度真真正正达到了 o(nlogn)。
值得一提的是,bfprt 算法的这五位作者,都是计算机科学领域的大牛。他们分别是:
b 是 blum,全名 manuel blum,他因为复杂度理论方面的贡献,以及密码学的应用,获得了 1995 年的图灵奖;
f 是 floyd,全名 robert w. floyd,相信大家都很熟悉。大家在算法课本上一定会学到的所有点对的最短路径算法,就是他和 warshall 一起提出的,即 floyd–warshall 算法。同时,floyed 还提出了非常著名的 floyed 环检测算法。他获得了 1978 年的图灵奖;
p 是 pratt,全名 vaughan pratt,是斯坦福的教授;
r 是 rivest,全名 ron rivest。他是 mit 的教授,专攻密码学。我们现在所经常使用的 md5 算法,他就是作者之一;
最后的 t,就是这篇文章的主角:tarjan,全名 robert endre tarjan。
在图论领域,tarjan 还改进了一个非常著名的算法:最小树形图。最小树形图这个名字听起来很复杂,但其实这个概念很简单:就是有向图的最小生成树。
解决最小树形图问题,有一个非常朴素的算法,叫朱刘算法。听这个名字大家也知道,这是两位华人科学家首先提出来的算法,在论文记载中,分别是 y.j. chu 和 t.h. liu 在 1965 年提出来的。朱刘算法的时间复杂度是 o(ve) 的。
后来,tarjan 改进了这个算法,可以使用 o(elogv) 的时间做预处理,之后使用 o(v) 的时间,求解图中以任意顶点为根的最小树形图
tarjan 还发明了一种平面图的检测算法,首次在线性时间解决了平面图检测问题(planarity-testing)。因为平面图检测离大多数同学的工作比较远,所以可能很少有同学了解这个算法。
tarjan 的平面图检测算法还有一个合作者:john hopcroft。他们二人因为这个算法,以及在算法和数据结构等基础领域对计算机科学的贡献,获得了 1986 年的图灵奖。
tarjan 的硕士和博士是在斯坦福大学读的。他的导师有两个。一个就是大名鼎鼎的 floyd,上文介绍 bfprt 算法的时候介绍了。在这里给一个年轻的时候,floyd 风流倜傥的帅照:
tarjan 的另一名导师,则是计算机科学领域的神级人物:donald knuth。他可以说是计算复杂领域的创始人。
donald knuth 的经历和贡献,可以写一本书了。有时间,我会再写一篇文章介绍他。现在,很多人了解他,都是因为他的神作:taocp,即 the art of computer programming,被中文翻译成《计算机程序设计艺术》。这套书被评为至今计算机科学史上最重要的神作,但其实还没有写完。
不过 donald knuth 对计算机科学领域的贡献,远不止一套书这么简单。要聊 donald knuth 的话,能聊的就太多。这篇文章我们收一收,说回 tarjan。
tarjan 现在还在世,今年已经 72 岁了。根据维基百科,现在 tarjan 在普林斯顿任教。
实际上,在计算机科学领域,很多在教科书中出现的人物,都还在世;很多教科书级别的算法,概念,理论,其实距离提出,也不过是几十年的时间。
这足以可见:计算机是多么年轻的一个学科。
也正是因为这个原因,在计算机科学领域中,还有大量的没有被完全解决的问题。
计算机科学领域其实还大有可为。
原文标题:tarjan 这个算法大神
文章出处:【微信公众号:算法与数据结构】欢迎添加关注!文章转载请注明出处。
Python-正则与简单web服务器
基于HFSS与ADS结合的微波滤波器设计
超高颜值 满血性能!4月畅销锐龙本排行榜
江苏移动精研科技项目,5G+AI助力智造新工厂
三星M10/M20售价曝光:约人民币850元起
算法大神Tarjan
面临扫地机器人设计挑战,这六种情况用小型放大器搞定
石墨烯乳液密度测试的测试步骤
物流仓储管理中的UWB定位系统
存储芯片开始出现供大于求的现象,相关产品价格也开始出现下降趋势
单相串激电动机怎么用
三相电机工作时不热但线路烧坏的原因分析
采用OPA128的精密光电检测电路
京东自营Nvidia显卡不再支持7天无理由退货:原因竟是这个?
计算机系统中哈希表的优化
光控电路图解析
液压拉力机的工作原理及技术参数
如何适配新架构?TPU-MLIR代码生成CodeGen全解析!
伟世通使用NI LabVIEW控制设计和仿真模块简化汽车动力总成控制
电瓶车投诉中电池问题占6成